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