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