binutils/
[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 1042
dff55db0 1043 if (asect->relocation == NULL)
92bc0e80 1044 {
dff55db0
TG
1045 res = bfd_malloc (asect->reloc_count * sizeof (arelent));
1046 if (res == NULL)
1047 return -1;
1048
1049 if (bfd_mach_o_canonicalize_relocs (abfd, asect->rel_filepos,
1050 asect->reloc_count, res, syms) < 0)
1051 {
1052 free (res);
1053 return -1;
1054 }
1055 asect->relocation = res;
92bc0e80
TG
1056 }
1057
dff55db0 1058 res = asect->relocation;
92bc0e80 1059 for (i = 0; i < asect->reloc_count; i++)
b32e07d7
TG
1060 rels[i] = &res[i];
1061 rels[i] = NULL;
92bc0e80 1062
b32e07d7
TG
1063 return i;
1064}
92bc0e80 1065
b32e07d7
TG
1066long
1067bfd_mach_o_get_dynamic_reloc_upper_bound (bfd *abfd)
1068{
1069 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
92bc0e80 1070
b32e07d7
TG
1071 if (mdata->dysymtab == NULL)
1072 return 1;
dff55db0 1073 return (mdata->dysymtab->nextrel + mdata->dysymtab->nlocrel + 1)
b32e07d7
TG
1074 * sizeof (arelent *);
1075}
92bc0e80 1076
b32e07d7
TG
1077long
1078bfd_mach_o_canonicalize_dynamic_reloc (bfd *abfd, arelent **rels,
1079 struct bfd_symbol **syms)
1080{
1081 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1082 bfd_mach_o_dysymtab_command *dysymtab = mdata->dysymtab;
1083 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
1084 unsigned long i;
1085 arelent *res;
1086
1087 if (dysymtab == NULL)
1088 return 0;
1089 if (dysymtab->nextrel == 0 && dysymtab->nlocrel == 0)
1090 return 0;
1091
1092 /* No need to go further if we don't know how to read relocs. */
1093 if (bed->_bfd_mach_o_swap_reloc_in == NULL)
1094 return 0;
1095
dff55db0 1096 if (mdata->dyn_reloc_cache == NULL)
b32e07d7 1097 {
dff55db0
TG
1098 res = bfd_malloc ((dysymtab->nextrel + dysymtab->nlocrel)
1099 * sizeof (arelent));
1100 if (res == NULL)
1101 return -1;
b32e07d7 1102
dff55db0
TG
1103 if (bfd_mach_o_canonicalize_relocs (abfd, dysymtab->extreloff,
1104 dysymtab->nextrel, res, syms) < 0)
1105 {
1106 free (res);
1107 return -1;
1108 }
1109
1110 if (bfd_mach_o_canonicalize_relocs (abfd, dysymtab->locreloff,
1111 dysymtab->nlocrel,
1112 res + dysymtab->nextrel, syms) < 0)
1113 {
1114 free (res);
1115 return -1;
1116 }
1117
1118 mdata->dyn_reloc_cache = res;
b32e07d7
TG
1119 }
1120
dff55db0 1121 res = mdata->dyn_reloc_cache;
b32e07d7
TG
1122 for (i = 0; i < dysymtab->nextrel + dysymtab->nlocrel; i++)
1123 rels[i] = &res[i];
1124 rels[i] = NULL;
92bc0e80
TG
1125 return i;
1126}
1127
1128static bfd_boolean
ab273af8 1129bfd_mach_o_write_relocs (bfd *abfd, bfd_mach_o_section *section)
92bc0e80 1130{
046b007d 1131 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
92bc0e80
TG
1132 unsigned int i;
1133 arelent **entries;
1134 asection *sec;
1135 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
1136
1137 sec = section->bfdsection;
1138 if (sec->reloc_count == 0)
1139 return TRUE;
1140
1141 if (bed->_bfd_mach_o_swap_reloc_out == NULL)
1142 return TRUE;
1143
1144 /* Allocate relocation room. */
1145 mdata->filelen = FILE_ALIGN(mdata->filelen, 2);
1146 section->nreloc = sec->reloc_count;
1147 sec->rel_filepos = mdata->filelen;
1148 section->reloff = sec->rel_filepos;
1149 mdata->filelen += sec->reloc_count * BFD_MACH_O_RELENT_SIZE;
1150
1151 if (bfd_seek (abfd, section->reloff, SEEK_SET) != 0)
1152 return FALSE;
1153
1154 /* Convert and write. */
1155 entries = section->bfdsection->orelocation;
1156 for (i = 0; i < section->nreloc; i++)
1157 {
1158 arelent *rel = entries[i];
46d1c23b 1159 struct mach_o_reloc_info_external raw;
92bc0e80
TG
1160 bfd_mach_o_reloc_info info, *pinfo = &info;
1161
1162 /* Convert relocation to an intermediate representation. */
1163 if (!(*bed->_bfd_mach_o_swap_reloc_out) (rel, pinfo))
1164 return FALSE;
1165
1166 /* Lower the relocation info. */
1167 if (pinfo->r_scattered)
1168 {
1169 unsigned long v;
1170
1171 v = BFD_MACH_O_SR_SCATTERED
1172 | (pinfo->r_pcrel ? BFD_MACH_O_SR_PCREL : 0)
1173 | BFD_MACH_O_SET_SR_LENGTH(pinfo->r_length)
1174 | BFD_MACH_O_SET_SR_TYPE(pinfo->r_type)
1175 | BFD_MACH_O_SET_SR_ADDRESS(pinfo->r_address);
46d1c23b
TG
1176 /* Note: scattered relocs have field in reverse order... */
1177 bfd_put_32 (abfd, v, raw.r_address);
1178 bfd_put_32 (abfd, pinfo->r_value, raw.r_symbolnum);
92bc0e80
TG
1179 }
1180 else
1181 {
1182 unsigned long v;
1183
46d1c23b 1184 bfd_put_32 (abfd, pinfo->r_address, raw.r_address);
92bc0e80
TG
1185 v = BFD_MACH_O_SET_R_SYMBOLNUM (pinfo->r_value)
1186 | (pinfo->r_pcrel ? BFD_MACH_O_R_PCREL : 0)
1187 | BFD_MACH_O_SET_R_LENGTH (pinfo->r_length)
1188 | (pinfo->r_extern ? BFD_MACH_O_R_EXTERN : 0)
1189 | BFD_MACH_O_SET_R_TYPE (pinfo->r_type);
46d1c23b 1190 bfd_put_32 (abfd, v, raw.r_symbolnum);
92bc0e80
TG
1191 }
1192
46d1c23b 1193 if (bfd_bwrite (&raw, BFD_MACH_O_RELENT_SIZE, abfd)
92bc0e80
TG
1194 != BFD_MACH_O_RELENT_SIZE)
1195 return FALSE;
1196 }
1197 return TRUE;
1198}
1199
116c20d2 1200static int
ab273af8 1201bfd_mach_o_write_section_32 (bfd *abfd, bfd_mach_o_section *section)
116c20d2 1202{
46d1c23b
TG
1203 struct mach_o_section_32_external raw;
1204
1205 memcpy (raw.sectname, section->sectname, 16);
72b5104c 1206 memcpy (raw.segname, section->segname, 16);
46d1c23b
TG
1207 bfd_h_put_32 (abfd, section->addr, raw.addr);
1208 bfd_h_put_32 (abfd, section->size, raw.size);
1209 bfd_h_put_32 (abfd, section->offset, raw.offset);
1210 bfd_h_put_32 (abfd, section->align, raw.align);
1211 bfd_h_put_32 (abfd, section->reloff, raw.reloff);
1212 bfd_h_put_32 (abfd, section->nreloc, raw.nreloc);
1213 bfd_h_put_32 (abfd, section->flags, raw.flags);
1214 bfd_h_put_32 (abfd, section->reserved1, raw.reserved1);
1215 bfd_h_put_32 (abfd, section->reserved2, raw.reserved2);
1216
1217 if (bfd_bwrite (&raw, BFD_MACH_O_SECTION_SIZE, abfd)
92bc0e80 1218 != BFD_MACH_O_SECTION_SIZE)
116c20d2
NC
1219 return -1;
1220
1221 return 0;
1222}
1223
1224static int
ab273af8 1225bfd_mach_o_write_section_64 (bfd *abfd, bfd_mach_o_section *section)
116c20d2 1226{
46d1c23b
TG
1227 struct mach_o_section_64_external raw;
1228
1229 memcpy (raw.sectname, section->sectname, 16);
1230 memcpy (raw.segname, section->segname, 16);
1231 bfd_h_put_64 (abfd, section->addr, raw.addr);
1232 bfd_h_put_64 (abfd, section->size, raw.size);
1233 bfd_h_put_32 (abfd, section->offset, raw.offset);
1234 bfd_h_put_32 (abfd, section->align, raw.align);
1235 bfd_h_put_32 (abfd, section->reloff, raw.reloff);
1236 bfd_h_put_32 (abfd, section->nreloc, raw.nreloc);
1237 bfd_h_put_32 (abfd, section->flags, raw.flags);
1238 bfd_h_put_32 (abfd, section->reserved1, raw.reserved1);
1239 bfd_h_put_32 (abfd, section->reserved2, raw.reserved2);
1240 bfd_h_put_32 (abfd, section->reserved3, raw.reserved3);
1241
1242 if (bfd_bwrite (&raw, BFD_MACH_O_SECTION_64_SIZE, abfd)
92bc0e80 1243 != BFD_MACH_O_SECTION_64_SIZE)
116c20d2
NC
1244 return -1;
1245
1e8a024a
TG
1246 return 0;
1247}
1248
1249static int
ab273af8 1250bfd_mach_o_write_segment_32 (bfd *abfd, bfd_mach_o_load_command *command)
1e8a024a 1251{
46d1c23b 1252 struct mach_o_segment_command_32_external raw;
1e8a024a 1253 bfd_mach_o_segment_command *seg = &command->command.segment;
f1bde64c 1254 bfd_mach_o_section *sec;
1e8a024a 1255
c2f09c75
TG
1256 BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT);
1257
f1bde64c
TG
1258 for (sec = seg->sect_head; sec != NULL; sec = sec->next)
1259 if (!bfd_mach_o_write_relocs (abfd, sec))
92bc0e80 1260 return -1;
c2f09c75 1261
46d1c23b
TG
1262 memcpy (raw.segname, seg->segname, 16);
1263 bfd_h_put_32 (abfd, seg->vmaddr, raw.vmaddr);
1264 bfd_h_put_32 (abfd, seg->vmsize, raw.vmsize);
1265 bfd_h_put_32 (abfd, seg->fileoff, raw.fileoff);
1266 bfd_h_put_32 (abfd, seg->filesize, raw.filesize);
1267 bfd_h_put_32 (abfd, seg->maxprot, raw.maxprot);
1268 bfd_h_put_32 (abfd, seg->initprot, raw.initprot);
1269 bfd_h_put_32 (abfd, seg->nsects, raw.nsects);
1270 bfd_h_put_32 (abfd, seg->flags, raw.flags);
c2f09c75 1271
46d1c23b
TG
1272 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
1273 || bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
c2f09c75 1274 return -1;
1e8a024a 1275
f1bde64c
TG
1276 for (sec = seg->sect_head; sec != NULL; sec = sec->next)
1277 if (bfd_mach_o_write_section_32 (abfd, sec))
92bc0e80 1278 return -1;
1e8a024a 1279
116c20d2
NC
1280 return 0;
1281}
1282
1e8a024a 1283static int
ab273af8 1284bfd_mach_o_write_segment_64 (bfd *abfd, bfd_mach_o_load_command *command)
1e8a024a 1285{
46d1c23b 1286 struct mach_o_segment_command_64_external raw;
c2f09c75 1287 bfd_mach_o_segment_command *seg = &command->command.segment;
f1bde64c 1288 bfd_mach_o_section *sec;
c2f09c75
TG
1289
1290 BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT_64);
1291
f1bde64c
TG
1292 for (sec = seg->sect_head; sec != NULL; sec = sec->next)
1293 if (!bfd_mach_o_write_relocs (abfd, sec))
92bc0e80 1294 return -1;
c2f09c75 1295
46d1c23b
TG
1296 memcpy (raw.segname, seg->segname, 16);
1297 bfd_h_put_64 (abfd, seg->vmaddr, raw.vmaddr);
1298 bfd_h_put_64 (abfd, seg->vmsize, raw.vmsize);
1299 bfd_h_put_64 (abfd, seg->fileoff, raw.fileoff);
1300 bfd_h_put_64 (abfd, seg->filesize, raw.filesize);
1301 bfd_h_put_32 (abfd, seg->maxprot, raw.maxprot);
1302 bfd_h_put_32 (abfd, seg->initprot, raw.initprot);
1303 bfd_h_put_32 (abfd, seg->nsects, raw.nsects);
1304 bfd_h_put_32 (abfd, seg->flags, raw.flags);
1305
1306 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
1307 || bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
c2f09c75
TG
1308 return -1;
1309
f1bde64c
TG
1310 for (sec = seg->sect_head; sec != NULL; sec = sec->next)
1311 if (bfd_mach_o_write_section_64 (abfd, sec))
92bc0e80 1312 return -1;
c2f09c75 1313
c2f09c75 1314 return 0;
1e8a024a
TG
1315}
1316
c2f09c75 1317static bfd_boolean
ab273af8 1318bfd_mach_o_write_symtab (bfd *abfd, bfd_mach_o_load_command *command)
116c20d2 1319{
046b007d 1320 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
116c20d2 1321 bfd_mach_o_symtab_command *sym = &command->command.symtab;
116c20d2 1322 unsigned long i;
c2f09c75 1323 unsigned int wide = bfd_mach_o_wide_p (abfd);
046b007d 1324 unsigned int symlen = wide ? BFD_MACH_O_NLIST_64_SIZE : BFD_MACH_O_NLIST_SIZE;
c2f09c75
TG
1325 struct bfd_strtab_hash *strtab;
1326 asymbol **symbols = bfd_get_outsymbols (abfd);
1327
1328 BFD_ASSERT (command->type == BFD_MACH_O_LC_SYMTAB);
1329
1330 /* Write the symbols first. */
92bc0e80
TG
1331 mdata->filelen = FILE_ALIGN(mdata->filelen, wide ? 3 : 2);
1332 sym->symoff = mdata->filelen;
c2f09c75
TG
1333 if (bfd_seek (abfd, sym->symoff, SEEK_SET) != 0)
1334 return FALSE;
1335
1336 sym->nsyms = bfd_get_symcount (abfd);
92bc0e80 1337 mdata->filelen += sym->nsyms * symlen;
c2f09c75
TG
1338
1339 strtab = _bfd_stringtab_init ();
1340 if (strtab == NULL)
1341 return FALSE;
116c20d2 1342
a4551119
TG
1343 if (sym->nsyms > 0)
1344 /* Although we don't strictly need to do this, for compatibility with
1345 Darwin system tools, actually output an empty string for the index
1346 0 entry. */
1347 _bfd_stringtab_add (strtab, "", TRUE, FALSE);
1348
116c20d2
NC
1349 for (i = 0; i < sym->nsyms; i++)
1350 {
91d6fa6a 1351 bfd_size_type str_index;
92bc0e80 1352 bfd_mach_o_asymbol *s = (bfd_mach_o_asymbol *)symbols[i];
c2f09c75 1353
92bc0e80 1354 /* Compute name index. */
c2f09c75 1355 /* An index of 0 always means the empty string. */
92bc0e80 1356 if (s->symbol.name == 0 || s->symbol.name[0] == '\0')
91d6fa6a 1357 str_index = 0;
c2f09c75
TG
1358 else
1359 {
91d6fa6a
NC
1360 str_index = _bfd_stringtab_add (strtab, s->symbol.name, TRUE, FALSE);
1361 if (str_index == (bfd_size_type) -1)
c2f09c75
TG
1362 goto err;
1363 }
46d1c23b 1364
c2f09c75 1365 if (wide)
46d1c23b
TG
1366 {
1367 struct mach_o_nlist_64_external raw;
1368
1369 bfd_h_put_32 (abfd, str_index, raw.n_strx);
1370 bfd_h_put_8 (abfd, s->n_type, raw.n_type);
1371 bfd_h_put_8 (abfd, s->n_sect, raw.n_sect);
1372 bfd_h_put_16 (abfd, s->n_desc, raw.n_desc);
1373 bfd_h_put_64 (abfd, s->symbol.section->vma + s->symbol.value,
1374 raw.n_value);
1375
1376 if (bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
1377 goto err;
1378 }
c2f09c75 1379 else
46d1c23b
TG
1380 {
1381 struct mach_o_nlist_external raw;
116c20d2 1382
46d1c23b
TG
1383 bfd_h_put_32 (abfd, str_index, raw.n_strx);
1384 bfd_h_put_8 (abfd, s->n_type, raw.n_type);
1385 bfd_h_put_8 (abfd, s->n_sect, raw.n_sect);
1386 bfd_h_put_16 (abfd, s->n_desc, raw.n_desc);
1387 bfd_h_put_32 (abfd, s->symbol.section->vma + s->symbol.value,
1388 raw.n_value);
1389
1390 if (bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
1391 goto err;
1392 }
116c20d2 1393 }
c2f09c75 1394 sym->strsize = _bfd_stringtab_size (strtab);
92bc0e80
TG
1395 sym->stroff = mdata->filelen;
1396 mdata->filelen += sym->strsize;
116c20d2 1397
c2f09c75
TG
1398 if (_bfd_stringtab_emit (abfd, strtab) != TRUE)
1399 goto err;
1400 _bfd_stringtab_free (strtab);
116c20d2 1401
c2f09c75 1402 /* The command. */
46d1c23b
TG
1403 {
1404 struct mach_o_symtab_command_external raw;
116c20d2 1405
46d1c23b
TG
1406 bfd_h_put_32 (abfd, sym->symoff, raw.symoff);
1407 bfd_h_put_32 (abfd, sym->nsyms, raw.nsyms);
1408 bfd_h_put_32 (abfd, sym->stroff, raw.stroff);
1409 bfd_h_put_32 (abfd, sym->strsize, raw.strsize);
1410
1411 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
1412 || bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
1413 return FALSE;
1414 }
116c20d2 1415
c2f09c75 1416 return TRUE;
116c20d2 1417
c2f09c75
TG
1418 err:
1419 _bfd_stringtab_free (strtab);
1420 return FALSE;
116c20d2
NC
1421}
1422
92bc0e80
TG
1423/* Process the symbols and generate Mach-O specific fields.
1424 Number them. */
1425
1426static bfd_boolean
1427bfd_mach_o_mangle_symbols (bfd *abfd)
1428{
1429 unsigned long i;
1430 asymbol **symbols = bfd_get_outsymbols (abfd);
1431
1432 for (i = 0; i < bfd_get_symcount (abfd); i++)
1433 {
1434 bfd_mach_o_asymbol *s = (bfd_mach_o_asymbol *)symbols[i];
1435
1436 if (s->n_type == BFD_MACH_O_N_UNDF && !(s->symbol.flags & BSF_DEBUGGING))
1437 {
1438 /* As genuine Mach-O symbols type shouldn't be N_UNDF (undefined
1439 symbols should be N_UNDEF | N_EXT), we suppose the back-end
1440 values haven't been set. */
1441 if (s->symbol.section == bfd_abs_section_ptr)
1442 s->n_type = BFD_MACH_O_N_ABS;
1443 else if (s->symbol.section == bfd_und_section_ptr)
1444 {
1445 s->n_type = BFD_MACH_O_N_UNDF;
1446 if (s->symbol.flags & BSF_WEAK)
1447 s->n_desc |= BFD_MACH_O_N_WEAK_REF;
1448 }
1449 else if (s->symbol.section == bfd_com_section_ptr)
1450 s->n_type = BFD_MACH_O_N_UNDF | BFD_MACH_O_N_EXT;
1451 else
1452 s->n_type = BFD_MACH_O_N_SECT;
1453
1454 if (s->symbol.flags & BSF_GLOBAL)
1455 s->n_type |= BFD_MACH_O_N_EXT;
1456 }
1457
1458 /* Compute section index. */
1459 if (s->symbol.section != bfd_abs_section_ptr
1460 && s->symbol.section != bfd_und_section_ptr
1461 && s->symbol.section != bfd_com_section_ptr)
1462 s->n_sect = s->symbol.section->target_index;
1463
1464 /* Number symbols. */
1465 s->symbol.udata.i = i;
1466 }
1467 return TRUE;
1468}
1469
154a1ee5 1470bfd_boolean
116c20d2 1471bfd_mach_o_write_contents (bfd *abfd)
3af9a47b
NC
1472{
1473 unsigned int i;
046b007d 1474 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3af9a47b 1475
92bc0e80
TG
1476 if (mdata->header.ncmds == 0)
1477 if (!bfd_mach_o_build_commands (abfd))
1478 return FALSE;
1479
3af9a47b 1480 /* Now write header information. */
c2f09c75
TG
1481 if (mdata->header.filetype == 0)
1482 {
1483 if (abfd->flags & EXEC_P)
1484 mdata->header.filetype = BFD_MACH_O_MH_EXECUTE;
1485 else if (abfd->flags & DYNAMIC)
1486 mdata->header.filetype = BFD_MACH_O_MH_DYLIB;
1487 else
1488 mdata->header.filetype = BFD_MACH_O_MH_OBJECT;
1489 }
154a1ee5 1490 if (!bfd_mach_o_write_header (abfd, &mdata->header))
b34976b6 1491 return FALSE;
3af9a47b 1492
92bc0e80
TG
1493 /* Assign a number to each symbols. */
1494 if (!bfd_mach_o_mangle_symbols (abfd))
1495 return FALSE;
1496
3af9a47b
NC
1497 for (i = 0; i < mdata->header.ncmds; i++)
1498 {
46d1c23b 1499 struct mach_o_load_command_external raw;
3af9a47b
NC
1500 bfd_mach_o_load_command *cur = &mdata->commands[i];
1501 unsigned long typeflag;
1502
154a1ee5 1503 typeflag = cur->type | (cur->type_required ? BFD_MACH_O_LC_REQ_DYLD : 0);
3af9a47b 1504
46d1c23b
TG
1505 bfd_h_put_32 (abfd, typeflag, raw.cmd);
1506 bfd_h_put_32 (abfd, cur->len, raw.cmdsize);
3af9a47b 1507
c2f09c75 1508 if (bfd_seek (abfd, cur->offset, SEEK_SET) != 0
46d1c23b 1509 || bfd_bwrite (&raw, BFD_MACH_O_LC_SIZE, abfd) != 8)
b34976b6 1510 return FALSE;
3af9a47b
NC
1511
1512 switch (cur->type)
1513 {
1514 case BFD_MACH_O_LC_SEGMENT:
ab273af8 1515 if (bfd_mach_o_write_segment_32 (abfd, cur) != 0)
1e8a024a
TG
1516 return FALSE;
1517 break;
1518 case BFD_MACH_O_LC_SEGMENT_64:
ab273af8 1519 if (bfd_mach_o_write_segment_64 (abfd, cur) != 0)
b34976b6 1520 return FALSE;
3af9a47b
NC
1521 break;
1522 case BFD_MACH_O_LC_SYMTAB:
ab273af8 1523 if (!bfd_mach_o_write_symtab (abfd, cur))
b34976b6 1524 return FALSE;
3af9a47b
NC
1525 break;
1526 case BFD_MACH_O_LC_SYMSEG:
1527 break;
1528 case BFD_MACH_O_LC_THREAD:
1529 case BFD_MACH_O_LC_UNIXTHREAD:
ab273af8 1530 if (bfd_mach_o_write_thread (abfd, cur) != 0)
b34976b6 1531 return FALSE;
3af9a47b
NC
1532 break;
1533 case BFD_MACH_O_LC_LOADFVMLIB:
1534 case BFD_MACH_O_LC_IDFVMLIB:
1535 case BFD_MACH_O_LC_IDENT:
1536 case BFD_MACH_O_LC_FVMFILE:
1537 case BFD_MACH_O_LC_PREPAGE:
1538 case BFD_MACH_O_LC_DYSYMTAB:
1539 case BFD_MACH_O_LC_LOAD_DYLIB:
1540 case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
1541 case BFD_MACH_O_LC_ID_DYLIB:
046b007d 1542 case BFD_MACH_O_LC_REEXPORT_DYLIB:
73017762 1543 case BFD_MACH_O_LC_LOAD_UPWARD_DYLIB:
3af9a47b
NC
1544 case BFD_MACH_O_LC_LOAD_DYLINKER:
1545 case BFD_MACH_O_LC_ID_DYLINKER:
1546 case BFD_MACH_O_LC_PREBOUND_DYLIB:
1547 case BFD_MACH_O_LC_ROUTINES:
1548 case BFD_MACH_O_LC_SUB_FRAMEWORK:
1549 break;
1550 default:
4a97a0e5
AM
1551 (*_bfd_error_handler) (_("unable to write unknown load command 0x%lx"),
1552 (unsigned long) cur->type);
b34976b6 1553 return FALSE;
3af9a47b
NC
1554 }
1555 }
1556
b34976b6 1557 return TRUE;
3af9a47b
NC
1558}
1559
f1bde64c
TG
1560static void
1561bfd_mach_o_append_section_to_segment (bfd_mach_o_segment_command *seg,
1562 asection *sec)
1563{
1564 bfd_mach_o_section *s = (bfd_mach_o_section *)sec->used_by_bfd;
1565 if (seg->sect_head == NULL)
1566 seg->sect_head = s;
1567 else
1568 seg->sect_tail->next = s;
1569 seg->sect_tail = s;
1570}
1571
1572/* Create section Mach-O flags from BFD flags. */
1573
1574static void
1575bfd_mach_o_set_section_flags_from_bfd (bfd *abfd ATTRIBUTE_UNUSED, asection *sec)
1576{
1577 flagword bfd_flags;
1578 bfd_mach_o_section *s = bfd_mach_o_get_mach_o_section (sec);
1579
1580 /* Create default flags. */
1581 bfd_flags = bfd_get_section_flags (abfd, sec);
1582 if ((bfd_flags & SEC_CODE) == SEC_CODE)
1583 s->flags = BFD_MACH_O_S_ATTR_PURE_INSTRUCTIONS
1584 | BFD_MACH_O_S_ATTR_SOME_INSTRUCTIONS
1585 | BFD_MACH_O_S_REGULAR;
1586 else if ((bfd_flags & (SEC_ALLOC | SEC_LOAD)) == SEC_ALLOC)
1587 s->flags = BFD_MACH_O_S_ZEROFILL;
1588 else if (bfd_flags & SEC_DEBUGGING)
1589 s->flags = BFD_MACH_O_S_REGULAR | BFD_MACH_O_S_ATTR_DEBUG;
1590 else
1591 s->flags = BFD_MACH_O_S_REGULAR;
1592}
1593
154a1ee5
TG
1594/* Build Mach-O load commands from the sections. */
1595
1596bfd_boolean
1597bfd_mach_o_build_commands (bfd *abfd)
1598{
046b007d 1599 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
c2f09c75 1600 unsigned int wide = mach_o_wide_p (&mdata->header);
154a1ee5 1601 bfd_mach_o_segment_command *seg;
154a1ee5 1602 asection *sec;
c2f09c75
TG
1603 bfd_mach_o_load_command *cmd;
1604 bfd_mach_o_load_command *symtab_cmd;
1605 int target_index;
154a1ee5
TG
1606
1607 /* Return now if commands are already built. */
1608 if (mdata->header.ncmds)
1609 return FALSE;
1610
f1bde64c
TG
1611 /* Very simple version: a command (segment) to contain all the sections and
1612 a command for the symbol table. */
c2f09c75
TG
1613 mdata->header.ncmds = 2;
1614 mdata->commands = bfd_alloc (abfd, mdata->header.ncmds
154a1ee5
TG
1615 * sizeof (bfd_mach_o_load_command));
1616 if (mdata->commands == NULL)
1617 return FALSE;
c2f09c75
TG
1618 cmd = &mdata->commands[0];
1619 seg = &cmd->command.segment;
1620
154a1ee5 1621 seg->nsects = bfd_count_sections (abfd);
154a1ee5
TG
1622
1623 /* Set segment command. */
1624 if (wide)
1625 {
c2f09c75
TG
1626 cmd->type = BFD_MACH_O_LC_SEGMENT_64;
1627 cmd->offset = BFD_MACH_O_HEADER_64_SIZE;
1628 cmd->len = BFD_MACH_O_LC_SEGMENT_64_SIZE
154a1ee5
TG
1629 + BFD_MACH_O_SECTION_64_SIZE * seg->nsects;
1630 }
1631 else
1632 {
c2f09c75
TG
1633 cmd->type = BFD_MACH_O_LC_SEGMENT;
1634 cmd->offset = BFD_MACH_O_HEADER_SIZE;
1635 cmd->len = BFD_MACH_O_LC_SEGMENT_SIZE
154a1ee5
TG
1636 + BFD_MACH_O_SECTION_SIZE * seg->nsects;
1637 }
c2f09c75
TG
1638 cmd->type_required = FALSE;
1639 mdata->header.sizeofcmds = cmd->len;
92bc0e80 1640 mdata->filelen = cmd->offset + cmd->len;
154a1ee5 1641
c2f09c75
TG
1642 /* Set symtab command. */
1643 symtab_cmd = &mdata->commands[1];
1644
1645 symtab_cmd->type = BFD_MACH_O_LC_SYMTAB;
1646 symtab_cmd->offset = cmd->offset + cmd->len;
1647 symtab_cmd->len = 6 * 4;
1648 symtab_cmd->type_required = FALSE;
1649
1650 mdata->header.sizeofcmds += symtab_cmd->len;
92bc0e80 1651 mdata->filelen += symtab_cmd->len;
c2f09c75
TG
1652
1653 /* Fill segment command. */
154a1ee5
TG
1654 memset (seg->segname, 0, sizeof (seg->segname));
1655 seg->vmaddr = 0;
92bc0e80 1656 seg->fileoff = mdata->filelen;
154a1ee5
TG
1657 seg->filesize = 0;
1658 seg->maxprot = BFD_MACH_O_PROT_READ | BFD_MACH_O_PROT_WRITE
1659 | BFD_MACH_O_PROT_EXECUTE;
1660 seg->initprot = seg->maxprot;
1661 seg->flags = 0;
7ba695a9
TG
1662 seg->sect_head = NULL;
1663 seg->sect_tail = NULL;
154a1ee5 1664
a4551119
TG
1665 /* Create Mach-O sections.
1666 Section type, attribute and align should have been set when the
1667 section was created - either read in or specified. */
c2f09c75 1668 target_index = 0;
154a1ee5
TG
1669 for (sec = abfd->sections; sec; sec = sec->next)
1670 {
a4551119 1671 unsigned bfd_align = bfd_get_section_alignment (abfd, sec);
f1bde64c 1672 bfd_mach_o_section *msect = bfd_mach_o_get_mach_o_section (sec);
c2f09c75 1673
f1bde64c
TG
1674 bfd_mach_o_append_section_to_segment (seg, sec);
1675
f1bde64c
TG
1676 msect->addr = bfd_get_section_vma (abfd, sec);
1677 msect->size = bfd_get_section_size (sec);
a4551119
TG
1678 /* Use the largest alignment set, in case it was bumped after the
1679 section was created. */
1680 msect->align = msect->align > bfd_align ? msect->align : bfd_align;
f1bde64c
TG
1681
1682 if (msect->size != 0)
1683 {
1684 mdata->filelen = FILE_ALIGN (mdata->filelen, msect->align);
1685 msect->offset = mdata->filelen;
92bc0e80
TG
1686 }
1687 else
f1bde64c
TG
1688 msect->offset = 0;
1689
1690 sec->filepos = msect->offset;
c2f09c75 1691 sec->target_index = ++target_index;
154a1ee5 1692
f1bde64c 1693 mdata->filelen += msect->size;
154a1ee5 1694 }
92bc0e80 1695 seg->filesize = mdata->filelen - seg->fileoff;
154a1ee5
TG
1696 seg->vmsize = seg->filesize;
1697
1698 return TRUE;
1699}
1700
1701/* Set the contents of a section. */
1702
1703bfd_boolean
1704bfd_mach_o_set_section_contents (bfd *abfd,
1705 asection *section,
1706 const void * location,
1707 file_ptr offset,
1708 bfd_size_type count)
1709{
1710 file_ptr pos;
1711
1712 /* This must be done first, because bfd_set_section_contents is
1713 going to set output_has_begun to TRUE. */
1714 if (! abfd->output_has_begun && ! bfd_mach_o_build_commands (abfd))
1715 return FALSE;
1716
1717 if (count == 0)
1718 return TRUE;
1719
1720 pos = section->filepos + offset;
1721 if (bfd_seek (abfd, pos, SEEK_SET) != 0
1722 || bfd_bwrite (location, count, abfd) != count)
1723 return FALSE;
1724
1725 return TRUE;
1726}
1727
1728int
116c20d2 1729bfd_mach_o_sizeof_headers (bfd *a ATTRIBUTE_UNUSED,
a6b96beb 1730 struct bfd_link_info *info ATTRIBUTE_UNUSED)
3af9a47b
NC
1731{
1732 return 0;
1733}
1734
1735/* Make an empty symbol. This is required only because
1736 bfd_make_section_anyway wants to create a symbol for the section. */
1737
154a1ee5 1738asymbol *
116c20d2 1739bfd_mach_o_make_empty_symbol (bfd *abfd)
3af9a47b 1740{
d3ce72d0
NC
1741 asymbol *new_symbol;
1742
1743 new_symbol = bfd_zalloc (abfd, sizeof (bfd_mach_o_asymbol));
1744 if (new_symbol == NULL)
1745 return new_symbol;
1746 new_symbol->the_bfd = abfd;
1747 new_symbol->udata.i = 0;
1748 return new_symbol;
3af9a47b
NC
1749}
1750
154a1ee5 1751static bfd_boolean
116c20d2 1752bfd_mach_o_read_header (bfd *abfd, bfd_mach_o_header *header)
3af9a47b 1753{
46d1c23b 1754 struct mach_o_header_external raw;
1e8a024a 1755 unsigned int size;
edeb6e24 1756 bfd_vma (*get32) (const void *) = NULL;
3af9a47b 1757
1e8a024a 1758 /* Just read the magic number. */
c2f09c75 1759 if (bfd_seek (abfd, 0, SEEK_SET) != 0
46d1c23b 1760 || bfd_bread (raw.magic, sizeof (raw.magic), abfd) != 4)
154a1ee5 1761 return FALSE;
3af9a47b 1762
46d1c23b 1763 if (bfd_getb32 (raw.magic) == BFD_MACH_O_MH_MAGIC)
3af9a47b
NC
1764 {
1765 header->byteorder = BFD_ENDIAN_BIG;
154a1ee5 1766 header->magic = BFD_MACH_O_MH_MAGIC;
1e8a024a 1767 header->version = 1;
3af9a47b
NC
1768 get32 = bfd_getb32;
1769 }
46d1c23b 1770 else if (bfd_getl32 (raw.magic) == BFD_MACH_O_MH_MAGIC)
3af9a47b 1771 {
a95a4550 1772 header->byteorder = BFD_ENDIAN_LITTLE;
154a1ee5 1773 header->magic = BFD_MACH_O_MH_MAGIC;
1e8a024a
TG
1774 header->version = 1;
1775 get32 = bfd_getl32;
1776 }
46d1c23b 1777 else if (bfd_getb32 (raw.magic) == BFD_MACH_O_MH_MAGIC_64)
1e8a024a
TG
1778 {
1779 header->byteorder = BFD_ENDIAN_BIG;
154a1ee5 1780 header->magic = BFD_MACH_O_MH_MAGIC_64;
1e8a024a
TG
1781 header->version = 2;
1782 get32 = bfd_getb32;
1783 }
46d1c23b 1784 else if (bfd_getl32 (raw.magic) == BFD_MACH_O_MH_MAGIC_64)
1e8a024a
TG
1785 {
1786 header->byteorder = BFD_ENDIAN_LITTLE;
154a1ee5 1787 header->magic = BFD_MACH_O_MH_MAGIC_64;
1e8a024a 1788 header->version = 2;
3af9a47b
NC
1789 get32 = bfd_getl32;
1790 }
1791 else
1792 {
1793 header->byteorder = BFD_ENDIAN_UNKNOWN;
154a1ee5 1794 return FALSE;
3af9a47b 1795 }
a95a4550 1796
1e8a024a 1797 /* Once the size of the header is known, read the full header. */
c2f09c75 1798 size = mach_o_wide_p (header) ?
154a1ee5 1799 BFD_MACH_O_HEADER_64_SIZE : BFD_MACH_O_HEADER_SIZE;
1e8a024a 1800
c2f09c75 1801 if (bfd_seek (abfd, 0, SEEK_SET) != 0
46d1c23b 1802 || bfd_bread (&raw, size, abfd) != size)
154a1ee5 1803 return FALSE;
1e8a024a 1804
46d1c23b
TG
1805 header->cputype = (*get32) (raw.cputype);
1806 header->cpusubtype = (*get32) (raw.cpusubtype);
1807 header->filetype = (*get32) (raw.filetype);
1808 header->ncmds = (*get32) (raw.ncmds);
1809 header->sizeofcmds = (*get32) (raw.sizeofcmds);
1810 header->flags = (*get32) (raw.flags);
3af9a47b 1811
c2f09c75 1812 if (mach_o_wide_p (header))
46d1c23b 1813 header->reserved = (*get32) (raw.reserved);
1e8a024a 1814
154a1ee5 1815 return TRUE;
3af9a47b
NC
1816}
1817
f1bde64c
TG
1818bfd_boolean
1819bfd_mach_o_new_section_hook (bfd *abfd, asection *sec)
1820{
1821 bfd_mach_o_section *s;
a4551119 1822 unsigned bfdalign = bfd_get_section_alignment (abfd, sec);
f1bde64c
TG
1823
1824 s = bfd_mach_o_get_mach_o_section (sec);
1825 if (s == NULL)
1826 {
1827 flagword bfd_flags;
a4551119 1828 static const mach_o_section_name_xlat * xlat;
f1bde64c
TG
1829
1830 s = (bfd_mach_o_section *) bfd_zalloc (abfd, sizeof (*s));
1831 if (s == NULL)
1832 return FALSE;
1833 sec->used_by_bfd = s;
1834 s->bfdsection = sec;
1835
a4551119
TG
1836 /* Create the Darwin seg/sect name pair from the bfd name.
1837 If this is a canonical name for which a specific paiting exists
1838 there will also be defined flags, type, attribute and alignment
1839 values. */
1840 xlat = bfd_mach_o_convert_section_name_to_mach_o (abfd, sec, s);
1841 if (xlat != NULL)
1842 {
1843 s->flags = xlat->macho_sectype | xlat->macho_secattr;
1844 s->align = xlat->sectalign > bfdalign ? xlat->sectalign
1845 : bfdalign;
1846 bfd_set_section_alignment (abfd, sec, s->align);
1847 bfd_flags = bfd_get_section_flags (abfd, sec);
1848 if (bfd_flags == SEC_NO_FLAGS)
1849 bfd_set_section_flags (abfd, sec, xlat->bfd_flags);
1850 }
f1bde64c 1851 else
a4551119
TG
1852 /* Create default flags. */
1853 bfd_mach_o_set_section_flags_from_bfd (abfd, sec);
f1bde64c
TG
1854 }
1855
1856 return _bfd_generic_new_section_hook (abfd, sec);
1857}
1858
1859static void
1860bfd_mach_o_init_section_from_mach_o (bfd *abfd, asection *sec,
1861 unsigned long prot)
3af9a47b 1862{
117ed4f8 1863 flagword flags;
f1bde64c 1864 bfd_mach_o_section *section;
3af9a47b 1865
f1bde64c
TG
1866 flags = bfd_get_section_flags (abfd, sec);
1867 section = bfd_mach_o_get_mach_o_section (sec);
3af9a47b 1868
a4551119
TG
1869 /* TODO: see if we should use the xlat system for doing this by
1870 preference and fall back to this for unknown sections. */
1871
8462aec7 1872 if (flags == SEC_NO_FLAGS)
ef17cb22 1873 {
8462aec7
TG
1874 /* Try to guess flags. */
1875 if (section->flags & BFD_MACH_O_S_ATTR_DEBUG)
1876 flags = SEC_DEBUGGING;
1877 else
1878 {
1879 flags = SEC_ALLOC;
1880 if ((section->flags & BFD_MACH_O_SECTION_TYPE_MASK)
1881 != BFD_MACH_O_S_ZEROFILL)
1882 {
1883 flags |= SEC_LOAD;
1884 if (prot & BFD_MACH_O_PROT_EXECUTE)
1885 flags |= SEC_CODE;
1886 if (prot & BFD_MACH_O_PROT_WRITE)
1887 flags |= SEC_DATA;
1888 else if (prot & BFD_MACH_O_PROT_READ)
1889 flags |= SEC_READONLY;
1890 }
1891 }
ef17cb22 1892 }
15e1c58a
TG
1893 else
1894 {
8462aec7
TG
1895 if ((flags & SEC_DEBUGGING) == 0)
1896 flags |= SEC_ALLOC;
15e1c58a 1897 }
8462aec7
TG
1898
1899 if (section->offset != 0)
1900 flags |= SEC_HAS_CONTENTS;
92bc0e80
TG
1901 if (section->nreloc != 0)
1902 flags |= SEC_RELOC;
1903
f1bde64c
TG
1904 bfd_set_section_flags (abfd, sec, flags);
1905
1906 sec->vma = section->addr;
1907 sec->lma = section->addr;
1908 sec->size = section->size;
1909 sec->filepos = section->offset;
1910 sec->alignment_power = section->align;
1911 sec->segment_mark = 0;
1912 sec->reloc_count = section->nreloc;
1913 sec->rel_filepos = section->reloff;
1914}
1915
1916static asection *
1917bfd_mach_o_make_bfd_section (bfd *abfd,
1918 const unsigned char *segname,
1919 const unsigned char *sectname)
1920{
1921 const char *sname;
1922 flagword flags;
a95a4550 1923
f1bde64c
TG
1924 bfd_mach_o_convert_section_name_to_bfd
1925 (abfd, (const char *)segname, (const char *)sectname, &sname, &flags);
1926 if (sname == NULL)
1927 return NULL;
3af9a47b 1928
f1bde64c 1929 return bfd_make_section_anyway_with_flags (abfd, sname, flags);
3af9a47b
NC
1930}
1931
f1bde64c 1932static asection *
ab273af8 1933bfd_mach_o_read_section_32 (bfd *abfd,
ab273af8
TG
1934 unsigned int offset,
1935 unsigned long prot)
3af9a47b 1936{
46d1c23b 1937 struct mach_o_section_32_external raw;
f1bde64c
TG
1938 asection *sec;
1939 bfd_mach_o_section *section;
3af9a47b 1940
c2f09c75 1941 if (bfd_seek (abfd, offset, SEEK_SET) != 0
46d1c23b 1942 || (bfd_bread (&raw, BFD_MACH_O_SECTION_SIZE, abfd)
c2f09c75 1943 != BFD_MACH_O_SECTION_SIZE))
f1bde64c 1944 return NULL;
a95a4550 1945
5a5cbf72 1946 sec = bfd_mach_o_make_bfd_section (abfd, raw.segname, raw.sectname);
f1bde64c
TG
1947 if (sec == NULL)
1948 return NULL;
1949
1950 section = bfd_mach_o_get_mach_o_section (sec);
1951 memcpy (section->segname, raw.segname, sizeof (raw.segname));
1952 section->segname[BFD_MACH_O_SEGNAME_SIZE] = 0;
1953 memcpy (section->sectname, raw.sectname, sizeof (raw.sectname));
69499dca 1954 section->sectname[BFD_MACH_O_SECTNAME_SIZE] = 0;
46d1c23b
TG
1955 section->addr = bfd_h_get_32 (abfd, raw.addr);
1956 section->size = bfd_h_get_32 (abfd, raw.size);
1957 section->offset = bfd_h_get_32 (abfd, raw.offset);
1958 section->align = bfd_h_get_32 (abfd, raw.align);
1959 section->reloff = bfd_h_get_32 (abfd, raw.reloff);
1960 section->nreloc = bfd_h_get_32 (abfd, raw.nreloc);
1961 section->flags = bfd_h_get_32 (abfd, raw.flags);
1962 section->reserved1 = bfd_h_get_32 (abfd, raw.reserved1);
1963 section->reserved2 = bfd_h_get_32 (abfd, raw.reserved2);
1e8a024a 1964 section->reserved3 = 0;
1e8a024a 1965
f1bde64c 1966 bfd_mach_o_init_section_from_mach_o (abfd, sec, prot);
1e8a024a 1967
f1bde64c 1968 return sec;
1e8a024a
TG
1969}
1970
f1bde64c 1971static asection *
ab273af8 1972bfd_mach_o_read_section_64 (bfd *abfd,
ab273af8
TG
1973 unsigned int offset,
1974 unsigned long prot)
1e8a024a 1975{
46d1c23b 1976 struct mach_o_section_64_external raw;
f1bde64c
TG
1977 asection *sec;
1978 bfd_mach_o_section *section;
1e8a024a 1979
c2f09c75 1980 if (bfd_seek (abfd, offset, SEEK_SET) != 0
46d1c23b 1981 || (bfd_bread (&raw, BFD_MACH_O_SECTION_64_SIZE, abfd)
c2f09c75 1982 != BFD_MACH_O_SECTION_64_SIZE))
f1bde64c
TG
1983 return NULL;
1984
5a5cbf72 1985 sec = bfd_mach_o_make_bfd_section (abfd, raw.segname, raw.sectname);
f1bde64c
TG
1986 if (sec == NULL)
1987 return NULL;
1e8a024a 1988
f1bde64c
TG
1989 section = bfd_mach_o_get_mach_o_section (sec);
1990 memcpy (section->segname, raw.segname, sizeof (raw.segname));
1991 section->segname[BFD_MACH_O_SEGNAME_SIZE] = 0;
1992 memcpy (section->sectname, raw.sectname, sizeof (raw.sectname));
69499dca 1993 section->sectname[BFD_MACH_O_SECTNAME_SIZE] = 0;
46d1c23b
TG
1994 section->addr = bfd_h_get_64 (abfd, raw.addr);
1995 section->size = bfd_h_get_64 (abfd, raw.size);
1996 section->offset = bfd_h_get_32 (abfd, raw.offset);
1997 section->align = bfd_h_get_32 (abfd, raw.align);
1998 section->reloff = bfd_h_get_32 (abfd, raw.reloff);
1999 section->nreloc = bfd_h_get_32 (abfd, raw.nreloc);
2000 section->flags = bfd_h_get_32 (abfd, raw.flags);
2001 section->reserved1 = bfd_h_get_32 (abfd, raw.reserved1);
2002 section->reserved2 = bfd_h_get_32 (abfd, raw.reserved2);
2003 section->reserved3 = bfd_h_get_32 (abfd, raw.reserved3);
3af9a47b 2004
f1bde64c 2005 bfd_mach_o_init_section_from_mach_o (abfd, sec, prot);
3af9a47b 2006
f1bde64c 2007 return sec;
3af9a47b
NC
2008}
2009
f1bde64c 2010static asection *
ab273af8 2011bfd_mach_o_read_section (bfd *abfd,
ab273af8
TG
2012 unsigned int offset,
2013 unsigned long prot,
2014 unsigned int wide)
1e8a024a
TG
2015{
2016 if (wide)
f1bde64c 2017 return bfd_mach_o_read_section_64 (abfd, offset, prot);
1e8a024a 2018 else
f1bde64c 2019 return bfd_mach_o_read_section_32 (abfd, offset, prot);
1e8a024a
TG
2020}
2021
afbb9e17 2022static bfd_boolean
ab273af8
TG
2023bfd_mach_o_read_symtab_symbol (bfd *abfd,
2024 bfd_mach_o_symtab_command *sym,
2025 bfd_mach_o_asymbol *s,
2026 unsigned long i)
3af9a47b 2027{
046b007d 2028 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
c2f09c75 2029 unsigned int wide = mach_o_wide_p (&mdata->header);
046b007d
TG
2030 unsigned int symwidth =
2031 wide ? BFD_MACH_O_NLIST_64_SIZE : BFD_MACH_O_NLIST_SIZE;
92bc0e80 2032 unsigned int symoff = sym->symoff + (i * symwidth);
46d1c23b 2033 struct mach_o_nlist_64_external raw;
3af9a47b
NC
2034 unsigned char type = -1;
2035 unsigned char section = -1;
2036 short desc = -1;
1e8a024a 2037 symvalue value = -1;
3af9a47b
NC
2038 unsigned long stroff = -1;
2039 unsigned int symtype = -1;
2040
2041 BFD_ASSERT (sym->strtab != NULL);
2042
c2f09c75 2043 if (bfd_seek (abfd, symoff, SEEK_SET) != 0
46d1c23b 2044 || bfd_bread (&raw, symwidth, abfd) != symwidth)
3af9a47b 2045 {
46d1c23b
TG
2046 (*_bfd_error_handler)
2047 (_("bfd_mach_o_read_symtab_symbol: unable to read %d bytes at %lu"),
2048 symwidth, (unsigned long) symoff);
afbb9e17 2049 return FALSE;
3af9a47b
NC
2050 }
2051
46d1c23b
TG
2052 stroff = bfd_h_get_32 (abfd, raw.n_strx);
2053 type = bfd_h_get_8 (abfd, raw.n_type);
c2f09c75 2054 symtype = type & BFD_MACH_O_N_TYPE;
46d1c23b
TG
2055 section = bfd_h_get_8 (abfd, raw.n_sect);
2056 desc = bfd_h_get_16 (abfd, raw.n_desc);
1e8a024a 2057 if (wide)
46d1c23b 2058 value = bfd_h_get_64 (abfd, raw.n_value);
1e8a024a 2059 else
46d1c23b 2060 value = bfd_h_get_32 (abfd, raw.n_value);
3af9a47b
NC
2061
2062 if (stroff >= sym->strsize)
2063 {
46d1c23b
TG
2064 (*_bfd_error_handler)
2065 (_("bfd_mach_o_read_symtab_symbol: name out of range (%lu >= %lu)"),
2066 (unsigned long) stroff,
2067 (unsigned long) sym->strsize);
afbb9e17 2068 return FALSE;
3af9a47b
NC
2069 }
2070
92bc0e80
TG
2071 s->symbol.the_bfd = abfd;
2072 s->symbol.name = sym->strtab + stroff;
2073 s->symbol.value = value;
2074 s->symbol.flags = 0x0;
2075 s->symbol.udata.i = 0;
2076 s->n_type = type;
2077 s->n_sect = section;
2078 s->n_desc = desc;
3af9a47b
NC
2079
2080 if (type & BFD_MACH_O_N_STAB)
2081 {
92bc0e80
TG
2082 s->symbol.flags |= BSF_DEBUGGING;
2083 s->symbol.section = bfd_und_section_ptr;
15e1c58a
TG
2084 switch (type)
2085 {
2086 case N_FUN:
2087 case N_STSYM:
2088 case N_LCSYM:
2089 case N_BNSYM:
2090 case N_SLINE:
2091 case N_ENSYM:
2092 case N_ECOMM:
2093 case N_ECOML:
2094 case N_GSYM:
2095 if ((section > 0) && (section <= mdata->nsects))
2096 {
92bc0e80
TG
2097 s->symbol.section = mdata->sections[section - 1]->bfdsection;
2098 s->symbol.value =
2099 s->symbol.value - mdata->sections[section - 1]->addr;
15e1c58a
TG
2100 }
2101 break;
2102 }
3af9a47b
NC
2103 }
2104 else
2105 {
2106 if (type & BFD_MACH_O_N_PEXT)
92bc0e80 2107 s->symbol.flags |= BSF_GLOBAL;
c2f09c75 2108
3af9a47b 2109 if (type & BFD_MACH_O_N_EXT)
92bc0e80 2110 s->symbol.flags |= BSF_GLOBAL;
15e1c58a
TG
2111
2112 if (!(type & (BFD_MACH_O_N_PEXT | BFD_MACH_O_N_EXT)))
92bc0e80 2113 s->symbol.flags |= BSF_LOCAL;
3af9a47b
NC
2114
2115 switch (symtype)
2116 {
2117 case BFD_MACH_O_N_UNDF:
c2f09c75 2118 if (type == (BFD_MACH_O_N_UNDF | BFD_MACH_O_N_EXT)
92bc0e80 2119 && s->symbol.value != 0)
c2f09c75
TG
2120 {
2121 /* A common symbol. */
92bc0e80
TG
2122 s->symbol.section = bfd_com_section_ptr;
2123 s->symbol.flags = BSF_NO_FLAGS;
c2f09c75
TG
2124 }
2125 else
92bc0e80
TG
2126 {
2127 s->symbol.section = bfd_und_section_ptr;
2128 if (s->n_desc & BFD_MACH_O_N_WEAK_REF)
2129 s->symbol.flags |= BSF_WEAK;
2130 }
3af9a47b
NC
2131 break;
2132 case BFD_MACH_O_N_PBUD:
92bc0e80 2133 s->symbol.section = bfd_und_section_ptr;
3af9a47b
NC
2134 break;
2135 case BFD_MACH_O_N_ABS:
92bc0e80 2136 s->symbol.section = bfd_abs_section_ptr;
3af9a47b
NC
2137 break;
2138 case BFD_MACH_O_N_SECT:
2139 if ((section > 0) && (section <= mdata->nsects))
2140 {
92bc0e80
TG
2141 s->symbol.section = mdata->sections[section - 1]->bfdsection;
2142 s->symbol.value =
2143 s->symbol.value - mdata->sections[section - 1]->addr;
3af9a47b
NC
2144 }
2145 else
2146 {
2147 /* Mach-O uses 0 to mean "no section"; not an error. */
2148 if (section != 0)
2149 {
4a97a0e5
AM
2150 (*_bfd_error_handler) (_("bfd_mach_o_read_symtab_symbol: "
2151 "symbol \"%s\" specified invalid section %d (max %lu): setting to undefined"),
2152 s->symbol.name, section, mdata->nsects);
3af9a47b 2153 }
92bc0e80 2154 s->symbol.section = bfd_und_section_ptr;
3af9a47b
NC
2155 }
2156 break;
2157 case BFD_MACH_O_N_INDR:
0596a831
TG
2158 /* FIXME: we don't follow the BFD convention as this indirect symbol
2159 won't be followed by the referenced one. This looks harmless
2160 unless we start using the linker. */
2161 s->symbol.flags |= BSF_INDIRECT;
2162 s->symbol.section = bfd_ind_section_ptr;
2163 s->symbol.value = 0;
3af9a47b
NC
2164 break;
2165 default:
4a97a0e5
AM
2166 (*_bfd_error_handler) (_("bfd_mach_o_read_symtab_symbol: "
2167 "symbol \"%s\" specified invalid type field 0x%x: setting to undefined"),
2168 s->symbol.name, symtype);
92bc0e80 2169 s->symbol.section = bfd_und_section_ptr;
3af9a47b
NC
2170 break;
2171 }
2172 }
2173
afbb9e17 2174 return TRUE;
3af9a47b
NC
2175}
2176
c5012cd8 2177bfd_boolean
ab273af8 2178bfd_mach_o_read_symtab_strtab (bfd *abfd)
3af9a47b 2179{
046b007d
TG
2180 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
2181 bfd_mach_o_symtab_command *sym = mdata->symtab;
2182
2183 /* Fail if there is no symtab. */
2184 if (sym == NULL)
afbb9e17 2185 return FALSE;
046b007d
TG
2186
2187 /* Success if already loaded. */
2188 if (sym->strtab)
afbb9e17 2189 return TRUE;
3af9a47b
NC
2190
2191 if (abfd->flags & BFD_IN_MEMORY)
2192 {
2193 struct bfd_in_memory *b;
2194
2195 b = (struct bfd_in_memory *) abfd->iostream;
2196
2197 if ((sym->stroff + sym->strsize) > b->size)
2198 {
2199 bfd_set_error (bfd_error_file_truncated);
afbb9e17 2200 return FALSE;
3af9a47b 2201 }
f075ee0c 2202 sym->strtab = (char *) b->buffer + sym->stroff;
3af9a47b 2203 }
046b007d 2204 else
3af9a47b 2205 {
046b007d
TG
2206 sym->strtab = bfd_alloc (abfd, sym->strsize);
2207 if (sym->strtab == NULL)
afbb9e17 2208 return FALSE;
046b007d
TG
2209
2210 if (bfd_seek (abfd, sym->stroff, SEEK_SET) != 0
afbb9e17 2211 || bfd_bread (sym->strtab, sym->strsize, abfd) != sym->strsize)
046b007d
TG
2212 {
2213 bfd_set_error (bfd_error_file_truncated);
afbb9e17 2214 return FALSE;
046b007d 2215 }
3af9a47b
NC
2216 }
2217
afbb9e17 2218 return TRUE;
3af9a47b
NC
2219}
2220
c5012cd8 2221bfd_boolean
ab273af8 2222bfd_mach_o_read_symtab_symbols (bfd *abfd)
3af9a47b 2223{
046b007d
TG
2224 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
2225 bfd_mach_o_symtab_command *sym = mdata->symtab;
3af9a47b 2226 unsigned long i;
3af9a47b 2227
092d27ff
TG
2228 if (sym == NULL || sym->symbols)
2229 {
2230 /* Return now if there are no symbols or if already loaded. */
afbb9e17 2231 return TRUE;
092d27ff 2232 }
046b007d 2233
92bc0e80 2234 sym->symbols = bfd_alloc (abfd, sym->nsyms * sizeof (bfd_mach_o_asymbol));
3af9a47b
NC
2235
2236 if (sym->symbols == NULL)
2237 {
4a97a0e5 2238 (*_bfd_error_handler) (_("bfd_mach_o_read_symtab_symbols: unable to allocate memory for symbols"));
afbb9e17 2239 return FALSE;
3af9a47b 2240 }
a95a4550 2241
afbb9e17
TG
2242 if (!bfd_mach_o_read_symtab_strtab (abfd))
2243 return FALSE;
3af9a47b
NC
2244
2245 for (i = 0; i < sym->nsyms; i++)
2246 {
afbb9e17
TG
2247 if (!bfd_mach_o_read_symtab_symbol (abfd, sym, &sym->symbols[i], i))
2248 return FALSE;
3af9a47b 2249 }
a95a4550 2250
afbb9e17 2251 return TRUE;
3af9a47b
NC
2252}
2253
2254static const char *
116c20d2 2255bfd_mach_o_i386_flavour_string (unsigned int flavour)
3af9a47b
NC
2256{
2257 switch ((int) flavour)
2258 {
15e1c58a
TG
2259 case BFD_MACH_O_x86_THREAD_STATE32: return "x86_THREAD_STATE32";
2260 case BFD_MACH_O_x86_FLOAT_STATE32: return "x86_FLOAT_STATE32";
2261 case BFD_MACH_O_x86_EXCEPTION_STATE32: return "x86_EXCEPTION_STATE32";
2262 case BFD_MACH_O_x86_THREAD_STATE64: return "x86_THREAD_STATE64";
2263 case BFD_MACH_O_x86_FLOAT_STATE64: return "x86_FLOAT_STATE64";
2264 case BFD_MACH_O_x86_EXCEPTION_STATE64: return "x86_EXCEPTION_STATE64";
2265 case BFD_MACH_O_x86_THREAD_STATE: return "x86_THREAD_STATE";
2266 case BFD_MACH_O_x86_FLOAT_STATE: return "x86_FLOAT_STATE";
2267 case BFD_MACH_O_x86_EXCEPTION_STATE: return "x86_EXCEPTION_STATE";
2268 case BFD_MACH_O_x86_DEBUG_STATE32: return "x86_DEBUG_STATE32";
2269 case BFD_MACH_O_x86_DEBUG_STATE64: return "x86_DEBUG_STATE64";
2270 case BFD_MACH_O_x86_DEBUG_STATE: return "x86_DEBUG_STATE";
b32e07d7 2271 case BFD_MACH_O_x86_THREAD_STATE_NONE: return "x86_THREAD_STATE_NONE";
3af9a47b
NC
2272 default: return "UNKNOWN";
2273 }
2274}
2275
2276static const char *
116c20d2 2277bfd_mach_o_ppc_flavour_string (unsigned int flavour)
3af9a47b
NC
2278{
2279 switch ((int) flavour)
2280 {
b32e07d7
TG
2281 case BFD_MACH_O_PPC_THREAD_STATE: return "PPC_THREAD_STATE";
2282 case BFD_MACH_O_PPC_FLOAT_STATE: return "PPC_FLOAT_STATE";
2283 case BFD_MACH_O_PPC_EXCEPTION_STATE: return "PPC_EXCEPTION_STATE";
2284 case BFD_MACH_O_PPC_VECTOR_STATE: return "PPC_VECTOR_STATE";
2285 case BFD_MACH_O_PPC_THREAD_STATE64: return "PPC_THREAD_STATE64";
2286 case BFD_MACH_O_PPC_EXCEPTION_STATE64: return "PPC_EXCEPTION_STATE64";
3af9a47b
NC
2287 default: return "UNKNOWN";
2288 }
2289}
2290
2291static int
ab273af8 2292bfd_mach_o_read_dylinker (bfd *abfd, bfd_mach_o_load_command *command)
3af9a47b
NC
2293{
2294 bfd_mach_o_dylinker_command *cmd = &command->command.dylinker;
46d1c23b 2295 struct mach_o_str_command_external raw;
3af9a47b 2296 unsigned int nameoff;
3af9a47b
NC
2297
2298 BFD_ASSERT ((command->type == BFD_MACH_O_LC_ID_DYLINKER)
2299 || (command->type == BFD_MACH_O_LC_LOAD_DYLINKER));
2300
46d1c23b
TG
2301 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
2302 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
3af9a47b
NC
2303 return -1;
2304
46d1c23b 2305 nameoff = bfd_h_get_32 (abfd, raw.str);
3af9a47b
NC
2306
2307 cmd->name_offset = command->offset + nameoff;
2308 cmd->name_len = command->len - nameoff;
b32e07d7
TG
2309 cmd->name_str = bfd_alloc (abfd, cmd->name_len);
2310 if (cmd->name_str == NULL)
3af9a47b 2311 return -1;
b32e07d7
TG
2312 if (bfd_seek (abfd, cmd->name_offset, SEEK_SET) != 0
2313 || bfd_bread (cmd->name_str, cmd->name_len, abfd) != cmd->name_len)
3af9a47b 2314 return -1;
3af9a47b
NC
2315 return 0;
2316}
2317
2318static int
ab273af8 2319bfd_mach_o_read_dylib (bfd *abfd, bfd_mach_o_load_command *command)
3af9a47b
NC
2320{
2321 bfd_mach_o_dylib_command *cmd = &command->command.dylib;
46d1c23b 2322 struct mach_o_dylib_command_external raw;
3af9a47b 2323 unsigned int nameoff;
3af9a47b 2324
046b007d
TG
2325 switch (command->type)
2326 {
2327 case BFD_MACH_O_LC_LOAD_DYLIB:
046b007d 2328 case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
046b007d 2329 case BFD_MACH_O_LC_ID_DYLIB:
046b007d 2330 case BFD_MACH_O_LC_REEXPORT_DYLIB:
73017762 2331 case BFD_MACH_O_LC_LOAD_UPWARD_DYLIB:
046b007d
TG
2332 break;
2333 default:
b32e07d7
TG
2334 BFD_FAIL ();
2335 return -1;
046b007d 2336 }
3af9a47b 2337
46d1c23b
TG
2338 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
2339 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
3af9a47b
NC
2340 return -1;
2341
46d1c23b
TG
2342 nameoff = bfd_h_get_32 (abfd, raw.name);
2343 cmd->timestamp = bfd_h_get_32 (abfd, raw.timestamp);
2344 cmd->current_version = bfd_h_get_32 (abfd, raw.current_version);
2345 cmd->compatibility_version = bfd_h_get_32 (abfd, raw.compatibility_version);
3af9a47b
NC
2346
2347 cmd->name_offset = command->offset + nameoff;
2348 cmd->name_len = command->len - nameoff;
b32e07d7
TG
2349 cmd->name_str = bfd_alloc (abfd, cmd->name_len);
2350 if (cmd->name_str == NULL)
3af9a47b 2351 return -1;
b32e07d7
TG
2352 if (bfd_seek (abfd, cmd->name_offset, SEEK_SET) != 0
2353 || bfd_bread (cmd->name_str, cmd->name_len, abfd) != cmd->name_len)
3af9a47b 2354 return -1;
3af9a47b
NC
2355 return 0;
2356}
2357
2358static int
ab273af8
TG
2359bfd_mach_o_read_prebound_dylib (bfd *abfd ATTRIBUTE_UNUSED,
2360 bfd_mach_o_load_command *command ATTRIBUTE_UNUSED)
3af9a47b
NC
2361{
2362 /* bfd_mach_o_prebound_dylib_command *cmd = &command->command.prebound_dylib; */
2363
2364 BFD_ASSERT (command->type == BFD_MACH_O_LC_PREBOUND_DYLIB);
2365 return 0;
2366}
2367
2368static int
ab273af8 2369bfd_mach_o_read_thread (bfd *abfd, bfd_mach_o_load_command *command)
3af9a47b 2370{
b32e07d7 2371 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3af9a47b 2372 bfd_mach_o_thread_command *cmd = &command->command.thread;
92bc0e80 2373 unsigned int offset;
3af9a47b
NC
2374 unsigned int nflavours;
2375 unsigned int i;
2376
2377 BFD_ASSERT ((command->type == BFD_MACH_O_LC_THREAD)
2378 || (command->type == BFD_MACH_O_LC_UNIXTHREAD));
2379
b32e07d7 2380 /* Count the number of threads. */
3af9a47b
NC
2381 offset = 8;
2382 nflavours = 0;
2383 while (offset != command->len)
2384 {
46d1c23b
TG
2385 struct mach_o_thread_command_external raw;
2386
3af9a47b
NC
2387 if (offset >= command->len)
2388 return -1;
2389
c2f09c75 2390 if (bfd_seek (abfd, command->offset + offset, SEEK_SET) != 0
46d1c23b 2391 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
3af9a47b
NC
2392 return -1;
2393
46d1c23b 2394 offset += sizeof (raw) + bfd_h_get_32 (abfd, raw.count) * 4;
3af9a47b
NC
2395 nflavours++;
2396 }
2397
b32e07d7
TG
2398 /* Allocate threads. */
2399 cmd->flavours = bfd_alloc
2400 (abfd, nflavours * sizeof (bfd_mach_o_thread_flavour));
3af9a47b
NC
2401 if (cmd->flavours == NULL)
2402 return -1;
2403 cmd->nflavours = nflavours;
2404
2405 offset = 8;
2406 nflavours = 0;
2407 while (offset != command->len)
2408 {
46d1c23b
TG
2409 struct mach_o_thread_command_external raw;
2410
3af9a47b
NC
2411 if (offset >= command->len)
2412 return -1;
2413
2414 if (nflavours >= cmd->nflavours)
2415 return -1;
2416
c2f09c75 2417 if (bfd_seek (abfd, command->offset + offset, SEEK_SET) != 0
46d1c23b 2418 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
3af9a47b
NC
2419 return -1;
2420
46d1c23b
TG
2421 cmd->flavours[nflavours].flavour = bfd_h_get_32 (abfd, raw.flavour);
2422 cmd->flavours[nflavours].offset = command->offset + offset + sizeof (raw);
2423 cmd->flavours[nflavours].size = bfd_h_get_32 (abfd, raw.count) * 4;
2424 offset += cmd->flavours[nflavours].size + sizeof (raw);
3af9a47b
NC
2425 nflavours++;
2426 }
2427
2428 for (i = 0; i < nflavours; i++)
2429 {
2430 asection *bfdsec;
2431 unsigned int snamelen;
2432 char *sname;
2433 const char *flavourstr;
2434 const char *prefix = "LC_THREAD";
a95a4550
AM
2435 unsigned int j = 0;
2436
3af9a47b
NC
2437 switch (mdata->header.cputype)
2438 {
2439 case BFD_MACH_O_CPU_TYPE_POWERPC:
1e8a024a 2440 case BFD_MACH_O_CPU_TYPE_POWERPC_64:
3af9a47b
NC
2441 flavourstr = bfd_mach_o_ppc_flavour_string (cmd->flavours[i].flavour);
2442 break;
2443 case BFD_MACH_O_CPU_TYPE_I386:
1e8a024a 2444 case BFD_MACH_O_CPU_TYPE_X86_64:
3af9a47b
NC
2445 flavourstr = bfd_mach_o_i386_flavour_string (cmd->flavours[i].flavour);
2446 break;
2447 default:
2448 flavourstr = "UNKNOWN_ARCHITECTURE";
2449 break;
2450 }
a95a4550 2451
3af9a47b 2452 snamelen = strlen (prefix) + 1 + 20 + 1 + strlen (flavourstr) + 1;
116c20d2 2453 sname = bfd_alloc (abfd, snamelen);
3af9a47b
NC
2454 if (sname == NULL)
2455 return -1;
2456
2457 for (;;)
2458 {
a95a4550
AM
2459 sprintf (sname, "%s.%s.%u", prefix, flavourstr, j);
2460 if (bfd_get_section_by_name (abfd, sname) == NULL)
3af9a47b 2461 break;
a95a4550 2462 j++;
3af9a47b
NC
2463 }
2464
117ed4f8 2465 bfdsec = bfd_make_section_with_flags (abfd, sname, SEC_HAS_CONTENTS);
a95a4550 2466
3af9a47b
NC
2467 bfdsec->vma = 0;
2468 bfdsec->lma = 0;
eea6121a 2469 bfdsec->size = cmd->flavours[i].size;
3af9a47b
NC
2470 bfdsec->filepos = cmd->flavours[i].offset;
2471 bfdsec->alignment_power = 0x0;
3af9a47b
NC
2472
2473 cmd->section = bfdsec;
2474 }
2475
2476 return 0;
2477}
2478
a95a4550 2479static int
ab273af8 2480bfd_mach_o_read_dysymtab (bfd *abfd, bfd_mach_o_load_command *command)
3af9a47b 2481{
046b007d 2482 bfd_mach_o_dysymtab_command *cmd = &command->command.dysymtab;
b32e07d7 2483 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3af9a47b
NC
2484
2485 BFD_ASSERT (command->type == BFD_MACH_O_LC_DYSYMTAB);
2486
46d1c23b
TG
2487 {
2488 struct mach_o_dysymtab_command_external raw;
2489
2490 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
2491 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
2492 return -1;
3af9a47b 2493
46d1c23b
TG
2494 cmd->ilocalsym = bfd_h_get_32 (abfd, raw.ilocalsym);
2495 cmd->nlocalsym = bfd_h_get_32 (abfd, raw.nlocalsym);
2496 cmd->iextdefsym = bfd_h_get_32 (abfd, raw.iextdefsym);
2497 cmd->nextdefsym = bfd_h_get_32 (abfd, raw.nextdefsym);
2498 cmd->iundefsym = bfd_h_get_32 (abfd, raw.iundefsym);
2499 cmd->nundefsym = bfd_h_get_32 (abfd, raw.nundefsym);
2500 cmd->tocoff = bfd_h_get_32 (abfd, raw.tocoff);
2501 cmd->ntoc = bfd_h_get_32 (abfd, raw.ntoc);
2502 cmd->modtaboff = bfd_h_get_32 (abfd, raw.modtaboff);
2503 cmd->nmodtab = bfd_h_get_32 (abfd, raw.nmodtab);
2504 cmd->extrefsymoff = bfd_h_get_32 (abfd, raw.extrefsymoff);
2505 cmd->nextrefsyms = bfd_h_get_32 (abfd, raw.nextrefsyms);
2506 cmd->indirectsymoff = bfd_h_get_32 (abfd, raw.indirectsymoff);
2507 cmd->nindirectsyms = bfd_h_get_32 (abfd, raw.nindirectsyms);
2508 cmd->extreloff = bfd_h_get_32 (abfd, raw.extreloff);
2509 cmd->nextrel = bfd_h_get_32 (abfd, raw.nextrel);
2510 cmd->locreloff = bfd_h_get_32 (abfd, raw.locreloff);
2511 cmd->nlocrel = bfd_h_get_32 (abfd, raw.nlocrel);
2512 }
046b007d
TG
2513
2514 if (cmd->nmodtab != 0)
2515 {
046b007d
TG
2516 unsigned int i;
2517 int wide = bfd_mach_o_wide_p (abfd);
2518 unsigned int module_len = wide ? 56 : 52;
2519
2520 cmd->dylib_module =
2521 bfd_alloc (abfd, cmd->nmodtab * sizeof (bfd_mach_o_dylib_module));
2522 if (cmd->dylib_module == NULL)
2523 return -1;
2524
2525 if (bfd_seek (abfd, cmd->modtaboff, SEEK_SET) != 0)
2526 return -1;
2527
2528 for (i = 0; i < cmd->nmodtab; i++)
2529 {
2530 bfd_mach_o_dylib_module *module = &cmd->dylib_module[i];
2531 unsigned long v;
46d1c23b 2532 unsigned char buf[56];
046b007d 2533
91d6fa6a 2534 if (bfd_bread ((void *) buf, module_len, abfd) != module_len)
046b007d
TG
2535 return -1;
2536
2537 module->module_name_idx = bfd_h_get_32 (abfd, buf + 0);
2538 module->iextdefsym = bfd_h_get_32 (abfd, buf + 4);
2539 module->nextdefsym = bfd_h_get_32 (abfd, buf + 8);
2540 module->irefsym = bfd_h_get_32 (abfd, buf + 12);
2541 module->nrefsym = bfd_h_get_32 (abfd, buf + 16);
2542 module->ilocalsym = bfd_h_get_32 (abfd, buf + 20);
2543 module->nlocalsym = bfd_h_get_32 (abfd, buf + 24);
2544 module->iextrel = bfd_h_get_32 (abfd, buf + 28);
2545 module->nextrel = bfd_h_get_32 (abfd, buf + 32);
2546 v = bfd_h_get_32 (abfd, buf +36);
2547 module->iinit = v & 0xffff;
2548 module->iterm = (v >> 16) & 0xffff;
2549 v = bfd_h_get_32 (abfd, buf + 40);
2550 module->ninit = v & 0xffff;
2551 module->nterm = (v >> 16) & 0xffff;
2552 if (wide)
2553 {
2554 module->objc_module_info_size = bfd_h_get_32 (abfd, buf + 44);
2555 module->objc_module_info_addr = bfd_h_get_64 (abfd, buf + 48);
2556 }
2557 else
2558 {
2559 module->objc_module_info_addr = bfd_h_get_32 (abfd, buf + 44);
2560 module->objc_module_info_size = bfd_h_get_32 (abfd, buf + 48);
2561 }
2562 }
2563 }
afbb9e17 2564
046b007d
TG
2565 if (cmd->ntoc != 0)
2566 {
046b007d
TG
2567 unsigned int i;
2568
2569 cmd->dylib_toc = bfd_alloc
2570 (abfd, cmd->ntoc * sizeof (bfd_mach_o_dylib_table_of_content));
2571 if (cmd->dylib_toc == NULL)
2572 return -1;
2573
2574 if (bfd_seek (abfd, cmd->tocoff, SEEK_SET) != 0)
2575 return -1;
2576
2577 for (i = 0; i < cmd->ntoc; i++)
2578 {
46d1c23b 2579 struct mach_o_dylib_table_of_contents_external raw;
046b007d
TG
2580 bfd_mach_o_dylib_table_of_content *toc = &cmd->dylib_toc[i];
2581
46d1c23b 2582 if (bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
046b007d
TG
2583 return -1;
2584
46d1c23b
TG
2585 toc->symbol_index = bfd_h_get_32 (abfd, raw.symbol_index);
2586 toc->module_index = bfd_h_get_32 (abfd, raw.module_index);
046b007d
TG
2587 }
2588 }
2589
2590 if (cmd->nindirectsyms != 0)
2591 {
046b007d
TG
2592 unsigned int i;
2593
2594 cmd->indirect_syms = bfd_alloc
2595 (abfd, cmd->nindirectsyms * sizeof (unsigned int));
2596 if (cmd->indirect_syms == NULL)
2597 return -1;
2598
2599 if (bfd_seek (abfd, cmd->indirectsymoff, SEEK_SET) != 0)
2600 return -1;
2601
2602 for (i = 0; i < cmd->nindirectsyms; i++)
2603 {
46d1c23b 2604 unsigned char raw[4];
046b007d
TG
2605 unsigned int *is = &cmd->indirect_syms[i];
2606
46d1c23b 2607 if (bfd_bread (raw, sizeof (raw), abfd) != sizeof (raw))
046b007d
TG
2608 return -1;
2609
46d1c23b 2610 *is = bfd_h_get_32 (abfd, raw);
046b007d
TG
2611 }
2612 }
2613
2614 if (cmd->nextrefsyms != 0)
2615 {
046b007d
TG
2616 unsigned long v;
2617 unsigned int i;
2618
2619 cmd->ext_refs = bfd_alloc
2620 (abfd, cmd->nextrefsyms * sizeof (bfd_mach_o_dylib_reference));
2621 if (cmd->ext_refs == NULL)
2622 return -1;
2623
2624 if (bfd_seek (abfd, cmd->extrefsymoff, SEEK_SET) != 0)
2625 return -1;
2626
2627 for (i = 0; i < cmd->nextrefsyms; i++)
2628 {
46d1c23b 2629 unsigned char raw[4];
046b007d
TG
2630 bfd_mach_o_dylib_reference *ref = &cmd->ext_refs[i];
2631
46d1c23b 2632 if (bfd_bread (raw, sizeof (raw), abfd) != sizeof (raw))
046b007d
TG
2633 return -1;
2634
b32e07d7
TG
2635 /* Fields isym and flags are written as bit-fields, thus we need
2636 a specific processing for endianness. */
46d1c23b 2637 v = bfd_h_get_32 (abfd, raw);
b32e07d7
TG
2638 if (bfd_big_endian (abfd))
2639 {
2640 ref->isym = (v >> 8) & 0xffffff;
2641 ref->flags = v & 0xff;
2642 }
2643 else
2644 {
2645 ref->isym = v & 0xffffff;
2646 ref->flags = (v >> 24) & 0xff;
2647 }
046b007d
TG
2648 }
2649 }
3af9a47b 2650
b32e07d7
TG
2651 if (mdata->dysymtab)
2652 return -1;
2653 mdata->dysymtab = cmd;
2654
3af9a47b
NC
2655 return 0;
2656}
2657
a95a4550 2658static int
ab273af8 2659bfd_mach_o_read_symtab (bfd *abfd, bfd_mach_o_load_command *command)
3af9a47b 2660{
046b007d
TG
2661 bfd_mach_o_symtab_command *symtab = &command->command.symtab;
2662 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
46d1c23b 2663 struct mach_o_symtab_command_external raw;
3af9a47b
NC
2664
2665 BFD_ASSERT (command->type == BFD_MACH_O_LC_SYMTAB);
2666
46d1c23b
TG
2667 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
2668 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
3af9a47b 2669 return -1;
a95a4550 2670
46d1c23b
TG
2671 symtab->symoff = bfd_h_get_32 (abfd, raw.symoff);
2672 symtab->nsyms = bfd_h_get_32 (abfd, raw.nsyms);
2673 symtab->stroff = bfd_h_get_32 (abfd, raw.stroff);
2674 symtab->strsize = bfd_h_get_32 (abfd, raw.strsize);
046b007d
TG
2675 symtab->symbols = NULL;
2676 symtab->strtab = NULL;
3af9a47b 2677
046b007d 2678 if (symtab->nsyms != 0)
15e1c58a
TG
2679 abfd->flags |= HAS_SYMS;
2680
046b007d
TG
2681 if (mdata->symtab)
2682 return -1;
2683 mdata->symtab = symtab;
3af9a47b
NC
2684 return 0;
2685}
2686
15e1c58a 2687static int
ab273af8 2688bfd_mach_o_read_uuid (bfd *abfd, bfd_mach_o_load_command *command)
15e1c58a
TG
2689{
2690 bfd_mach_o_uuid_command *cmd = &command->command.uuid;
15e1c58a
TG
2691
2692 BFD_ASSERT (command->type == BFD_MACH_O_LC_UUID);
2693
46d1c23b
TG
2694 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
2695 || bfd_bread (cmd->uuid, 16, abfd) != 16)
15e1c58a
TG
2696 return -1;
2697
15e1c58a
TG
2698 return 0;
2699}
2700
046b007d 2701static int
ab273af8 2702bfd_mach_o_read_linkedit (bfd *abfd, bfd_mach_o_load_command *command)
046b007d
TG
2703{
2704 bfd_mach_o_linkedit_command *cmd = &command->command.linkedit;
46d1c23b 2705 struct mach_o_linkedit_data_command_external raw;
046b007d 2706
46d1c23b
TG
2707 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
2708 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
046b007d
TG
2709 return -1;
2710
46d1c23b
TG
2711 cmd->dataoff = bfd_get_32 (abfd, raw.dataoff);
2712 cmd->datasize = bfd_get_32 (abfd, raw.datasize);
046b007d
TG
2713 return 0;
2714}
2715
2716static int
ab273af8 2717bfd_mach_o_read_str (bfd *abfd, bfd_mach_o_load_command *command)
046b007d
TG
2718{
2719 bfd_mach_o_str_command *cmd = &command->command.str;
46d1c23b 2720 struct mach_o_str_command_external raw;
046b007d
TG
2721 unsigned long off;
2722
46d1c23b
TG
2723 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
2724 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
046b007d
TG
2725 return -1;
2726
46d1c23b 2727 off = bfd_get_32 (abfd, raw.str);
046b007d
TG
2728 cmd->stroff = command->offset + off;
2729 cmd->str_len = command->len - off;
2730 cmd->str = bfd_alloc (abfd, cmd->str_len);
2731 if (cmd->str == NULL)
2732 return -1;
2733 if (bfd_seek (abfd, cmd->stroff, SEEK_SET) != 0
91d6fa6a 2734 || bfd_bread ((void *) cmd->str, cmd->str_len, abfd) != cmd->str_len)
046b007d
TG
2735 return -1;
2736 return 0;
2737}
2738
ad86f1fb 2739static int
ab273af8 2740bfd_mach_o_read_dyld_info (bfd *abfd, bfd_mach_o_load_command *command)
ad86f1fb
TG
2741{
2742 bfd_mach_o_dyld_info_command *cmd = &command->command.dyld_info;
46d1c23b 2743 struct mach_o_dyld_info_command_external raw;
ad86f1fb 2744
46d1c23b
TG
2745 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
2746 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
ad86f1fb
TG
2747 return -1;
2748
46d1c23b
TG
2749 cmd->rebase_off = bfd_get_32 (abfd, raw.rebase_off);
2750 cmd->rebase_size = bfd_get_32 (abfd, raw.rebase_size);
2751 cmd->bind_off = bfd_get_32 (abfd, raw.bind_off);
2752 cmd->bind_size = bfd_get_32 (abfd, raw.bind_size);
2753 cmd->weak_bind_off = bfd_get_32 (abfd, raw.weak_bind_off);
2754 cmd->weak_bind_size = bfd_get_32 (abfd, raw.weak_bind_size);
2755 cmd->lazy_bind_off = bfd_get_32 (abfd, raw.lazy_bind_off);
2756 cmd->lazy_bind_size = bfd_get_32 (abfd, raw.lazy_bind_size);
2757 cmd->export_off = bfd_get_32 (abfd, raw.export_off);
2758 cmd->export_size = bfd_get_32 (abfd, raw.export_size);
ad86f1fb
TG
2759 return 0;
2760}
2761
edbdea0e
TG
2762static bfd_boolean
2763bfd_mach_o_read_version_min (bfd *abfd, bfd_mach_o_load_command *command)
2764{
2765 bfd_mach_o_version_min_command *cmd = &command->command.version_min;
2766 struct mach_o_version_min_command_external raw;
2767 unsigned int ver;
2768
2769 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
2770 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
2771 return FALSE;
2772
2773 ver = bfd_get_32 (abfd, raw.version);
2774 cmd->rel = ver >> 16;
2775 cmd->maj = ver >> 8;
2776 cmd->min = ver;
2777 cmd->reserved = bfd_get_32 (abfd, raw.reserved);
2778 return TRUE;
2779}
2780
3af9a47b 2781static int
ab273af8
TG
2782bfd_mach_o_read_segment (bfd *abfd,
2783 bfd_mach_o_load_command *command,
2784 unsigned int wide)
3af9a47b 2785{
3af9a47b
NC
2786 bfd_mach_o_segment_command *seg = &command->command.segment;
2787 unsigned long i;
a95a4550 2788
1e8a024a
TG
2789 if (wide)
2790 {
46d1c23b
TG
2791 struct mach_o_segment_command_64_external raw;
2792
1e8a024a 2793 BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT_64);
3af9a47b 2794
46d1c23b
TG
2795 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
2796 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
2797 return -1;
3af9a47b 2798
46d1c23b 2799 memcpy (seg->segname, raw.segname, 16);
15e1c58a 2800 seg->segname[16] = '\0';
1e8a024a 2801
46d1c23b
TG
2802 seg->vmaddr = bfd_h_get_64 (abfd, raw.vmaddr);
2803 seg->vmsize = bfd_h_get_64 (abfd, raw.vmsize);
2804 seg->fileoff = bfd_h_get_64 (abfd, raw.fileoff);
2805 seg->filesize = bfd_h_get_64 (abfd, raw.filesize);
2806 seg->maxprot = bfd_h_get_32 (abfd, raw.maxprot);
2807 seg->initprot = bfd_h_get_32 (abfd, raw.initprot);
2808 seg->nsects = bfd_h_get_32 (abfd, raw.nsects);
2809 seg->flags = bfd_h_get_32 (abfd, raw.flags);
1e8a024a
TG
2810 }
2811 else
2812 {
46d1c23b
TG
2813 struct mach_o_segment_command_32_external raw;
2814
1e8a024a
TG
2815 BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT);
2816
46d1c23b
TG
2817 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
2818 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
2819 return -1;
1e8a024a 2820
46d1c23b 2821 memcpy (seg->segname, raw.segname, 16);
15e1c58a 2822 seg->segname[16] = '\0';
1e8a024a 2823
46d1c23b
TG
2824 seg->vmaddr = bfd_h_get_32 (abfd, raw.vmaddr);
2825 seg->vmsize = bfd_h_get_32 (abfd, raw.vmsize);
2826 seg->fileoff = bfd_h_get_32 (abfd, raw.fileoff);
2827 seg->filesize = bfd_h_get_32 (abfd, raw.filesize);
2828 seg->maxprot = bfd_h_get_32 (abfd, raw.maxprot);
2829 seg->initprot = bfd_h_get_32 (abfd, raw.initprot);
2830 seg->nsects = bfd_h_get_32 (abfd, raw.nsects);
2831 seg->flags = bfd_h_get_32 (abfd, raw.flags);
1e8a024a 2832 }
9d4b6009
TG
2833 seg->sect_head = NULL;
2834 seg->sect_tail = NULL;
3af9a47b 2835
f1bde64c 2836 for (i = 0; i < seg->nsects; i++)
3af9a47b 2837 {
f1bde64c
TG
2838 bfd_vma segoff;
2839 asection *sec;
a95a4550 2840
f1bde64c
TG
2841 if (wide)
2842 segoff = command->offset + BFD_MACH_O_LC_SEGMENT_64_SIZE
2843 + (i * BFD_MACH_O_SECTION_64_SIZE);
2844 else
2845 segoff = command->offset + BFD_MACH_O_LC_SEGMENT_SIZE
2846 + (i * BFD_MACH_O_SECTION_SIZE);
3af9a47b 2847
f1bde64c
TG
2848 sec = bfd_mach_o_read_section (abfd, segoff, seg->initprot, wide);
2849 if (sec == NULL)
2850 return -1;
2851
2852 bfd_mach_o_append_section_to_segment (seg, sec);
3af9a47b
NC
2853 }
2854
2855 return 0;
2856}
2857
1e8a024a 2858static int
ab273af8 2859bfd_mach_o_read_segment_32 (bfd *abfd, bfd_mach_o_load_command *command)
1e8a024a 2860{
ab273af8 2861 return bfd_mach_o_read_segment (abfd, command, 0);
1e8a024a
TG
2862}
2863
2864static int
ab273af8 2865bfd_mach_o_read_segment_64 (bfd *abfd, bfd_mach_o_load_command *command)
1e8a024a 2866{
ab273af8 2867 return bfd_mach_o_read_segment (abfd, command, 1);
1e8a024a
TG
2868}
2869
3af9a47b 2870static int
ab273af8 2871bfd_mach_o_read_command (bfd *abfd, bfd_mach_o_load_command *command)
3af9a47b 2872{
46d1c23b
TG
2873 struct mach_o_load_command_external raw;
2874 unsigned int cmd;
3af9a47b 2875
046b007d 2876 /* Read command type and length. */
c2f09c75 2877 if (bfd_seek (abfd, command->offset, SEEK_SET) != 0
46d1c23b 2878 || bfd_bread (&raw, BFD_MACH_O_LC_SIZE, abfd) != BFD_MACH_O_LC_SIZE)
3af9a47b
NC
2879 return -1;
2880
46d1c23b
TG
2881 cmd = bfd_h_get_32 (abfd, raw.cmd);
2882 command->type = cmd & ~BFD_MACH_O_LC_REQ_DYLD;
2883 command->type_required = cmd & BFD_MACH_O_LC_REQ_DYLD ? TRUE : FALSE;
2884 command->len = bfd_h_get_32 (abfd, raw.cmdsize);
3af9a47b
NC
2885
2886 switch (command->type)
2887 {
2888 case BFD_MACH_O_LC_SEGMENT:
ab273af8 2889 if (bfd_mach_o_read_segment_32 (abfd, command) != 0)
1e8a024a
TG
2890 return -1;
2891 break;
2892 case BFD_MACH_O_LC_SEGMENT_64:
ab273af8 2893 if (bfd_mach_o_read_segment_64 (abfd, command) != 0)
3af9a47b
NC
2894 return -1;
2895 break;
2896 case BFD_MACH_O_LC_SYMTAB:
ab273af8 2897 if (bfd_mach_o_read_symtab (abfd, command) != 0)
3af9a47b
NC
2898 return -1;
2899 break;
2900 case BFD_MACH_O_LC_SYMSEG:
2901 break;
2902 case BFD_MACH_O_LC_THREAD:
2903 case BFD_MACH_O_LC_UNIXTHREAD:
ab273af8 2904 if (bfd_mach_o_read_thread (abfd, command) != 0)
3af9a47b
NC
2905 return -1;
2906 break;
2907 case BFD_MACH_O_LC_LOAD_DYLINKER:
2908 case BFD_MACH_O_LC_ID_DYLINKER:
ab273af8 2909 if (bfd_mach_o_read_dylinker (abfd, command) != 0)
3af9a47b
NC
2910 return -1;
2911 break;
2912 case BFD_MACH_O_LC_LOAD_DYLIB:
2913 case BFD_MACH_O_LC_ID_DYLIB:
2914 case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
046b007d 2915 case BFD_MACH_O_LC_REEXPORT_DYLIB:
73017762 2916 case BFD_MACH_O_LC_LOAD_UPWARD_DYLIB:
ab273af8 2917 if (bfd_mach_o_read_dylib (abfd, command) != 0)
3af9a47b
NC
2918 return -1;
2919 break;
2920 case BFD_MACH_O_LC_PREBOUND_DYLIB:
ab273af8 2921 if (bfd_mach_o_read_prebound_dylib (abfd, command) != 0)
3af9a47b
NC
2922 return -1;
2923 break;
2924 case BFD_MACH_O_LC_LOADFVMLIB:
2925 case BFD_MACH_O_LC_IDFVMLIB:
2926 case BFD_MACH_O_LC_IDENT:
2927 case BFD_MACH_O_LC_FVMFILE:
2928 case BFD_MACH_O_LC_PREPAGE:
2929 case BFD_MACH_O_LC_ROUTINES:
9b02d212 2930 case BFD_MACH_O_LC_ROUTINES_64:
046b007d 2931 break;
3af9a47b 2932 case BFD_MACH_O_LC_SUB_FRAMEWORK:
046b007d
TG
2933 case BFD_MACH_O_LC_SUB_UMBRELLA:
2934 case BFD_MACH_O_LC_SUB_LIBRARY:
2935 case BFD_MACH_O_LC_SUB_CLIENT:
0c9b2b4c 2936 case BFD_MACH_O_LC_RPATH:
ab273af8 2937 if (bfd_mach_o_read_str (abfd, command) != 0)
046b007d 2938 return -1;
3af9a47b
NC
2939 break;
2940 case BFD_MACH_O_LC_DYSYMTAB:
ab273af8 2941 if (bfd_mach_o_read_dysymtab (abfd, command) != 0)
3af9a47b
NC
2942 return -1;
2943 break;
3af9a47b
NC
2944 case BFD_MACH_O_LC_TWOLEVEL_HINTS:
2945 case BFD_MACH_O_LC_PREBIND_CKSUM:
2946 break;
15e1c58a 2947 case BFD_MACH_O_LC_UUID:
ab273af8 2948 if (bfd_mach_o_read_uuid (abfd, command) != 0)
15e1c58a
TG
2949 return -1;
2950 break;
2951 case BFD_MACH_O_LC_CODE_SIGNATURE:
846b9259 2952 case BFD_MACH_O_LC_SEGMENT_SPLIT_INFO:
edbdea0e 2953 case BFD_MACH_O_LC_FUNCTION_STARTS:
ab273af8 2954 if (bfd_mach_o_read_linkedit (abfd, command) != 0)
046b007d 2955 return -1;
15e1c58a 2956 break;
ad86f1fb 2957 case BFD_MACH_O_LC_DYLD_INFO:
ab273af8 2958 if (bfd_mach_o_read_dyld_info (abfd, command) != 0)
ad86f1fb
TG
2959 return -1;
2960 break;
edbdea0e
TG
2961 case BFD_MACH_O_LC_VERSION_MIN_MACOSX:
2962 case BFD_MACH_O_LC_VERSION_MIN_IPHONEOS:
2963 if (!bfd_mach_o_read_version_min (abfd, command))
2964 return -1;
2965 break;
3af9a47b 2966 default:
c0d9d051
TG
2967 (*_bfd_error_handler)(_("%B: unable to read unknown load command 0x%lx"),
2968 abfd, (unsigned long) command->type);
3af9a47b
NC
2969 break;
2970 }
2971
2972 return 0;
2973}
2974
2975static void
116c20d2 2976bfd_mach_o_flatten_sections (bfd *abfd)
3af9a47b 2977{
046b007d 2978 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3af9a47b 2979 long csect = 0;
f1bde64c 2980 unsigned long i;
a95a4550 2981
15e1c58a 2982 /* Count total number of sections. */
3af9a47b
NC
2983 mdata->nsects = 0;
2984
2985 for (i = 0; i < mdata->header.ncmds; i++)
2986 {
1e8a024a
TG
2987 if (mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT
2988 || mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT_64)
3af9a47b 2989 {
e84d6fca
AM
2990 bfd_mach_o_segment_command *seg;
2991
2992 seg = &mdata->commands[i].command.segment;
3af9a47b
NC
2993 mdata->nsects += seg->nsects;
2994 }
2995 }
2996
15e1c58a 2997 /* Allocate sections array. */
e84d6fca
AM
2998 mdata->sections = bfd_alloc (abfd,
2999 mdata->nsects * sizeof (bfd_mach_o_section *));
15e1c58a
TG
3000
3001 /* Fill the array. */
3af9a47b
NC
3002 csect = 0;
3003
3004 for (i = 0; i < mdata->header.ncmds; i++)
3005 {
1e8a024a
TG
3006 if (mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT
3007 || mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT_64)
3af9a47b 3008 {
e84d6fca 3009 bfd_mach_o_segment_command *seg;
f1bde64c 3010 bfd_mach_o_section *sec;
3af9a47b 3011
e84d6fca 3012 seg = &mdata->commands[i].command.segment;
3af9a47b
NC
3013 BFD_ASSERT (csect + seg->nsects <= mdata->nsects);
3014
f1bde64c
TG
3015 for (sec = seg->sect_head; sec != NULL; sec = sec->next)
3016 mdata->sections[csect++] = sec;
3af9a47b
NC
3017 }
3018 }
3019}
3020
afbb9e17 3021static bfd_boolean
116c20d2 3022bfd_mach_o_scan_start_address (bfd *abfd)
3af9a47b 3023{
046b007d 3024 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3af9a47b
NC
3025 bfd_mach_o_thread_command *cmd = NULL;
3026 unsigned long i;
3027
3028 for (i = 0; i < mdata->header.ncmds; i++)
afbb9e17
TG
3029 if ((mdata->commands[i].type == BFD_MACH_O_LC_THREAD) ||
3030 (mdata->commands[i].type == BFD_MACH_O_LC_UNIXTHREAD))
3031 {
3032 cmd = &mdata->commands[i].command.thread;
3033 break;
3034 }
3af9a47b
NC
3035
3036 if (cmd == NULL)
afbb9e17 3037 return FALSE;
3af9a47b 3038
afbb9e17 3039 /* FIXME: create a subtarget hook ? */
3af9a47b
NC
3040 for (i = 0; i < cmd->nflavours; i++)
3041 {
a95a4550 3042 if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_I386)
e84d6fca 3043 && (cmd->flavours[i].flavour
15e1c58a 3044 == (unsigned long) BFD_MACH_O_x86_THREAD_STATE32))
3af9a47b
NC
3045 {
3046 unsigned char buf[4];
3047
c2f09c75
TG
3048 if (bfd_seek (abfd, cmd->flavours[i].offset + 40, 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 }
a95a4550 3054 else if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_POWERPC)
3af9a47b
NC
3055 && (cmd->flavours[i].flavour == BFD_MACH_O_PPC_THREAD_STATE))
3056 {
3057 unsigned char buf[4];
3058
c2f09c75
TG
3059 if (bfd_seek (abfd, cmd->flavours[i].offset + 0, SEEK_SET) != 0
3060 || bfd_bread (buf, 4, abfd) != 4)
afbb9e17 3061 return FALSE;
3af9a47b
NC
3062
3063 abfd->start_address = bfd_h_get_32 (abfd, buf);
3064 }
1e8a024a 3065 else if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_POWERPC_64)
b32e07d7 3066 && (cmd->flavours[i].flavour == BFD_MACH_O_PPC_THREAD_STATE64))
1e8a024a
TG
3067 {
3068 unsigned char buf[8];
3069
c2f09c75
TG
3070 if (bfd_seek (abfd, cmd->flavours[i].offset + 0, 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 }
3076 else if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_X86_64)
3077 && (cmd->flavours[i].flavour == BFD_MACH_O_x86_THREAD_STATE64))
3078 {
3079 unsigned char buf[8];
3080
c2f09c75
TG
3081 if (bfd_seek (abfd, cmd->flavours[i].offset + (16 * 8), SEEK_SET) != 0
3082 || bfd_bread (buf, 8, abfd) != 8)
afbb9e17 3083 return FALSE;
1e8a024a
TG
3084
3085 abfd->start_address = bfd_h_get_64 (abfd, buf);
3086 }
3af9a47b
NC
3087 }
3088
afbb9e17 3089 return TRUE;
3af9a47b
NC
3090}
3091
42fa0891
TG
3092bfd_boolean
3093bfd_mach_o_set_arch_mach (bfd *abfd,
3094 enum bfd_architecture arch,
3095 unsigned long machine)
3096{
3097 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
3098
3099 /* If this isn't the right architecture for this backend, and this
3100 isn't the generic backend, fail. */
3101 if (arch != bed->arch
3102 && arch != bfd_arch_unknown
3103 && bed->arch != bfd_arch_unknown)
3104 return FALSE;
3105
3106 return bfd_default_set_arch_mach (abfd, arch, machine);
3107}
3108
afbb9e17 3109static bfd_boolean
116c20d2
NC
3110bfd_mach_o_scan (bfd *abfd,
3111 bfd_mach_o_header *header,
3112 bfd_mach_o_data_struct *mdata)
3af9a47b
NC
3113{
3114 unsigned int i;
3af9a47b
NC
3115 enum bfd_architecture cputype;
3116 unsigned long cpusubtype;
1e8a024a
TG
3117 unsigned int hdrsize;
3118
c2f09c75 3119 hdrsize = mach_o_wide_p (header) ?
154a1ee5 3120 BFD_MACH_O_HEADER_64_SIZE : BFD_MACH_O_HEADER_SIZE;
3af9a47b 3121
3af9a47b 3122 mdata->header = *header;
3af9a47b 3123
154a1ee5 3124 abfd->flags = abfd->flags & BFD_IN_MEMORY;
15e1c58a
TG
3125 switch (header->filetype)
3126 {
3127 case BFD_MACH_O_MH_OBJECT:
3128 abfd->flags |= HAS_RELOC;
3129 break;
3130 case BFD_MACH_O_MH_EXECUTE:
3131 abfd->flags |= EXEC_P;
3132 break;
3133 case BFD_MACH_O_MH_DYLIB:
3134 case BFD_MACH_O_MH_BUNDLE:
3135 abfd->flags |= DYNAMIC;
3136 break;
3137 }
3138
3af9a47b
NC
3139 abfd->tdata.mach_o_data = mdata;
3140
e84d6fca
AM
3141 bfd_mach_o_convert_architecture (header->cputype, header->cpusubtype,
3142 &cputype, &cpusubtype);
3af9a47b
NC
3143 if (cputype == bfd_arch_unknown)
3144 {
afbb9e17
TG
3145 (*_bfd_error_handler)
3146 (_("bfd_mach_o_scan: unknown architecture 0x%lx/0x%lx"),
3147 header->cputype, header->cpusubtype);
3148 return FALSE;
3af9a47b
NC
3149 }
3150
3151 bfd_set_arch_mach (abfd, cputype, cpusubtype);
a95a4550 3152
3af9a47b
NC
3153 if (header->ncmds != 0)
3154 {
046b007d
TG
3155 mdata->commands = bfd_alloc
3156 (abfd, header->ncmds * sizeof (bfd_mach_o_load_command));
3af9a47b 3157 if (mdata->commands == NULL)
afbb9e17 3158 return FALSE;
a95a4550 3159
3af9a47b
NC
3160 for (i = 0; i < header->ncmds; i++)
3161 {
3162 bfd_mach_o_load_command *cur = &mdata->commands[i];
3163
3164 if (i == 0)
1e8a024a 3165 cur->offset = hdrsize;
3af9a47b
NC
3166 else
3167 {
3168 bfd_mach_o_load_command *prev = &mdata->commands[i - 1];
3169 cur->offset = prev->offset + prev->len;
3170 }
3171
ab273af8 3172 if (bfd_mach_o_read_command (abfd, cur) < 0)
afbb9e17 3173 return FALSE;
a95a4550 3174 }
3af9a47b
NC
3175 }
3176
3177 if (bfd_mach_o_scan_start_address (abfd) < 0)
afbb9e17 3178 return FALSE;
3af9a47b
NC
3179
3180 bfd_mach_o_flatten_sections (abfd);
afbb9e17 3181 return TRUE;
3af9a47b
NC
3182}
3183
b34976b6 3184bfd_boolean
154a1ee5 3185bfd_mach_o_mkobject_init (bfd *abfd)
3af9a47b
NC
3186{
3187 bfd_mach_o_data_struct *mdata = NULL;
3188
116c20d2 3189 mdata = bfd_alloc (abfd, sizeof (bfd_mach_o_data_struct));
3af9a47b 3190 if (mdata == NULL)
b34976b6 3191 return FALSE;
3af9a47b
NC
3192 abfd->tdata.mach_o_data = mdata;
3193
3194 mdata->header.magic = 0;
3195 mdata->header.cputype = 0;
3196 mdata->header.cpusubtype = 0;
3197 mdata->header.filetype = 0;
3198 mdata->header.ncmds = 0;
3199 mdata->header.sizeofcmds = 0;
3200 mdata->header.flags = 0;
3201 mdata->header.byteorder = BFD_ENDIAN_UNKNOWN;
3202 mdata->commands = NULL;
3af9a47b
NC
3203 mdata->nsects = 0;
3204 mdata->sections = NULL;
4434114c 3205 mdata->dyn_reloc_cache = NULL;
3af9a47b 3206
b34976b6 3207 return TRUE;
3af9a47b
NC
3208}
3209
42fa0891
TG
3210static bfd_boolean
3211bfd_mach_o_gen_mkobject (bfd *abfd)
3212{
3213 bfd_mach_o_data_struct *mdata;
3214
3215 if (!bfd_mach_o_mkobject_init (abfd))
3216 return FALSE;
3217
3218 mdata = bfd_mach_o_get_data (abfd);
3219 mdata->header.magic = BFD_MACH_O_MH_MAGIC;
3220 mdata->header.cputype = 0;
3221 mdata->header.cpusubtype = 0;
3222 mdata->header.byteorder = abfd->xvec->byteorder;
3223 mdata->header.version = 1;
3224
3225 return TRUE;
3226}
3227
3af9a47b 3228const bfd_target *
154a1ee5
TG
3229bfd_mach_o_header_p (bfd *abfd,
3230 bfd_mach_o_filetype filetype,
3231 bfd_mach_o_cpu_type cputype)
3af9a47b 3232{
e84d6fca 3233 struct bfd_preserve preserve;
3af9a47b
NC
3234 bfd_mach_o_header header;
3235
e84d6fca 3236 preserve.marker = NULL;
154a1ee5 3237 if (!bfd_mach_o_read_header (abfd, &header))
e84d6fca 3238 goto wrong;
3af9a47b 3239
e84d6fca
AM
3240 if (! (header.byteorder == BFD_ENDIAN_BIG
3241 || header.byteorder == BFD_ENDIAN_LITTLE))
3af9a47b 3242 {
4a97a0e5
AM
3243 (*_bfd_error_handler) (_("unknown header byte-order value 0x%lx"),
3244 (unsigned long) header.byteorder);
e84d6fca 3245 goto wrong;
3af9a47b
NC
3246 }
3247
e84d6fca
AM
3248 if (! ((header.byteorder == BFD_ENDIAN_BIG
3249 && abfd->xvec->byteorder == BFD_ENDIAN_BIG
3250 && abfd->xvec->header_byteorder == BFD_ENDIAN_BIG)
3251 || (header.byteorder == BFD_ENDIAN_LITTLE
3252 && abfd->xvec->byteorder == BFD_ENDIAN_LITTLE
3253 && abfd->xvec->header_byteorder == BFD_ENDIAN_LITTLE)))
3254 goto wrong;
3af9a47b 3255
154a1ee5
TG
3256 /* Check cputype and filetype.
3257 In case of wildcard, do not accept magics that are handled by existing
3258 targets. */
3259 if (cputype)
3260 {
3261 if (header.cputype != cputype)
3262 goto wrong;
3263 }
3264 else
3265 {
3266 switch (header.cputype)
3267 {
3268 case BFD_MACH_O_CPU_TYPE_I386:
3269 /* Handled by mach-o-i386 */
3270 goto wrong;
3271 default:
3272 break;
3273 }
3274 }
3275 if (filetype)
3276 {
3277 if (header.filetype != filetype)
3278 goto wrong;
3279 }
3280 else
3281 {
3282 switch (header.filetype)
3283 {
3284 case BFD_MACH_O_MH_CORE:
3285 /* Handled by core_p */
3286 goto wrong;
3287 default:
3288 break;
3289 }
3290 }
3291
e84d6fca
AM
3292 preserve.marker = bfd_zalloc (abfd, sizeof (bfd_mach_o_data_struct));
3293 if (preserve.marker == NULL
3294 || !bfd_preserve_save (abfd, &preserve))
3295 goto fail;
3af9a47b 3296
afbb9e17
TG
3297 if (!bfd_mach_o_scan (abfd, &header,
3298 (bfd_mach_o_data_struct *) preserve.marker))
e84d6fca 3299 goto wrong;
a95a4550 3300
e84d6fca 3301 bfd_preserve_finish (abfd, &preserve);
3af9a47b 3302 return abfd->xvec;
e84d6fca
AM
3303
3304 wrong:
3305 bfd_set_error (bfd_error_wrong_format);
3306
3307 fail:
3308 if (preserve.marker != NULL)
3309 bfd_preserve_restore (abfd, &preserve);
3310 return NULL;
3af9a47b
NC
3311}
3312
154a1ee5
TG
3313static const bfd_target *
3314bfd_mach_o_gen_object_p (bfd *abfd)
3af9a47b 3315{
154a1ee5
TG
3316 return bfd_mach_o_header_p (abfd, 0, 0);
3317}
e84d6fca 3318
154a1ee5
TG
3319static const bfd_target *
3320bfd_mach_o_gen_core_p (bfd *abfd)
3321{
3322 return bfd_mach_o_header_p (abfd, BFD_MACH_O_MH_CORE, 0);
3af9a47b
NC
3323}
3324
3325typedef struct mach_o_fat_archentry
3326{
3327 unsigned long cputype;
3328 unsigned long cpusubtype;
3329 unsigned long offset;
3330 unsigned long size;
3331 unsigned long align;
3af9a47b
NC
3332} mach_o_fat_archentry;
3333
3334typedef struct mach_o_fat_data_struct
3335{
3336 unsigned long magic;
3337 unsigned long nfat_arch;
3338 mach_o_fat_archentry *archentries;
3339} mach_o_fat_data_struct;
3340
3341const bfd_target *
116c20d2 3342bfd_mach_o_archive_p (bfd *abfd)
3af9a47b 3343{
e84d6fca 3344 mach_o_fat_data_struct *adata = NULL;
46d1c23b 3345 struct mach_o_fat_header_external hdr;
3af9a47b
NC
3346 unsigned long i;
3347
c2f09c75 3348 if (bfd_seek (abfd, 0, SEEK_SET) != 0
46d1c23b 3349 || bfd_bread (&hdr, sizeof (hdr), abfd) != sizeof (hdr))
e84d6fca 3350 goto error;
3af9a47b 3351
116c20d2 3352 adata = bfd_alloc (abfd, sizeof (mach_o_fat_data_struct));
3af9a47b 3353 if (adata == NULL)
e84d6fca 3354 goto error;
a95a4550 3355
46d1c23b
TG
3356 adata->magic = bfd_getb32 (hdr.magic);
3357 adata->nfat_arch = bfd_getb32 (hdr.nfat_arch);
3af9a47b 3358 if (adata->magic != 0xcafebabe)
e84d6fca 3359 goto error;
27cc28f9
AS
3360 /* Avoid matching Java bytecode files, which have the same magic number.
3361 In the Java bytecode file format this field contains the JVM version,
3362 which starts at 43.0. */
3363 if (adata->nfat_arch > 30)
3364 goto error;
3af9a47b 3365
c2f09c75 3366 adata->archentries =
3af9a47b
NC
3367 bfd_alloc (abfd, adata->nfat_arch * sizeof (mach_o_fat_archentry));
3368 if (adata->archentries == NULL)
e84d6fca 3369 goto error;
3af9a47b
NC
3370
3371 for (i = 0; i < adata->nfat_arch; i++)
3372 {
46d1c23b
TG
3373 struct mach_o_fat_arch_external arch;
3374 if (bfd_bread (&arch, sizeof (arch), abfd) != sizeof (arch))
e84d6fca 3375 goto error;
46d1c23b
TG
3376 adata->archentries[i].cputype = bfd_getb32 (arch.cputype);
3377 adata->archentries[i].cpusubtype = bfd_getb32 (arch.cpusubtype);
3378 adata->archentries[i].offset = bfd_getb32 (arch.offset);
3379 adata->archentries[i].size = bfd_getb32 (arch.size);
3380 adata->archentries[i].align = bfd_getb32 (arch.align);
3af9a47b
NC
3381 }
3382
3383 abfd->tdata.mach_o_fat_data = adata;
3384 return abfd->xvec;
e84d6fca
AM
3385
3386 error:
3387 if (adata != NULL)
3388 bfd_release (abfd, adata);
3389 bfd_set_error (bfd_error_wrong_format);
3390 return NULL;
3af9a47b
NC
3391}
3392
3393bfd *
116c20d2 3394bfd_mach_o_openr_next_archived_file (bfd *archive, bfd *prev)
3af9a47b 3395{
e84d6fca 3396 mach_o_fat_data_struct *adata;
3af9a47b
NC
3397 mach_o_fat_archentry *entry = NULL;
3398 unsigned long i;
15e1c58a 3399 bfd *nbfd;
15e1c58a
TG
3400 enum bfd_architecture arch_type;
3401 unsigned long arch_subtype;
3af9a47b 3402
e84d6fca 3403 adata = (mach_o_fat_data_struct *) archive->tdata.mach_o_fat_data;
3af9a47b
NC
3404 BFD_ASSERT (adata != NULL);
3405
3406 /* Find index of previous entry. */
3407 if (prev == NULL)
3408 i = 0; /* Start at first one. */
3409 else
3410 {
3411 for (i = 0; i < adata->nfat_arch; i++)
3412 {
15e1c58a 3413 if (adata->archentries[i].offset == prev->origin)
3af9a47b
NC
3414 break;
3415 }
3416
3417 if (i == adata->nfat_arch)
3418 {
3419 /* Not found. */
3420 bfd_set_error (bfd_error_bad_value);
a95a4550 3421 return NULL;
3af9a47b
NC
3422 }
3423 i++; /* Get next entry. */
3424 }
a95a4550 3425
3af9a47b
NC
3426 if (i >= adata->nfat_arch)
3427 {
3428 bfd_set_error (bfd_error_no_more_archived_files);
3429 return NULL;
3430 }
3431
3432 entry = &adata->archentries[i];
15e1c58a
TG
3433 nbfd = _bfd_new_bfd_contained_in (archive);
3434 if (nbfd == NULL)
3435 return NULL;
3436
3437 nbfd->origin = entry->offset;
3438
3439 bfd_mach_o_convert_architecture (entry->cputype, entry->cpusubtype,
3440 &arch_type, &arch_subtype);
846b9259 3441
c0d9d051
TG
3442 /* Create the member filename. Use ARCH_NAME. */
3443 nbfd->filename = bfd_printable_arch_mach (arch_type, arch_subtype);
15e1c58a 3444 nbfd->iostream = NULL;
846b9259 3445 bfd_set_arch_mach (nbfd, arch_type, arch_subtype);
3af9a47b 3446
15e1c58a 3447 return nbfd;
3af9a47b
NC
3448}
3449
846b9259
TG
3450/* If ABFD format is FORMAT and architecture is ARCH, return it.
3451 If ABFD is a fat image containing a member that corresponds to FORMAT
3452 and ARCH, returns it.
3453 In other case, returns NULL.
3454 This function allows transparent uses of fat images. */
3455bfd *
3456bfd_mach_o_fat_extract (bfd *abfd,
3457 bfd_format format,
3458 const bfd_arch_info_type *arch)
3459{
3460 bfd *res;
3461 mach_o_fat_data_struct *adata;
3462 unsigned int i;
3463
3464 if (bfd_check_format (abfd, format))
3465 {
3466 if (bfd_get_arch_info (abfd) == arch)
3467 return abfd;
3468 return NULL;
3469 }
3470 if (!bfd_check_format (abfd, bfd_archive)
3471 || abfd->xvec != &mach_o_fat_vec)
3472 return NULL;
c2f09c75 3473
846b9259
TG
3474 /* This is a Mach-O fat image. */
3475 adata = (mach_o_fat_data_struct *) abfd->tdata.mach_o_fat_data;
3476 BFD_ASSERT (adata != NULL);
3477
3478 for (i = 0; i < adata->nfat_arch; i++)
3479 {
3480 struct mach_o_fat_archentry *e = &adata->archentries[i];
3481 enum bfd_architecture cpu_type;
3482 unsigned long cpu_subtype;
3483
3484 bfd_mach_o_convert_architecture (e->cputype, e->cpusubtype,
3485 &cpu_type, &cpu_subtype);
3486 if (cpu_type != arch->arch || cpu_subtype != arch->mach)
3487 continue;
3488
3489 /* The architecture is found. */
3490 res = _bfd_new_bfd_contained_in (abfd);
3491 if (res == NULL)
3492 return NULL;
3493
3494 res->origin = e->offset;
3495
c0d9d051 3496 res->filename = bfd_printable_arch_mach (cpu_type, cpu_subtype);
846b9259
TG
3497 res->iostream = NULL;
3498
3499 if (bfd_check_format (res, format))
3500 {
3501 BFD_ASSERT (bfd_get_arch_info (res) == arch);
3502 return res;
3503 }
3504 bfd_close (res);
3505 return NULL;
3506 }
3507
3508 return NULL;
3509}
3510
3af9a47b 3511int
116c20d2
NC
3512bfd_mach_o_lookup_command (bfd *abfd,
3513 bfd_mach_o_load_command_type type,
3514 bfd_mach_o_load_command **mcommand)
3af9a47b 3515{
046b007d 3516 struct mach_o_data_struct *md = bfd_mach_o_get_data (abfd);
3af9a47b
NC
3517 bfd_mach_o_load_command *ncmd = NULL;
3518 unsigned int i, num;
3519
3af9a47b
NC
3520 BFD_ASSERT (md != NULL);
3521 BFD_ASSERT (mcommand != NULL);
3522
3523 num = 0;
3524 for (i = 0; i < md->header.ncmds; i++)
3525 {
3526 struct bfd_mach_o_load_command *cmd = &md->commands[i];
3527
3528 if (cmd->type != type)
3529 continue;
3530
3531 if (num == 0)
3532 ncmd = cmd;
3533 num++;
3534 }
3535
3536 *mcommand = ncmd;
3537 return num;
3538}
3539
3540unsigned long
116c20d2 3541bfd_mach_o_stack_addr (enum bfd_mach_o_cpu_type type)
3af9a47b
NC
3542{
3543 switch (type)
3544 {
3545 case BFD_MACH_O_CPU_TYPE_MC680x0:
3546 return 0x04000000;
3547 case BFD_MACH_O_CPU_TYPE_MC88000:
3548 return 0xffffe000;
3549 case BFD_MACH_O_CPU_TYPE_POWERPC:
3550 return 0xc0000000;
3551 case BFD_MACH_O_CPU_TYPE_I386:
3552 return 0xc0000000;
3553 case BFD_MACH_O_CPU_TYPE_SPARC:
3554 return 0xf0000000;
3555 case BFD_MACH_O_CPU_TYPE_I860:
3556 return 0;
3557 case BFD_MACH_O_CPU_TYPE_HPPA:
e84d6fca 3558 return 0xc0000000 - 0x04000000;
3af9a47b
NC
3559 default:
3560 return 0;
3561 }
3562}
3563
c5012cd8 3564const bfd_mach_o_xlat_name bfd_mach_o_section_type_name[] =
046b007d
TG
3565{
3566 { "regular", BFD_MACH_O_S_REGULAR},
3567 { "zerofill", BFD_MACH_O_S_ZEROFILL},
3568 { "cstring_literals", BFD_MACH_O_S_CSTRING_LITERALS},
3569 { "4byte_literals", BFD_MACH_O_S_4BYTE_LITERALS},
3570 { "8byte_literals", BFD_MACH_O_S_8BYTE_LITERALS},
3571 { "literal_pointers", BFD_MACH_O_S_LITERAL_POINTERS},
3572 { "non_lazy_symbol_pointers", BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS},
3573 { "lazy_symbol_pointers", BFD_MACH_O_S_LAZY_SYMBOL_POINTERS},
3574 { "symbol_stubs", BFD_MACH_O_S_SYMBOL_STUBS},
3575 { "mod_init_func_pointers", BFD_MACH_O_S_MOD_INIT_FUNC_POINTERS},
3576 { "mod_fini_func_pointers", BFD_MACH_O_S_MOD_FINI_FUNC_POINTERS},
3577 { "coalesced", BFD_MACH_O_S_COALESCED},
3578 { "gb_zerofill", BFD_MACH_O_S_GB_ZEROFILL},
3579 { "interposing", BFD_MACH_O_S_INTERPOSING},
3580 { "16byte_literals", BFD_MACH_O_S_16BYTE_LITERALS},
3581 { "dtrace_dof", BFD_MACH_O_S_DTRACE_DOF},
a4551119 3582 { "symbol_stubs", BFD_MACH_O_S_SYMBOL_STUBS},
046b007d
TG
3583 { "lazy_dylib_symbol_pointers", BFD_MACH_O_S_LAZY_DYLIB_SYMBOL_POINTERS},
3584 { NULL, 0}
3585};
3586
c5012cd8 3587const bfd_mach_o_xlat_name bfd_mach_o_section_attribute_name[] =
046b007d
TG
3588{
3589 { "loc_reloc", BFD_MACH_O_S_ATTR_LOC_RELOC },
3590 { "ext_reloc", BFD_MACH_O_S_ATTR_EXT_RELOC },
3591 { "some_instructions", BFD_MACH_O_S_ATTR_SOME_INSTRUCTIONS },
3592 { "debug", BFD_MACH_O_S_ATTR_DEBUG },
3593 { "modifying_code", BFD_MACH_O_S_SELF_MODIFYING_CODE },
3594 { "live_support", BFD_MACH_O_S_ATTR_LIVE_SUPPORT },
3595 { "no_dead_strip", BFD_MACH_O_S_ATTR_NO_DEAD_STRIP },
3596 { "strip_static_syms", BFD_MACH_O_S_ATTR_STRIP_STATIC_SYMS },
3597 { "no_toc", BFD_MACH_O_S_ATTR_NO_TOC },
3598 { "pure_instructions", BFD_MACH_O_S_ATTR_PURE_INSTRUCTIONS },
a4551119 3599 { "self_modifying_code", BFD_MACH_O_S_SELF_MODIFYING_CODE },
046b007d
TG
3600 { NULL, 0}
3601};
3602
a4551119 3603/* Get the section type from NAME. Return 256 if NAME is unknown. */
53d58d96
TG
3604
3605unsigned int
3606bfd_mach_o_get_section_type_from_name (const char *name)
3607{
afbb9e17 3608 const bfd_mach_o_xlat_name *x;
53d58d96
TG
3609
3610 for (x = bfd_mach_o_section_type_name; x->name; x++)
3611 if (strcmp (x->name, name) == 0)
3612 return x->val;
a4551119
TG
3613 /* Maximum section ID = 0xff. */
3614 return 256;
53d58d96
TG
3615}
3616
3617/* Get the section attribute from NAME. Return -1 if NAME is unknown. */
3618
3619unsigned int
3620bfd_mach_o_get_section_attribute_from_name (const char *name)
3621{
afbb9e17 3622 const bfd_mach_o_xlat_name *x;
53d58d96
TG
3623
3624 for (x = bfd_mach_o_section_attribute_name; x->name; x++)
3625 if (strcmp (x->name, name) == 0)
3626 return x->val;
3627 return (unsigned int)-1;
3628}
3629
3af9a47b 3630int
116c20d2
NC
3631bfd_mach_o_core_fetch_environment (bfd *abfd,
3632 unsigned char **rbuf,
3633 unsigned int *rlen)
3af9a47b 3634{
046b007d 3635 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3af9a47b
NC
3636 unsigned long stackaddr = bfd_mach_o_stack_addr (mdata->header.cputype);
3637 unsigned int i = 0;
3638
3639 for (i = 0; i < mdata->header.ncmds; i++)
3640 {
3641 bfd_mach_o_load_command *cur = &mdata->commands[i];
3642 bfd_mach_o_segment_command *seg = NULL;
3643
3644 if (cur->type != BFD_MACH_O_LC_SEGMENT)
3645 continue;
3646
3647 seg = &cur->command.segment;
3648
3649 if ((seg->vmaddr + seg->vmsize) == stackaddr)
3650 {
3651 unsigned long start = seg->fileoff;
3652 unsigned long end = seg->fileoff + seg->filesize;
3653 unsigned char *buf = bfd_malloc (1024);
3654 unsigned long size = 1024;
3655
3656 for (;;)
3657 {
3658 bfd_size_type nread = 0;
3659 unsigned long offset;
3660 int found_nonnull = 0;
3661
3662 if (size > (end - start))
3663 size = (end - start);
3664
515ef31d
NC
3665 buf = bfd_realloc_or_free (buf, size);
3666 if (buf == NULL)
3667 return -1;
c2f09c75
TG
3668
3669 if (bfd_seek (abfd, end - size, SEEK_SET) != 0)
3670 {
3671 free (buf);
3672 return -1;
3673 }
3674
3af9a47b 3675 nread = bfd_bread (buf, size, abfd);
a95a4550 3676
3af9a47b 3677 if (nread != size)
515ef31d
NC
3678 {
3679 free (buf);
3680 return -1;
3681 }
a95a4550 3682
3af9a47b
NC
3683 for (offset = 4; offset <= size; offset += 4)
3684 {
e84d6fca 3685 unsigned long val;
3af9a47b 3686
e84d6fca 3687 val = *((unsigned long *) (buf + size - offset));
3af9a47b
NC
3688 if (! found_nonnull)
3689 {
3690 if (val != 0)
3691 found_nonnull = 1;
3692 }
3693 else if (val == 0x0)
3694 {
e84d6fca
AM
3695 unsigned long bottom;
3696 unsigned long top;
3af9a47b 3697
e84d6fca
AM
3698 bottom = seg->fileoff + seg->filesize - offset;
3699 top = seg->fileoff + seg->filesize - 4;
3af9a47b
NC
3700 *rbuf = bfd_malloc (top - bottom);
3701 *rlen = top - bottom;
3702
3703 memcpy (*rbuf, buf + size - *rlen, *rlen);
515ef31d 3704 free (buf);
3af9a47b
NC
3705 return 0;
3706 }
3707 }
3708
3709 if (size == (end - start))
3710 break;
3711
3712 size *= 2;
3713 }
515ef31d
NC
3714
3715 free (buf);
3af9a47b
NC
3716 }
3717 }
3718
3719 return -1;
3720}
3721
3722char *
116c20d2 3723bfd_mach_o_core_file_failing_command (bfd *abfd)
3af9a47b
NC
3724{
3725 unsigned char *buf = NULL;
3726 unsigned int len = 0;
3727 int ret = -1;
3728
3729 ret = bfd_mach_o_core_fetch_environment (abfd, &buf, &len);
3730 if (ret < 0)
3731 return NULL;
3732
f075ee0c 3733 return (char *) buf;
3af9a47b
NC
3734}
3735
3736int
116c20d2 3737bfd_mach_o_core_file_failing_signal (bfd *abfd ATTRIBUTE_UNUSED)
3af9a47b
NC
3738{
3739 return 0;
3740}
3741
d9071b0c
TG
3742bfd_boolean
3743bfd_mach_o_find_nearest_line (bfd *abfd,
3744 asection *section,
3745 asymbol **symbols,
3746 bfd_vma offset,
3747 const char **filename_ptr,
3748 const char **functionname_ptr,
3749 unsigned int *line_ptr)
3750{
3751 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3752 /* TODO: Handle executables and dylibs by using dSYMs. */
3753 if (mdata->header.filetype != BFD_MACH_O_MH_OBJECT)
3754 return FALSE;
3755 if (_bfd_dwarf2_find_nearest_line (abfd, dwarf_debug_sections,
3756 section, symbols, offset,
3757 filename_ptr, functionname_ptr,
3758 line_ptr, 0,
3759 &mdata->dwarf2_find_line_info))
3760 return TRUE;
3761 return FALSE;
3762}
3763
3764bfd_boolean
3765bfd_mach_o_close_and_cleanup (bfd *abfd)
3766{
3767 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3768 if (bfd_get_format (abfd) == bfd_object && mdata != NULL)
4434114c
TG
3769 {
3770 _bfd_dwarf2_cleanup_debug_info (abfd, &mdata->dwarf2_find_line_info);
3771 bfd_mach_o_free_cached_info (abfd);
3772 }
dff55db0 3773
d9071b0c
TG
3774 return _bfd_generic_close_and_cleanup (abfd);
3775}
3776
dff55db0
TG
3777bfd_boolean bfd_mach_o_free_cached_info (bfd *abfd)
3778{
3779 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3780 asection *asect;
3781 free (mdata->dyn_reloc_cache);
3782 mdata->dyn_reloc_cache = NULL;
3783 for (asect = abfd->sections; asect != NULL; asect = asect->next)
3784 {
3785 free (asect->relocation);
3786 asect->relocation = NULL;
3787 }
3788
3789 return TRUE;
3790}
3791
92bc0e80
TG
3792#define bfd_mach_o_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup
3793#define bfd_mach_o_bfd_reloc_name_lookup _bfd_norelocs_bfd_reloc_name_lookup
3794
3795#define bfd_mach_o_swap_reloc_in NULL
3796#define bfd_mach_o_swap_reloc_out NULL
b32e07d7 3797#define bfd_mach_o_print_thread NULL
a4551119 3798#define bfd_mach_o_tgt_seg_table NULL
92bc0e80 3799
116c20d2
NC
3800#define TARGET_NAME mach_o_be_vec
3801#define TARGET_STRING "mach-o-be"
42fa0891 3802#define TARGET_ARCHITECTURE bfd_arch_unknown
116c20d2
NC
3803#define TARGET_BIG_ENDIAN 1
3804#define TARGET_ARCHIVE 0
3af9a47b
NC
3805#include "mach-o-target.c"
3806
3807#undef TARGET_NAME
3808#undef TARGET_STRING
42fa0891 3809#undef TARGET_ARCHITECTURE
3af9a47b
NC
3810#undef TARGET_BIG_ENDIAN
3811#undef TARGET_ARCHIVE
3812
116c20d2
NC
3813#define TARGET_NAME mach_o_le_vec
3814#define TARGET_STRING "mach-o-le"
42fa0891 3815#define TARGET_ARCHITECTURE bfd_arch_unknown
116c20d2
NC
3816#define TARGET_BIG_ENDIAN 0
3817#define TARGET_ARCHIVE 0
3af9a47b
NC
3818
3819#include "mach-o-target.c"
3820
3821#undef TARGET_NAME
3822#undef TARGET_STRING
42fa0891 3823#undef TARGET_ARCHITECTURE
3af9a47b
NC
3824#undef TARGET_BIG_ENDIAN
3825#undef TARGET_ARCHIVE
3826
8f95b6e4
TG
3827/* Not yet handled: creating an archive. */
3828#define bfd_mach_o_mkarchive _bfd_noarchive_mkarchive
3829
3830/* Not used. */
3831#define bfd_mach_o_read_ar_hdr _bfd_noarchive_read_ar_hdr
3832#define bfd_mach_o_write_ar_hdr _bfd_noarchive_write_ar_hdr
3833#define bfd_mach_o_slurp_armap _bfd_noarchive_slurp_armap
3834#define bfd_mach_o_slurp_extended_name_table _bfd_noarchive_slurp_extended_name_table
3835#define bfd_mach_o_construct_extended_name_table _bfd_noarchive_construct_extended_name_table
3836#define bfd_mach_o_truncate_arname _bfd_noarchive_truncate_arname
3837#define bfd_mach_o_write_armap _bfd_noarchive_write_armap
3838#define bfd_mach_o_get_elt_at_index _bfd_noarchive_get_elt_at_index
3839#define bfd_mach_o_generic_stat_arch_elt _bfd_noarchive_generic_stat_arch_elt
3840#define bfd_mach_o_update_armap_timestamp _bfd_noarchive_update_armap_timestamp
3841
116c20d2
NC
3842#define TARGET_NAME mach_o_fat_vec
3843#define TARGET_STRING "mach-o-fat"
42fa0891 3844#define TARGET_ARCHITECTURE bfd_arch_unknown
116c20d2
NC
3845#define TARGET_BIG_ENDIAN 1
3846#define TARGET_ARCHIVE 1
3af9a47b
NC
3847
3848#include "mach-o-target.c"
3849
3850#undef TARGET_NAME
3851#undef TARGET_STRING
42fa0891 3852#undef TARGET_ARCHITECTURE
3af9a47b
NC
3853#undef TARGET_BIG_ENDIAN
3854#undef TARGET_ARCHIVE
This page took 0.861528 seconds and 4 git commands to generate.