]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - bfd/mach-o.c
Fix problem where gold does not create base version for executables.
[thirdparty/binutils-gdb.git] / bfd / mach-o.c
CommitLineData
3af9a47b 1/* Mach-O support for BFD.
219d1afa 2 Copyright (C) 1999-2018 Free Software Foundation, Inc.
3af9a47b
NC
3
4 This file is part of BFD, the Binary File Descriptor library.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
cd123cb7 8 the Free Software Foundation; either version 3 of the License, or
3af9a47b
NC
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
a95a4550 17 along with this program; if not, write to the Free Software
cd123cb7
NC
18 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19 MA 02110-1301, USA. */
3af9a47b 20
3db64b00 21#include "sysdep.h"
3af9a47b
NC
22#include "mach-o.h"
23#include "bfd.h"
3af9a47b
NC
24#include "libbfd.h"
25#include "libiberty.h"
15e1c58a 26#include "aout/stab_gnu.h"
46d1c23b
TG
27#include "mach-o/reloc.h"
28#include "mach-o/external.h"
3af9a47b 29#include <ctype.h>
7f307238
IS
30#include <stdlib.h>
31#include <string.h>
3af9a47b 32
154a1ee5
TG
33#define bfd_mach_o_object_p bfd_mach_o_gen_object_p
34#define bfd_mach_o_core_p bfd_mach_o_gen_core_p
42fa0891 35#define bfd_mach_o_mkobject bfd_mach_o_gen_mkobject
116c20d2 36
92bc0e80 37#define FILE_ALIGN(off, algn) \
b6518b38 38 (((off) + ((file_ptr) 1 << (algn)) - 1) & ((file_ptr) -1U << (algn)))
92bc0e80 39
c9ffd2ea
TG
40static bfd_boolean
41bfd_mach_o_read_dyld_content (bfd *abfd, bfd_mach_o_dyld_info_command *cmd);
42
c2f09c75 43unsigned int
1e8a024a
TG
44bfd_mach_o_version (bfd *abfd)
45{
46 bfd_mach_o_data_struct *mdata = NULL;
47
48 BFD_ASSERT (bfd_mach_o_valid (abfd));
046b007d 49 mdata = bfd_mach_o_get_data (abfd);
1e8a024a
TG
50
51 return mdata->header.version;
52}
53
b34976b6 54bfd_boolean
116c20d2 55bfd_mach_o_valid (bfd *abfd)
3af9a47b
NC
56{
57 if (abfd == NULL || abfd->xvec == NULL)
154a1ee5 58 return FALSE;
3af9a47b 59
154a1ee5
TG
60 if (abfd->xvec->flavour != bfd_target_mach_o_flavour)
61 return FALSE;
3af9a47b 62
046b007d 63 if (bfd_mach_o_get_data (abfd) == NULL)
154a1ee5
TG
64 return FALSE;
65 return TRUE;
66}
67
c2f09c75
TG
68static INLINE bfd_boolean
69mach_o_wide_p (bfd_mach_o_header *header)
70{
71 switch (header->version)
72 {
73 case 1:
74 return FALSE;
75 case 2:
76 return TRUE;
77 default:
78 BFD_FAIL ();
79 return FALSE;
80 }
81}
82
83static INLINE bfd_boolean
84bfd_mach_o_wide_p (bfd *abfd)
85{
046b007d 86 return mach_o_wide_p (&bfd_mach_o_get_data (abfd)->header);
c2f09c75 87}
68ffbac6 88
154a1ee5
TG
89/* Tables to translate well known Mach-O segment/section names to bfd
90 names. Use of canonical names (such as .text or .debug_frame) is required
91 by gdb. */
92
a4551119
TG
93/* __TEXT Segment. */
94static const mach_o_section_name_xlat text_section_names_xlat[] =
154a1ee5 95 {
68ffbac6 96 { ".text", "__text",
a4551119
TG
97 SEC_CODE | SEC_LOAD, BFD_MACH_O_S_REGULAR,
98 BFD_MACH_O_S_ATTR_PURE_INSTRUCTIONS, 0},
99 { ".const", "__const",
100 SEC_READONLY | SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
101 BFD_MACH_O_S_ATTR_NONE, 0},
102 { ".static_const", "__static_const",
103 SEC_READONLY | SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
104 BFD_MACH_O_S_ATTR_NONE, 0},
105 { ".cstring", "__cstring",
106 SEC_READONLY | SEC_DATA | SEC_LOAD | SEC_MERGE | SEC_STRINGS,
107 BFD_MACH_O_S_CSTRING_LITERALS,
108 BFD_MACH_O_S_ATTR_NONE, 0},
109 { ".literal4", "__literal4",
110 SEC_READONLY | SEC_DATA | SEC_LOAD, BFD_MACH_O_S_4BYTE_LITERALS,
111 BFD_MACH_O_S_ATTR_NONE, 2},
112 { ".literal8", "__literal8",
113 SEC_READONLY | SEC_DATA | SEC_LOAD, BFD_MACH_O_S_8BYTE_LITERALS,
114 BFD_MACH_O_S_ATTR_NONE, 3},
115 { ".literal16", "__literal16",
116 SEC_READONLY | SEC_DATA | SEC_LOAD, BFD_MACH_O_S_16BYTE_LITERALS,
117 BFD_MACH_O_S_ATTR_NONE, 4},
118 { ".constructor", "__constructor",
119 SEC_CODE | SEC_LOAD, BFD_MACH_O_S_REGULAR,
120 BFD_MACH_O_S_ATTR_NONE, 0},
121 { ".destructor", "__destructor",
122 SEC_CODE | SEC_LOAD, BFD_MACH_O_S_REGULAR,
123 BFD_MACH_O_S_ATTR_NONE, 0},
124 { ".eh_frame", "__eh_frame",
632039e0 125 SEC_READONLY | SEC_DATA | SEC_LOAD, BFD_MACH_O_S_COALESCED,
a4551119
TG
126 BFD_MACH_O_S_ATTR_LIVE_SUPPORT
127 | BFD_MACH_O_S_ATTR_STRIP_STATIC_SYMS
632039e0 128 | BFD_MACH_O_S_ATTR_NO_TOC, 2},
a4551119 129 { NULL, NULL, 0, 0, 0, 0}
154a1ee5
TG
130 };
131
a4551119
TG
132/* __DATA Segment. */
133static const mach_o_section_name_xlat data_section_names_xlat[] =
154a1ee5 134 {
a4551119
TG
135 { ".data", "__data",
136 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
137 BFD_MACH_O_S_ATTR_NONE, 0},
138 { ".bss", "__bss",
139 SEC_NO_FLAGS, BFD_MACH_O_S_ZEROFILL,
140 BFD_MACH_O_S_ATTR_NONE, 0},
141 { ".const_data", "__const",
142 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
143 BFD_MACH_O_S_ATTR_NONE, 0},
144 { ".static_data", "__static_data",
145 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
146 BFD_MACH_O_S_ATTR_NONE, 0},
147 { ".mod_init_func", "__mod_init_func",
148 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_MOD_INIT_FUNC_POINTERS,
149 BFD_MACH_O_S_ATTR_NONE, 2},
150 { ".mod_term_func", "__mod_term_func",
151 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_MOD_FINI_FUNC_POINTERS,
152 BFD_MACH_O_S_ATTR_NONE, 2},
153 { ".dyld", "__dyld",
154 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
155 BFD_MACH_O_S_ATTR_NONE, 0},
156 { ".cfstring", "__cfstring",
157 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
158 BFD_MACH_O_S_ATTR_NONE, 2},
159 { NULL, NULL, 0, 0, 0, 0}
154a1ee5
TG
160 };
161
a4551119
TG
162/* __DWARF Segment. */
163static const mach_o_section_name_xlat dwarf_section_names_xlat[] =
154a1ee5 164 {
a4551119
TG
165 { ".debug_frame", "__debug_frame",
166 SEC_DEBUGGING, BFD_MACH_O_S_REGULAR,
167 BFD_MACH_O_S_ATTR_DEBUG, 0},
168 { ".debug_info", "__debug_info",
169 SEC_DEBUGGING, BFD_MACH_O_S_REGULAR,
170 BFD_MACH_O_S_ATTR_DEBUG, 0},
171 { ".debug_abbrev", "__debug_abbrev",
172 SEC_DEBUGGING, BFD_MACH_O_S_REGULAR,
173 BFD_MACH_O_S_ATTR_DEBUG, 0},
174 { ".debug_aranges", "__debug_aranges",
175 SEC_DEBUGGING, BFD_MACH_O_S_REGULAR,
176 BFD_MACH_O_S_ATTR_DEBUG, 0},
177 { ".debug_macinfo", "__debug_macinfo",
178 SEC_DEBUGGING, BFD_MACH_O_S_REGULAR,
179 BFD_MACH_O_S_ATTR_DEBUG, 0},
180 { ".debug_line", "__debug_line",
181 SEC_DEBUGGING, BFD_MACH_O_S_REGULAR,
182 BFD_MACH_O_S_ATTR_DEBUG, 0},
183 { ".debug_loc", "__debug_loc",
184 SEC_DEBUGGING, BFD_MACH_O_S_REGULAR,
185 BFD_MACH_O_S_ATTR_DEBUG, 0},
186 { ".debug_pubnames", "__debug_pubnames",
187 SEC_DEBUGGING, BFD_MACH_O_S_REGULAR,
188 BFD_MACH_O_S_ATTR_DEBUG, 0},
189 { ".debug_pubtypes", "__debug_pubtypes",
190 SEC_DEBUGGING, BFD_MACH_O_S_REGULAR,
191 BFD_MACH_O_S_ATTR_DEBUG, 0},
192 { ".debug_str", "__debug_str",
193 SEC_DEBUGGING, BFD_MACH_O_S_REGULAR,
194 BFD_MACH_O_S_ATTR_DEBUG, 0},
195 { ".debug_ranges", "__debug_ranges",
196 SEC_DEBUGGING, BFD_MACH_O_S_REGULAR,
197 BFD_MACH_O_S_ATTR_DEBUG, 0},
198 { ".debug_macro", "__debug_macro",
199 SEC_DEBUGGING, BFD_MACH_O_S_REGULAR,
200 BFD_MACH_O_S_ATTR_DEBUG, 0},
671a6cbe
NC
201 { ".debug_gdb_scripts", "__debug_gdb_scri",
202 SEC_DEBUGGING, BFD_MACH_O_S_REGULAR,
203 BFD_MACH_O_S_ATTR_DEBUG, 0},
a4551119 204 { NULL, NULL, 0, 0, 0, 0}
154a1ee5
TG
205 };
206
a4551119
TG
207/* __OBJC Segment. */
208static const mach_o_section_name_xlat objc_section_names_xlat[] =
209 {
210 { ".objc_class", "__class",
211 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
212 BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
213 { ".objc_meta_class", "__meta_class",
214 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
215 BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
216 { ".objc_cat_cls_meth", "__cat_cls_meth",
217 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
218 BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
219 { ".objc_cat_inst_meth", "__cat_inst_meth",
220 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
221 BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
222 { ".objc_protocol", "__protocol",
223 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
224 BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
225 { ".objc_string_object", "__string_object",
226 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
227 BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
228 { ".objc_cls_meth", "__cls_meth",
229 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
230 BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
231 { ".objc_inst_meth", "__inst_meth",
232 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
233 BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
234 { ".objc_cls_refs", "__cls_refs",
235 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_LITERAL_POINTERS,
236 BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
237 { ".objc_message_refs", "__message_refs",
238 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_LITERAL_POINTERS,
239 BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
240 { ".objc_symbols", "__symbols",
241 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
242 BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
243 { ".objc_category", "__category",
244 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
245 BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
246 { ".objc_class_vars", "__class_vars",
247 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
248 BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
249 { ".objc_instance_vars", "__instance_vars",
250 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
251 BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
252 { ".objc_module_info", "__module_info",
253 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
254 BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
255 { ".objc_selector_strs", "__selector_strs",
256 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_CSTRING_LITERALS,
257 BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
258 { ".objc_image_info", "__image_info",
259 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
260 BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
261 { ".objc_selector_fixup", "__sel_fixup",
262 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
263 BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
264 /* Objc V1 */
265 { ".objc1_class_ext", "__class_ext",
266 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
267 BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
268 { ".objc1_property_list", "__property",
269 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
270 BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
271 { ".objc1_protocol_ext", "__protocol_ext",
272 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
273 BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
274 { NULL, NULL, 0, 0, 0, 0}
275 };
5a5cbf72 276
a4551119 277static const mach_o_segment_name_xlat segsec_names_xlat[] =
154a1ee5 278 {
154a1ee5
TG
279 { "__TEXT", text_section_names_xlat },
280 { "__DATA", data_section_names_xlat },
5a5cbf72 281 { "__DWARF", dwarf_section_names_xlat },
a4551119 282 { "__OBJC", objc_section_names_xlat },
154a1ee5
TG
283 { NULL, NULL }
284 };
285
2ca7691a
TG
286static const char dsym_subdir[] = ".dSYM/Contents/Resources/DWARF";
287
a4551119
TG
288/* For both cases bfd-name => mach-o name and vice versa, the specific target
289 is checked before the generic. This allows a target (e.g. ppc for cstring)
290 to override the generic definition with a more specific one. */
154a1ee5 291
a4551119
TG
292/* Fetch the translation from a Mach-O section designation (segment, section)
293 as a bfd short name, if one exists. Otherwise return NULL.
68ffbac6 294
a4551119
TG
295 Allow the segment and section names to be unterminated 16 byte arrays. */
296
297const mach_o_section_name_xlat *
298bfd_mach_o_section_data_for_mach_sect (bfd *abfd, const char *segname,
299 const char *sectname)
154a1ee5
TG
300{
301 const struct mach_o_segment_name_xlat *seg;
a4551119
TG
302 const mach_o_section_name_xlat *sec;
303 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
154a1ee5 304
a4551119
TG
305 /* First try any target-specific translations defined... */
306 if (bed->segsec_names_xlat)
307 for (seg = bed->segsec_names_xlat; seg->segname; seg++)
308 if (strncmp (seg->segname, segname, BFD_MACH_O_SEGNAME_SIZE) == 0)
309 for (sec = seg->sections; sec->mach_o_name; sec++)
310 if (strncmp (sec->mach_o_name, sectname,
311 BFD_MACH_O_SECTNAME_SIZE) == 0)
312 return sec;
8462aec7 313
a4551119 314 /* ... and then the Mach-O generic ones. */
154a1ee5 315 for (seg = segsec_names_xlat; seg->segname; seg++)
a4551119
TG
316 if (strncmp (seg->segname, segname, BFD_MACH_O_SEGNAME_SIZE) == 0)
317 for (sec = seg->sections; sec->mach_o_name; sec++)
07d6d2b8 318 if (strncmp (sec->mach_o_name, sectname,
a4551119 319 BFD_MACH_O_SECTNAME_SIZE) == 0)
07d6d2b8 320 return sec;
154a1ee5 321
68ffbac6 322 return NULL;
53d58d96
TG
323}
324
a4551119 325/* If the bfd_name for this section is a 'canonical' form for which we
68ffbac6 326 know the Mach-O data, return the segment name and the data for the
a4551119 327 Mach-O equivalent. Otherwise return NULL. */
7ba695a9 328
a4551119
TG
329const mach_o_section_name_xlat *
330bfd_mach_o_section_data_for_bfd_name (bfd *abfd, const char *bfd_name,
331 const char **segname)
53d58d96 332{
a4551119
TG
333 const struct mach_o_segment_name_xlat *seg;
334 const mach_o_section_name_xlat *sec;
335 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
336 *segname = NULL;
337
338 if (bfd_name[0] != '.')
339 return NULL;
340
341 /* First try any target-specific translations defined... */
342 if (bed->segsec_names_xlat)
343 for (seg = bed->segsec_names_xlat; seg->segname; seg++)
344 for (sec = seg->sections; sec->bfd_name; sec++)
345 if (strcmp (bfd_name, sec->bfd_name) == 0)
346 {
347 *segname = seg->segname;
348 return sec;
349 }
350
351 /* ... and then the Mach-O generic ones. */
352 for (seg = segsec_names_xlat; seg->segname; seg++)
353 for (sec = seg->sections; sec->bfd_name; sec++)
354 if (strcmp (bfd_name, sec->bfd_name) == 0)
355 {
356 *segname = seg->segname;
357 return sec;
358 }
359
68ffbac6 360 return NULL;
a4551119
TG
361}
362
363/* Convert Mach-O section name to BFD.
364
68ffbac6 365 Try to use standard/canonical names, for which we have tables including
a4551119
TG
366 default flag settings - which are returned. Otherwise forge a new name
367 in the form "<segmentname>.<sectionname>" this will be prefixed with
368 LC_SEGMENT. if the segment name does not begin with an underscore.
369
370 SEGNAME and SECTNAME are 16 byte arrays (they do not need to be NUL-
371 terminated if the name length is exactly 16 bytes - but must be if the name
372 length is less than 16 characters). */
373
374void
375bfd_mach_o_convert_section_name_to_bfd (bfd *abfd, const char *segname,
376 const char *secname, const char **name,
377 flagword *flags)
378{
379 const mach_o_section_name_xlat *xlat;
53d58d96
TG
380 char *res;
381 unsigned int len;
382 const char *pfx = "";
383
a4551119
TG
384 *name = NULL;
385 *flags = SEC_NO_FLAGS;
53d58d96 386
68ffbac6 387 /* First search for a canonical name...
a4551119
TG
388 xlat will be non-null if there is an entry for segname, secname. */
389 xlat = bfd_mach_o_section_data_for_mach_sect (abfd, segname, secname);
390 if (xlat)
391 {
392 len = strlen (xlat->bfd_name);
64d29018 393 res = bfd_alloc (abfd, len + 1);
a4551119
TG
394 if (res == NULL)
395 return;
396 memcpy (res, xlat->bfd_name, len+1);
397 *name = res;
398 *flags = xlat->bfd_flags;
399 return;
400 }
401
402 /* ... else we make up a bfd name from the segment concatenated with the
403 section. */
154a1ee5 404
7ba695a9 405 len = 16 + 1 + 16 + 1;
154a1ee5 406
c2f09c75
TG
407 /* Put "LC_SEGMENT." prefix if the segment name is weird (ie doesn't start
408 with an underscore. */
f1bde64c 409 if (segname[0] != '_')
c2f09c75
TG
410 {
411 static const char seg_pfx[] = "LC_SEGMENT.";
412
413 pfx = seg_pfx;
414 len += sizeof (seg_pfx) - 1;
415 }
416
154a1ee5
TG
417 res = bfd_alloc (abfd, len);
418 if (res == NULL)
8462aec7 419 return;
a4551119 420 snprintf (res, len, "%s%.16s.%.16s", pfx, segname, secname);
8462aec7 421 *name = res;
154a1ee5
TG
422}
423
a4551119 424/* Convert a bfd section name to a Mach-O segment + section name.
154a1ee5 425
a4551119
TG
426 If the name is a canonical one for which we have a Darwin match
427 return the translation table - which contains defaults for flags,
428 type, attribute and default alignment data.
429
68ffbac6 430 Otherwise, expand the bfd_name (assumed to be in the form
a4551119
TG
431 "[LC_SEGMENT.]<segmentname>.<sectionname>") and return NULL. */
432
433static const mach_o_section_name_xlat *
154a1ee5 434bfd_mach_o_convert_section_name_to_mach_o (bfd *abfd ATTRIBUTE_UNUSED,
07d6d2b8
AM
435 asection *sect,
436 bfd_mach_o_section *section)
154a1ee5 437{
a4551119 438 const mach_o_section_name_xlat *xlat;
154a1ee5 439 const char *name = bfd_get_section_name (abfd, sect);
a4551119 440 const char *segname;
154a1ee5
TG
441 const char *dot;
442 unsigned int len;
443 unsigned int seglen;
444 unsigned int seclen;
445
a4551119
TG
446 memset (section->segname, 0, BFD_MACH_O_SEGNAME_SIZE + 1);
447 memset (section->sectname, 0, BFD_MACH_O_SECTNAME_SIZE + 1);
448
449 /* See if is a canonical name ... */
450 xlat = bfd_mach_o_section_data_for_bfd_name (abfd, name, &segname);
451 if (xlat)
452 {
453 strcpy (section->segname, segname);
454 strcpy (section->sectname, xlat->mach_o_name);
455 return xlat;
456 }
154a1ee5 457
a4551119
TG
458 /* .. else we convert our constructed one back to Mach-O.
459 Strip LC_SEGMENT. prefix, if present. */
154a1ee5
TG
460 if (strncmp (name, "LC_SEGMENT.", 11) == 0)
461 name += 11;
462
463 /* Find a dot. */
464 dot = strchr (name, '.');
465 len = strlen (name);
466
467 /* Try to split name into segment and section names. */
468 if (dot && dot != name)
469 {
470 seglen = dot - name;
471 seclen = len - (dot + 1 - name);
472
ca148c5a
TG
473 if (seglen <= BFD_MACH_O_SEGNAME_SIZE
474 && seclen <= BFD_MACH_O_SECTNAME_SIZE)
07d6d2b8
AM
475 {
476 memcpy (section->segname, name, seglen);
477 section->segname[seglen] = 0;
478 memcpy (section->sectname, dot + 1, seclen);
479 section->sectname[seclen] = 0;
480 return NULL;
481 }
154a1ee5
TG
482 }
483
a4551119
TG
484 /* The segment and section names are both missing - don't make them
485 into dots. */
486 if (dot && dot == name)
487 return NULL;
488
489 /* Just duplicate the name into both segment and section. */
154a1ee5
TG
490 if (len > 16)
491 len = 16;
492 memcpy (section->segname, name, len);
493 section->segname[len] = 0;
494 memcpy (section->sectname, name, len);
495 section->sectname[len] = 0;
a4551119 496 return NULL;
3af9a47b
NC
497}
498
b2b62060
TG
499/* Return the size of an entry for section SEC.
500 Must be called only for symbol pointer section and symbol stubs
501 sections. */
502
c5012cd8 503unsigned int
b2b62060
TG
504bfd_mach_o_section_get_entry_size (bfd *abfd, bfd_mach_o_section *sec)
505{
506 switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
507 {
508 case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS:
509 case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS:
510 return bfd_mach_o_wide_p (abfd) ? 8 : 4;
511 case BFD_MACH_O_S_SYMBOL_STUBS:
512 return sec->reserved2;
513 default:
514 BFD_FAIL ();
515 return 0;
516 }
517}
518
519/* Return the number of indirect symbols for a section.
520 Must be called only for symbol pointer section and symbol stubs
521 sections. */
522
c5012cd8 523unsigned int
b2b62060
TG
524bfd_mach_o_section_get_nbr_indirect (bfd *abfd, bfd_mach_o_section *sec)
525{
526 unsigned int elsz;
527
528 elsz = bfd_mach_o_section_get_entry_size (abfd, sec);
529 if (elsz == 0)
530 return 0;
531 else
532 return sec->size / elsz;
533}
534
c9ffd2ea
TG
535/* Append command CMD to ABFD. Note that header.ncmds is not updated. */
536
537static void
538bfd_mach_o_append_command (bfd *abfd, bfd_mach_o_load_command *cmd)
539{
540 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
541
542 if (mdata->last_command != NULL)
543 mdata->last_command->next = cmd;
544 else
545 mdata->first_command = cmd;
546 mdata->last_command = cmd;
547 cmd->next = NULL;
548}
b2b62060 549
3af9a47b
NC
550/* Copy any private info we understand from the input symbol
551 to the output symbol. */
552
154a1ee5 553bfd_boolean
116c20d2 554bfd_mach_o_bfd_copy_private_symbol_data (bfd *ibfd ATTRIBUTE_UNUSED,
b22161d6 555 asymbol *isymbol,
116c20d2 556 bfd *obfd ATTRIBUTE_UNUSED,
b22161d6
IS
557 asymbol *osymbol)
558{
559 bfd_mach_o_asymbol *os, *is;
c9ffd2ea 560
b22161d6
IS
561 os = (bfd_mach_o_asymbol *)osymbol;
562 is = (bfd_mach_o_asymbol *)isymbol;
563 os->n_type = is->n_type;
564 os->n_sect = is->n_sect;
565 os->n_desc = is->n_desc;
566 os->symbol.udata.i = is->symbol.udata.i;
c9ffd2ea 567
b34976b6 568 return TRUE;
3af9a47b
NC
569}
570
571/* Copy any private info we understand from the input section
572 to the output section. */
573
154a1ee5 574bfd_boolean
c9ffd2ea
TG
575bfd_mach_o_bfd_copy_private_section_data (bfd *ibfd, asection *isection,
576 bfd *obfd, asection *osection)
a4551119 577{
c9ffd2ea
TG
578 bfd_mach_o_section *os = bfd_mach_o_get_mach_o_section (osection);
579 bfd_mach_o_section *is = bfd_mach_o_get_mach_o_section (isection);
68ffbac6 580
c9ffd2ea
TG
581 if (ibfd->xvec->flavour != bfd_target_mach_o_flavour
582 || obfd->xvec->flavour != bfd_target_mach_o_flavour)
583 return TRUE;
584
585 BFD_ASSERT (is != NULL && os != NULL);
586
587 os->flags = is->flags;
588 os->reserved1 = is->reserved1;
589 os->reserved2 = is->reserved2;
590 os->reserved3 = is->reserved3;
a4551119 591
b34976b6 592 return TRUE;
3af9a47b
NC
593}
594
595/* Copy any private info we understand from the input bfd
596 to the output bfd. */
597
154a1ee5 598bfd_boolean
967b2c53 599bfd_mach_o_bfd_copy_private_header_data (bfd *ibfd, bfd *obfd)
3af9a47b 600{
c9ffd2ea
TG
601 bfd_mach_o_data_struct *imdata;
602 bfd_mach_o_data_struct *omdata;
603 bfd_mach_o_load_command *icmd;
604
154a1ee5
TG
605 if (bfd_get_flavour (ibfd) != bfd_target_mach_o_flavour
606 || bfd_get_flavour (obfd) != bfd_target_mach_o_flavour)
607 return TRUE;
608
3af9a47b
NC
609 BFD_ASSERT (bfd_mach_o_valid (ibfd));
610 BFD_ASSERT (bfd_mach_o_valid (obfd));
611
c9ffd2ea
TG
612 imdata = bfd_mach_o_get_data (ibfd);
613 omdata = bfd_mach_o_get_data (obfd);
614
615 /* Copy header flags. */
616 omdata->header.flags = imdata->header.flags;
617
618 /* Copy commands. */
619 for (icmd = imdata->first_command; icmd != NULL; icmd = icmd->next)
620 {
621 bfd_mach_o_load_command *ocmd;
622
623 switch (icmd->type)
624 {
625 case BFD_MACH_O_LC_LOAD_DYLIB:
626 case BFD_MACH_O_LC_LOAD_DYLINKER:
627 case BFD_MACH_O_LC_DYLD_INFO:
628 /* Command is copied. */
629 ocmd = bfd_alloc (obfd, sizeof (bfd_mach_o_load_command));
630 if (ocmd == NULL)
631 return FALSE;
632
633 /* Copy common fields. */
634 ocmd->type = icmd->type;
635 ocmd->type_required = icmd->type_required;
636 ocmd->offset = 0;
637 ocmd->len = icmd->len;
638 break;
639
640 default:
641 /* Command is not copied. */
642 continue;
643 break;
644 }
645
646 switch (icmd->type)
647 {
648 case BFD_MACH_O_LC_LOAD_DYLIB:
649 {
650 bfd_mach_o_dylib_command *idy = &icmd->command.dylib;
651 bfd_mach_o_dylib_command *ody = &ocmd->command.dylib;
652
653 ody->name_offset = idy->name_offset;
654 ody->timestamp = idy->timestamp;
655 ody->current_version = idy->current_version;
656 ody->compatibility_version = idy->compatibility_version;
657 ody->name_str = idy->name_str;
658 }
659 break;
660
661 case BFD_MACH_O_LC_LOAD_DYLINKER:
662 {
663 bfd_mach_o_dylinker_command *idy = &icmd->command.dylinker;
664 bfd_mach_o_dylinker_command *ody = &ocmd->command.dylinker;
665
666 ody->name_offset = idy->name_offset;
667 ody->name_str = idy->name_str;
668 }
669 break;
670
671 case BFD_MACH_O_LC_DYLD_INFO:
672 {
673 bfd_mach_o_dyld_info_command *idy = &icmd->command.dyld_info;
674 bfd_mach_o_dyld_info_command *ody = &ocmd->command.dyld_info;
675
676 if (bfd_mach_o_read_dyld_content (ibfd, idy))
677 {
678 ody->rebase_size = idy->rebase_size;
679 ody->rebase_content = idy->rebase_content;
680
681 ody->bind_size = idy->bind_size;
682 ody->bind_content = idy->bind_content;
683
684 ody->weak_bind_size = idy->weak_bind_size;
685 ody->weak_bind_content = idy->weak_bind_content;
686
687 ody->lazy_bind_size = idy->lazy_bind_size;
688 ody->lazy_bind_content = idy->lazy_bind_content;
689
690 ody->export_size = idy->export_size;
691 ody->export_content = idy->export_content;
692 }
86eafac0
NC
693 /* PR 17512L: file: 730e492d. */
694 else
695 {
1b786873
L
696 ody->rebase_size =
697 ody->bind_size =
698 ody->weak_bind_size =
699 ody->lazy_bind_size =
86eafac0 700 ody->export_size = 0;
1b786873
L
701 ody->rebase_content =
702 ody->bind_content =
703 ody->weak_bind_content =
704 ody->lazy_bind_content =
86eafac0
NC
705 ody->export_content = NULL;
706 }
c9ffd2ea
TG
707 }
708 break;
709
710 default:
711 /* That command should be handled. */
712 abort ();
713 }
714
715 /* Insert command. */
716 bfd_mach_o_append_command (obfd, ocmd);
717 }
154a1ee5 718
b34976b6 719 return TRUE;
3af9a47b
NC
720}
721
0c9ef0f0
TG
722/* This allows us to set up to 32 bits of flags (unless we invent some
723 fiendish scheme to subdivide). For now, we'll just set the file flags
724 without error checking - just overwrite. */
68ffbac6 725
0c9ef0f0
TG
726bfd_boolean
727bfd_mach_o_bfd_set_private_flags (bfd *abfd, flagword flags)
728{
729 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
730
731 if (!mdata)
732 return FALSE;
733
734 mdata->header.flags = flags;
735 return TRUE;
736}
737
046b007d 738/* Count the total number of symbols. */
154a1ee5 739
3af9a47b 740static long
116c20d2 741bfd_mach_o_count_symbols (bfd *abfd)
3af9a47b 742{
046b007d 743 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3af9a47b 744
046b007d
TG
745 if (mdata->symtab == NULL)
746 return 0;
747 return mdata->symtab->nsyms;
3af9a47b
NC
748}
749
154a1ee5 750long
116c20d2 751bfd_mach_o_get_symtab_upper_bound (bfd *abfd)
3af9a47b
NC
752{
753 long nsyms = bfd_mach_o_count_symbols (abfd);
754
3af9a47b
NC
755 return ((nsyms + 1) * sizeof (asymbol *));
756}
757
154a1ee5 758long
116c20d2 759bfd_mach_o_canonicalize_symtab (bfd *abfd, asymbol **alocation)
3af9a47b 760{
046b007d 761 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3af9a47b 762 long nsyms = bfd_mach_o_count_symbols (abfd);
046b007d
TG
763 bfd_mach_o_symtab_command *sym = mdata->symtab;
764 unsigned long j;
3af9a47b
NC
765
766 if (nsyms < 0)
767 return nsyms;
768
092d27ff
TG
769 if (nsyms == 0)
770 {
771 /* Do not try to read symbols if there are none. */
772 alocation[0] = NULL;
773 return 0;
774 }
775
afbb9e17 776 if (!bfd_mach_o_read_symtab_symbols (abfd))
3af9a47b 777 {
4eca0228 778 _bfd_error_handler
07d6d2b8 779 (_("bfd_mach_o_canonicalize_symtab: unable to load symbols"));
046b007d
TG
780 return 0;
781 }
3af9a47b 782
046b007d 783 BFD_ASSERT (sym->symbols != NULL);
3af9a47b 784
046b007d
TG
785 for (j = 0; j < sym->nsyms; j++)
786 alocation[j] = &sym->symbols[j].symbol;
3af9a47b 787
046b007d 788 alocation[j] = NULL;
a95a4550 789
3af9a47b
NC
790 return nsyms;
791}
792
aeefa1c9
TG
793/* Create synthetic symbols for indirect symbols. */
794
b2b62060
TG
795long
796bfd_mach_o_get_synthetic_symtab (bfd *abfd,
07d6d2b8
AM
797 long symcount ATTRIBUTE_UNUSED,
798 asymbol **syms ATTRIBUTE_UNUSED,
799 long dynsymcount ATTRIBUTE_UNUSED,
800 asymbol **dynsyms ATTRIBUTE_UNUSED,
801 asymbol **ret)
b2b62060
TG
802{
803 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
804 bfd_mach_o_dysymtab_command *dysymtab = mdata->dysymtab;
805 bfd_mach_o_symtab_command *symtab = mdata->symtab;
806 asymbol *s;
896ca098
NC
807 char * s_start;
808 char * s_end;
b2b62060
TG
809 unsigned long count, i, j, n;
810 size_t size;
811 char *names;
812 char *nul_name;
896ca098 813 const char stub [] = "$stub";
b2b62060
TG
814
815 *ret = NULL;
816
aeefa1c9 817 /* Stop now if no symbols or no indirect symbols. */
896ca098
NC
818 if (dysymtab == NULL || dysymtab->nindirectsyms == 0
819 || symtab == NULL || symtab->symbols == NULL)
b2b62060
TG
820 return 0;
821
aeefa1c9
TG
822 /* We need to allocate a bfd symbol for every indirect symbol and to
823 allocate the memory for its name. */
b2b62060
TG
824 count = dysymtab->nindirectsyms;
825 size = count * sizeof (asymbol) + 1;
826
827 for (j = 0; j < count; j++)
828 {
896ca098 829 const char * strng;
b2b62060 830 unsigned int isym = dysymtab->indirect_syms[j];
aeefa1c9
TG
831
832 /* Some indirect symbols are anonymous. */
896ca098
NC
833 if (isym < symtab->nsyms && (strng = symtab->symbols[isym].symbol.name))
834 /* PR 17512: file: f5b8eeba. */
835 size += strnlen (strng, symtab->strsize - (strng - symtab->strtab)) + sizeof (stub);
b2b62060
TG
836 }
837
896ca098
NC
838 s_start = bfd_malloc (size);
839 s = *ret = (asymbol *) s_start;
b2b62060
TG
840 if (s == NULL)
841 return -1;
842 names = (char *) (s + count);
843 nul_name = names;
844 *names++ = 0;
896ca098 845 s_end = s_start + size;
68ffbac6 846
b2b62060
TG
847 n = 0;
848 for (i = 0; i < mdata->nsects; i++)
849 {
850 bfd_mach_o_section *sec = mdata->sections[i];
91d6fa6a 851 unsigned int first, last;
b2b62060
TG
852 bfd_vma addr;
853 bfd_vma entry_size;
68ffbac6 854
b2b62060 855 switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
07d6d2b8
AM
856 {
857 case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS:
858 case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS:
859 case BFD_MACH_O_S_SYMBOL_STUBS:
860 /* Only these sections have indirect symbols. */
861 first = sec->reserved1;
862 last = first + bfd_mach_o_section_get_nbr_indirect (abfd, sec);
863 addr = sec->addr;
864 entry_size = bfd_mach_o_section_get_entry_size (abfd, sec);
896ca098
NC
865
866 /* PR 17512: file: 08e15eec. */
867 if (first >= count || last >= count || first > last)
868 goto fail;
869
07d6d2b8
AM
870 for (j = first; j < last; j++)
871 {
872 unsigned int isym = dysymtab->indirect_syms[j];
b2b62060 873
896ca098
NC
874 /* PR 17512: file: 04d64d9b. */
875 if (((char *) s) + sizeof (* s) > s_end)
876 goto fail;
877
07d6d2b8
AM
878 s->flags = BSF_GLOBAL | BSF_SYNTHETIC;
879 s->section = sec->bfdsection;
880 s->value = addr - sec->addr;
881 s->udata.p = NULL;
68ffbac6 882
07d6d2b8
AM
883 if (isym < symtab->nsyms
884 && symtab->symbols[isym].symbol.name)
885 {
886 const char *sym = symtab->symbols[isym].symbol.name;
887 size_t len;
b2b62060 888
07d6d2b8
AM
889 s->name = names;
890 len = strlen (sym);
896ca098
NC
891 /* PR 17512: file: 47dfd4d2. */
892 if (names + len >= s_end)
893 goto fail;
07d6d2b8
AM
894 memcpy (names, sym, len);
895 names += len;
896ca098
NC
896 /* PR 17512: file: 18f340a4. */
897 if (names + sizeof (stub) >= s_end)
898 goto fail;
07d6d2b8
AM
899 memcpy (names, stub, sizeof (stub));
900 names += sizeof (stub);
901 }
902 else
903 s->name = nul_name;
904
905 addr += entry_size;
906 s++;
907 n++;
908 }
909 break;
910 default:
911 break;
912 }
b2b62060
TG
913 }
914
915 return n;
896ca098
NC
916
917 fail:
918 free (s_start);
919 * ret = NULL;
920 return -1;
b2b62060
TG
921}
922
154a1ee5 923void
116c20d2
NC
924bfd_mach_o_get_symbol_info (bfd *abfd ATTRIBUTE_UNUSED,
925 asymbol *symbol,
926 symbol_info *ret)
3af9a47b
NC
927{
928 bfd_symbol_info (symbol, ret);
929}
930
154a1ee5 931void
116c20d2 932bfd_mach_o_print_symbol (bfd *abfd,
91d6fa6a 933 void * afile,
116c20d2
NC
934 asymbol *symbol,
935 bfd_print_symbol_type how)
3af9a47b
NC
936{
937 FILE *file = (FILE *) afile;
15e1c58a 938 const char *name;
92bc0e80 939 bfd_mach_o_asymbol *asym = (bfd_mach_o_asymbol *)symbol;
3af9a47b
NC
940
941 switch (how)
942 {
943 case bfd_print_symbol_name:
944 fprintf (file, "%s", symbol->name);
945 break;
946 default:
91d6fa6a 947 bfd_print_symbol_vandf (abfd, (void *) file, symbol);
92bc0e80
TG
948 if (asym->n_type & BFD_MACH_O_N_STAB)
949 name = bfd_get_stab_name (asym->n_type);
15e1c58a 950 else
92bc0e80 951 switch (asym->n_type & BFD_MACH_O_N_TYPE)
15e1c58a
TG
952 {
953 case BFD_MACH_O_N_UNDF:
07d6d2b8
AM
954 if (symbol->value == 0)
955 name = "UND";
956 else
957 name = "COM";
15e1c58a
TG
958 break;
959 case BFD_MACH_O_N_ABS:
960 name = "ABS";
961 break;
962 case BFD_MACH_O_N_INDR:
963 name = "INDR";
964 break;
965 case BFD_MACH_O_N_PBUD:
966 name = "PBUD";
967 break;
968 case BFD_MACH_O_N_SECT:
969 name = "SECT";
970 break;
971 default:
972 name = "???";
973 break;
974 }
975 if (name == NULL)
976 name = "";
92bc0e80 977 fprintf (file, " %02x %-6s %02x %04x",
07d6d2b8 978 asym->n_type, name, asym->n_sect, asym->n_desc);
92bc0e80
TG
979 if ((asym->n_type & BFD_MACH_O_N_STAB) == 0
980 && (asym->n_type & BFD_MACH_O_N_TYPE) == BFD_MACH_O_N_SECT)
e0ce1005 981 fprintf (file, " [%s]", symbol->section->name);
15e1c58a 982 fprintf (file, " %s", symbol->name);
3af9a47b
NC
983 }
984}
985
986static void
116c20d2 987bfd_mach_o_convert_architecture (bfd_mach_o_cpu_type mtype,
0b2de107 988 bfd_mach_o_cpu_subtype msubtype,
116c20d2
NC
989 enum bfd_architecture *type,
990 unsigned long *subtype)
3af9a47b
NC
991{
992 *subtype = bfd_arch_unknown;
993
994 switch (mtype)
995 {
0b2de107
TG
996 case BFD_MACH_O_CPU_TYPE_VAX:
997 *type = bfd_arch_vax;
998 break;
999 case BFD_MACH_O_CPU_TYPE_MC680x0:
1000 *type = bfd_arch_m68k;
1001 break;
1e8a024a
TG
1002 case BFD_MACH_O_CPU_TYPE_I386:
1003 *type = bfd_arch_i386;
1004 *subtype = bfd_mach_i386_i386;
1005 break;
1006 case BFD_MACH_O_CPU_TYPE_X86_64:
1007 *type = bfd_arch_i386;
1008 *subtype = bfd_mach_x86_64;
1009 break;
0b2de107
TG
1010 case BFD_MACH_O_CPU_TYPE_MIPS:
1011 *type = bfd_arch_mips;
1012 break;
1013 case BFD_MACH_O_CPU_TYPE_MC98000:
1014 *type = bfd_arch_m98k;
1015 break;
1016 case BFD_MACH_O_CPU_TYPE_HPPA:
1017 *type = bfd_arch_hppa;
1018 break;
1019 case BFD_MACH_O_CPU_TYPE_ARM:
1020 *type = bfd_arch_arm;
1021 switch (msubtype)
07d6d2b8
AM
1022 {
1023 case BFD_MACH_O_CPU_SUBTYPE_ARM_V4T:
1024 *subtype = bfd_mach_arm_4T;
1025 break;
1026 case BFD_MACH_O_CPU_SUBTYPE_ARM_V6:
1027 *subtype = bfd_mach_arm_4T; /* Best fit ? */
1028 break;
1029 case BFD_MACH_O_CPU_SUBTYPE_ARM_V5TEJ:
1030 *subtype = bfd_mach_arm_5TE;
1031 break;
1032 case BFD_MACH_O_CPU_SUBTYPE_ARM_XSCALE:
1033 *subtype = bfd_mach_arm_XScale;
1034 break;
1035 case BFD_MACH_O_CPU_SUBTYPE_ARM_V7:
1036 *subtype = bfd_mach_arm_5TE; /* Best fit ? */
1037 break;
1038 case BFD_MACH_O_CPU_SUBTYPE_ARM_ALL:
1039 default:
1040 break;
1041 }
0b2de107 1042 break;
1e8a024a
TG
1043 case BFD_MACH_O_CPU_TYPE_SPARC:
1044 *type = bfd_arch_sparc;
1045 *subtype = bfd_mach_sparc;
1046 break;
0b2de107
TG
1047 case BFD_MACH_O_CPU_TYPE_ALPHA:
1048 *type = bfd_arch_alpha;
1049 break;
1e8a024a
TG
1050 case BFD_MACH_O_CPU_TYPE_POWERPC:
1051 *type = bfd_arch_powerpc;
c2f09c75 1052 *subtype = bfd_mach_ppc;
1e8a024a
TG
1053 break;
1054 case BFD_MACH_O_CPU_TYPE_POWERPC_64:
1055 *type = bfd_arch_powerpc;
c2f09c75 1056 *subtype = bfd_mach_ppc64;
1e8a024a 1057 break;
d8028530
TG
1058 case BFD_MACH_O_CPU_TYPE_ARM64:
1059 *type = bfd_arch_aarch64;
1060 *subtype = bfd_mach_aarch64;
1061 break;
3af9a47b 1062 default:
1e8a024a
TG
1063 *type = bfd_arch_unknown;
1064 break;
3af9a47b
NC
1065 }
1066}
a95a4550 1067
c9ffd2ea
TG
1068/* Write n NUL bytes to ABFD so that LEN + n is a multiple of 4. Return the
1069 number of bytes written or -1 in case of error. */
1070
1071static int
1072bfd_mach_o_pad4 (bfd *abfd, unsigned int len)
1073{
1074 if (len % 4 != 0)
1075 {
1076 char pad[4] = {0,0,0,0};
1077 unsigned int padlen = 4 - (len % 4);
1078
1079 if (bfd_bwrite (pad, padlen, abfd) != padlen)
1080 return -1;
1081
1082 return padlen;
1083 }
1084 else
1085 return 0;
1086}
1087
1088/* Likewise, but for a command. */
1089
1090static int
1091bfd_mach_o_pad_command (bfd *abfd, unsigned int len)
1092{
1093 unsigned int align = bfd_mach_o_wide_p (abfd) ? 8 : 4;
1094
1095 if (len % align != 0)
1096 {
1097 char pad[8] = {0};
1098 unsigned int padlen = align - (len % align);
1099
1100 if (bfd_bwrite (pad, padlen, abfd) != padlen)
1101 return -1;
1102
1103 return padlen;
1104 }
1105 else
1106 return 0;
1107}
1108
154a1ee5 1109static bfd_boolean
116c20d2
NC
1110bfd_mach_o_write_header (bfd *abfd, bfd_mach_o_header *header)
1111{
46d1c23b 1112 struct mach_o_header_external raw;
1e8a024a
TG
1113 unsigned int size;
1114
c2f09c75 1115 size = mach_o_wide_p (header) ?
154a1ee5 1116 BFD_MACH_O_HEADER_64_SIZE : BFD_MACH_O_HEADER_SIZE;
116c20d2 1117
46d1c23b
TG
1118 bfd_h_put_32 (abfd, header->magic, raw.magic);
1119 bfd_h_put_32 (abfd, header->cputype, raw.cputype);
1120 bfd_h_put_32 (abfd, header->cpusubtype, raw.cpusubtype);
1121 bfd_h_put_32 (abfd, header->filetype, raw.filetype);
1122 bfd_h_put_32 (abfd, header->ncmds, raw.ncmds);
1123 bfd_h_put_32 (abfd, header->sizeofcmds, raw.sizeofcmds);
1124 bfd_h_put_32 (abfd, header->flags, raw.flags);
116c20d2 1125
c2f09c75 1126 if (mach_o_wide_p (header))
46d1c23b 1127 bfd_h_put_32 (abfd, header->reserved, raw.reserved);
1e8a024a 1128
c2f09c75 1129 if (bfd_seek (abfd, 0, SEEK_SET) != 0
46d1c23b 1130 || bfd_bwrite (&raw, size, abfd) != size)
154a1ee5 1131 return FALSE;
116c20d2 1132
154a1ee5 1133 return TRUE;
116c20d2
NC
1134}
1135
452216ab 1136static bfd_boolean
ab273af8 1137bfd_mach_o_write_thread (bfd *abfd, bfd_mach_o_load_command *command)
116c20d2
NC
1138{
1139 bfd_mach_o_thread_command *cmd = &command->command.thread;
1140 unsigned int i;
46d1c23b 1141 struct mach_o_thread_command_external raw;
92bc0e80 1142 unsigned int offset;
116c20d2
NC
1143
1144 BFD_ASSERT ((command->type == BFD_MACH_O_LC_THREAD)
1145 || (command->type == BFD_MACH_O_LC_UNIXTHREAD));
1146
c9ffd2ea 1147 offset = BFD_MACH_O_LC_SIZE;
116c20d2
NC
1148 for (i = 0; i < cmd->nflavours; i++)
1149 {
1150 BFD_ASSERT ((cmd->flavours[i].size % 4) == 0);
46d1c23b 1151 BFD_ASSERT (cmd->flavours[i].offset ==
07d6d2b8 1152 (command->offset + offset + BFD_MACH_O_LC_SIZE));
116c20d2 1153
46d1c23b
TG
1154 bfd_h_put_32 (abfd, cmd->flavours[i].flavour, raw.flavour);
1155 bfd_h_put_32 (abfd, (cmd->flavours[i].size / 4), raw.count);
116c20d2 1156
c2f09c75 1157 if (bfd_seek (abfd, command->offset + offset, SEEK_SET) != 0
07d6d2b8 1158 || bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
452216ab 1159 return FALSE;
116c20d2 1160
46d1c23b 1161 offset += cmd->flavours[i].size + sizeof (raw);
116c20d2
NC
1162 }
1163
452216ab 1164 return TRUE;
116c20d2
NC
1165}
1166
c9ffd2ea
TG
1167static bfd_boolean
1168bfd_mach_o_write_dylinker (bfd *abfd, bfd_mach_o_load_command *command)
1169{
1170 bfd_mach_o_dylinker_command *cmd = &command->command.dylinker;
1171 struct mach_o_str_command_external raw;
1172 unsigned int namelen;
1173
1174 bfd_h_put_32 (abfd, cmd->name_offset, raw.str);
1175
1176 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
1177 || bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
1178 return FALSE;
1179
1180 namelen = strlen (cmd->name_str) + 1;
1181 if (bfd_bwrite (cmd->name_str, namelen, abfd) != namelen)
1182 return FALSE;
1183
1184 if (bfd_mach_o_pad_command (abfd, namelen) < 0)
1185 return FALSE;
1186
1187 return TRUE;
1188}
1189
1190static bfd_boolean
1191bfd_mach_o_write_dylib (bfd *abfd, bfd_mach_o_load_command *command)
1192{
1193 bfd_mach_o_dylib_command *cmd = &command->command.dylib;
1194 struct mach_o_dylib_command_external raw;
1195 unsigned int namelen;
1196
1197 bfd_h_put_32 (abfd, cmd->name_offset, raw.name);
1198 bfd_h_put_32 (abfd, cmd->timestamp, raw.timestamp);
1199 bfd_h_put_32 (abfd, cmd->current_version, raw.current_version);
1200 bfd_h_put_32 (abfd, cmd->compatibility_version, raw.compatibility_version);
1201
1202 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
1203 || bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
1204 return FALSE;
1205
1206 namelen = strlen (cmd->name_str) + 1;
1207 if (bfd_bwrite (cmd->name_str, namelen, abfd) != namelen)
1208 return FALSE;
1209
1210 if (bfd_mach_o_pad_command (abfd, namelen) < 0)
1211 return FALSE;
1212
1213 return TRUE;
1214}
1215
1216static bfd_boolean
1217bfd_mach_o_write_main (bfd *abfd, bfd_mach_o_load_command *command)
1218{
1219 bfd_mach_o_main_command *cmd = &command->command.main;
1220 struct mach_o_entry_point_command_external raw;
1221
1222 bfd_h_put_64 (abfd, cmd->entryoff, raw.entryoff);
1223 bfd_h_put_64 (abfd, cmd->stacksize, raw.stacksize);
1224
1225 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
1226 || bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
1227 return FALSE;
1228
1229 return TRUE;
1230}
1231
1232static bfd_boolean
1233bfd_mach_o_write_dyld_info (bfd *abfd, bfd_mach_o_load_command *command)
1234{
1235 bfd_mach_o_dyld_info_command *cmd = &command->command.dyld_info;
1236 struct mach_o_dyld_info_command_external raw;
1237
1238 bfd_h_put_32 (abfd, cmd->rebase_off, raw.rebase_off);
1239 bfd_h_put_32 (abfd, cmd->rebase_size, raw.rebase_size);
1240 bfd_h_put_32 (abfd, cmd->bind_off, raw.bind_off);
1241 bfd_h_put_32 (abfd, cmd->bind_size, raw.bind_size);
1242 bfd_h_put_32 (abfd, cmd->weak_bind_off, raw.weak_bind_off);
1243 bfd_h_put_32 (abfd, cmd->weak_bind_size, raw.weak_bind_size);
1244 bfd_h_put_32 (abfd, cmd->lazy_bind_off, raw.lazy_bind_off);
1245 bfd_h_put_32 (abfd, cmd->lazy_bind_size, raw.lazy_bind_size);
1246 bfd_h_put_32 (abfd, cmd->export_off, raw.export_off);
1247 bfd_h_put_32 (abfd, cmd->export_size, raw.export_size);
1248
1249 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
1250 || bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
1251 return FALSE;
1252
1253 if (cmd->rebase_size != 0)
1254 if (bfd_seek (abfd, cmd->rebase_off, SEEK_SET) != 0
1255 || (bfd_bwrite (cmd->rebase_content, cmd->rebase_size, abfd) !=
1256 cmd->rebase_size))
1257 return FALSE;
1258
1259 if (cmd->bind_size != 0)
1260 if (bfd_seek (abfd, cmd->bind_off, SEEK_SET) != 0
1261 || (bfd_bwrite (cmd->bind_content, cmd->bind_size, abfd) !=
1262 cmd->bind_size))
1263 return FALSE;
1264
1265 if (cmd->weak_bind_size != 0)
1266 if (bfd_seek (abfd, cmd->weak_bind_off, SEEK_SET) != 0
1267 || (bfd_bwrite (cmd->weak_bind_content, cmd->weak_bind_size, abfd) !=
1268 cmd->weak_bind_size))
1269 return FALSE;
1270
1271 if (cmd->lazy_bind_size != 0)
1272 if (bfd_seek (abfd, cmd->lazy_bind_off, SEEK_SET) != 0
1273 || (bfd_bwrite (cmd->lazy_bind_content, cmd->lazy_bind_size, abfd) !=
1274 cmd->lazy_bind_size))
1275 return FALSE;
1276
1277 if (cmd->export_size != 0)
1278 if (bfd_seek (abfd, cmd->export_off, SEEK_SET) != 0
1279 || (bfd_bwrite (cmd->export_content, cmd->export_size, abfd) !=
1280 cmd->export_size))
1281 return FALSE;
1282
1283 return TRUE;
1284}
1285
92bc0e80
TG
1286long
1287bfd_mach_o_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED,
07d6d2b8 1288 asection *asect)
92bc0e80
TG
1289{
1290 return (asect->reloc_count + 1) * sizeof (arelent *);
1291}
1292
19765f52
IS
1293/* In addition to the need to byte-swap the symbol number, the bit positions
1294 of the fields in the relocation information vary per target endian-ness. */
1295
bcb51645 1296void
19765f52
IS
1297bfd_mach_o_swap_in_non_scattered_reloc (bfd *abfd, bfd_mach_o_reloc_info *rel,
1298 unsigned char *fields)
1299{
1300 unsigned char info = fields[3];
1301
1302 if (bfd_big_endian (abfd))
1303 {
1304 rel->r_value = (fields[0] << 16) | (fields[1] << 8) | fields[2];
1305 rel->r_type = (info >> BFD_MACH_O_BE_TYPE_SHIFT) & BFD_MACH_O_TYPE_MASK;
1306 rel->r_pcrel = (info & BFD_MACH_O_BE_PCREL) ? 1 : 0;
68ffbac6 1307 rel->r_length = (info >> BFD_MACH_O_BE_LENGTH_SHIFT)
19765f52
IS
1308 & BFD_MACH_O_LENGTH_MASK;
1309 rel->r_extern = (info & BFD_MACH_O_BE_EXTERN) ? 1 : 0;
1310 }
1311 else
1312 {
1313 rel->r_value = (fields[2] << 16) | (fields[1] << 8) | fields[0];
1314 rel->r_type = (info >> BFD_MACH_O_LE_TYPE_SHIFT) & BFD_MACH_O_TYPE_MASK;
1315 rel->r_pcrel = (info & BFD_MACH_O_LE_PCREL) ? 1 : 0;
68ffbac6 1316 rel->r_length = (info >> BFD_MACH_O_LE_LENGTH_SHIFT)
19765f52
IS
1317 & BFD_MACH_O_LENGTH_MASK;
1318 rel->r_extern = (info & BFD_MACH_O_LE_EXTERN) ? 1 : 0;
1319 }
1320}
1321
bcb51645
TG
1322/* Set syms_ptr_ptr and addend of RES. */
1323
1324bfd_boolean
1325bfd_mach_o_canonicalize_non_scattered_reloc (bfd *abfd,
1326 bfd_mach_o_reloc_info *reloc,
1327 arelent *res, asymbol **syms)
92bc0e80 1328{
046b007d 1329 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
bcb51645 1330 unsigned int num;
b32e07d7
TG
1331 asymbol **sym;
1332
bcb51645
TG
1333 /* Non-scattered relocation. */
1334 reloc->r_scattered = 0;
1335 res->addend = 0;
1336
1337 num = reloc->r_value;
1338
1339 if (reloc->r_extern)
1340 {
1341 /* PR 17512: file: 8396-1185-0.004. */
1342 if (num >= (unsigned) bfd_mach_o_count_symbols (abfd))
1343 sym = bfd_und_section_ptr->symbol_ptr_ptr;
1344 else if (syms == NULL)
1345 sym = bfd_und_section_ptr->symbol_ptr_ptr;
1346 else
1347 /* An external symbol number. */
1348 sym = syms + num;
1349 }
1350 else if (num == 0x00ffffff || num == 0)
1351 {
1352 /* The 'symnum' in a non-scattered PAIR is 0x00ffffff. But as this
1353 is generic code, we don't know wether this is really a PAIR.
1354 This value is almost certainly not a valid section number, hence
1355 this specific case to avoid an assertion failure.
1356 Target specific swap_reloc_in routine should adjust that. */
1357 sym = bfd_abs_section_ptr->symbol_ptr_ptr;
1358 }
1359 else
1360 {
1361 /* PR 17512: file: 006-2964-0.004. */
1362 if (num > mdata->nsects)
1363 return FALSE;
1364
1365 /* A section number. */
1366 sym = mdata->sections[num - 1]->bfdsection->symbol_ptr_ptr;
1367 /* For a symbol defined in section S, the addend (stored in the
1368 binary) contains the address of the section. To comply with
1369 bfd convention, subtract the section address.
1370 Use the address from the header, so that the user can modify
07d6d2b8 1371 the vma of the section. */
bcb51645
TG
1372 res->addend = -mdata->sections[num - 1]->addr;
1373 }
1374
1375 /* Note: Pairs for PPC LO/HI/HA are not scattered, but contain the offset
1376 in the lower 16bits of the address value. So we have to find the
1377 'symbol' from the preceding reloc. We do this even though the
1378 section symbol is probably not needed here, because NULL symbol
1379 values cause an assert in generic BFD code. This must be done in
1380 the PPC swap_reloc_in routine. */
1381 res->sym_ptr_ptr = sym;
1382
1383 return TRUE;
1384}
1385
1386/* Do most of the work for canonicalize_relocs on RAW: create internal
1387 representation RELOC and set most fields of RES using symbol table SYMS.
1388 Each target still has to set the howto of RES and possibly adjust other
1389 fields.
1390 Previously the Mach-O hook point was simply swap_in, but some targets
1391 (like arm64) don't follow the generic rules (symnum is a value for the
1392 non-scattered relocation ADDEND). */
1393
1394bfd_boolean
1395bfd_mach_o_pre_canonicalize_one_reloc (bfd *abfd,
1396 struct mach_o_reloc_info_external *raw,
1397 bfd_mach_o_reloc_info *reloc,
1398 arelent *res, asymbol **syms)
1399{
1400 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1401 bfd_vma addr;
1402
46d1c23b 1403 addr = bfd_get_32 (abfd, raw->r_address);
19765f52
IS
1404 res->sym_ptr_ptr = NULL;
1405 res->addend = 0;
f4716ee2 1406
b32e07d7
TG
1407 if (addr & BFD_MACH_O_SR_SCATTERED)
1408 {
1409 unsigned int j;
19765f52 1410 bfd_vma symnum = bfd_get_32 (abfd, raw->r_symbolnum);
b32e07d7 1411
19765f52 1412 /* Scattered relocation, can't be extern. */
bcb51645
TG
1413 reloc->r_scattered = 1;
1414 reloc->r_extern = 0;
19765f52
IS
1415
1416 /* Extract section and offset from r_value (symnum). */
bcb51645 1417 reloc->r_value = symnum;
19765f52
IS
1418 /* FIXME: This breaks when a symbol in a reloc exactly follows the
1419 end of the data for the section (e.g. in a calculation of section
1420 data length). At present, the symbol will end up associated with
1421 the following section or, if it falls within alignment padding, as
1422 null - which will assert later. */
b32e07d7 1423 for (j = 0; j < mdata->nsects; j++)
07d6d2b8
AM
1424 {
1425 bfd_mach_o_section *sect = mdata->sections[j];
1426 if (symnum >= sect->addr && symnum < sect->addr + sect->size)
1427 {
1428 res->sym_ptr_ptr = sect->bfdsection->symbol_ptr_ptr;
1429 res->addend = symnum - sect->addr;
1430 break;
1431 }
1432 }
19765f52
IS
1433
1434 /* Extract the info and address fields from r_address. */
bcb51645
TG
1435 reloc->r_type = BFD_MACH_O_GET_SR_TYPE (addr);
1436 reloc->r_length = BFD_MACH_O_GET_SR_LENGTH (addr);
1437 reloc->r_pcrel = addr & BFD_MACH_O_SR_PCREL;
1438 reloc->r_address = BFD_MACH_O_GET_SR_TYPE (addr);
19765f52 1439 res->address = BFD_MACH_O_GET_SR_ADDRESS (addr);
b32e07d7
TG
1440 }
1441 else
1442 {
19765f52 1443 /* Non-scattered relocation. */
bcb51645
TG
1444 reloc->r_scattered = 0;
1445 reloc->r_address = addr;
1446 res->address = addr;
f4716ee2 1447
19765f52 1448 /* The value and info fields have to be extracted dependent on target
07d6d2b8 1449 endian-ness. */
bcb51645 1450 bfd_mach_o_swap_in_non_scattered_reloc (abfd, reloc, raw->r_symbolnum);
19765f52 1451
bcb51645
TG
1452 if (!bfd_mach_o_canonicalize_non_scattered_reloc (abfd, reloc,
1453 res, syms))
1454 return FALSE;
b32e07d7 1455 }
f4716ee2
TG
1456
1457 /* We have set up a reloc with all the information present, so the swapper
1458 can modify address, value and addend fields, if necessary, to convey
1459 information in the generic BFD reloc that is mach-o specific. */
19765f52 1460
bcb51645 1461 return TRUE;
b32e07d7
TG
1462}
1463
1464static int
1465bfd_mach_o_canonicalize_relocs (bfd *abfd, unsigned long filepos,
07d6d2b8
AM
1466 unsigned long count,
1467 arelent *res, asymbol **syms)
b32e07d7 1468{
bcb51645 1469 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
92bc0e80 1470 unsigned long i;
46d1c23b 1471 struct mach_o_reloc_info_external *native_relocs;
92bc0e80
TG
1472 bfd_size_type native_size;
1473
92bc0e80 1474 /* Allocate and read relocs. */
b32e07d7 1475 native_size = count * BFD_MACH_O_RELENT_SIZE;
033539e2 1476
64d29018
NC
1477 /* PR 17512: file: 09477b57. */
1478 if (native_size < count)
1479 return -1;
1480
46d1c23b
TG
1481 native_relocs =
1482 (struct mach_o_reloc_info_external *) bfd_malloc (native_size);
92bc0e80
TG
1483 if (native_relocs == NULL)
1484 return -1;
1485
b32e07d7 1486 if (bfd_seek (abfd, filepos, SEEK_SET) != 0
92bc0e80 1487 || bfd_bread (native_relocs, native_size, abfd) != native_size)
b32e07d7
TG
1488 goto err;
1489
1490 for (i = 0; i < count; i++)
92bc0e80 1491 {
bcb51645 1492 if (!(*bed->_bfd_mach_o_canonicalize_one_reloc)(abfd, &native_relocs[i],
ca4cf9b9 1493 &res[i], syms, res))
07d6d2b8 1494 goto err;
92bc0e80 1495 }
b32e07d7
TG
1496 free (native_relocs);
1497 return i;
1498 err:
1499 free (native_relocs);
1500 return -1;
1501}
1502
1503long
1504bfd_mach_o_canonicalize_reloc (bfd *abfd, asection *asect,
07d6d2b8 1505 arelent **rels, asymbol **syms)
b32e07d7
TG
1506{
1507 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
1508 unsigned long i;
1509 arelent *res;
1510
1511 if (asect->reloc_count == 0)
1512 return 0;
1513
1514 /* No need to go further if we don't know how to read relocs. */
bcb51645 1515 if (bed->_bfd_mach_o_canonicalize_one_reloc == NULL)
b32e07d7 1516 return 0;
92bc0e80 1517
dff55db0 1518 if (asect->relocation == NULL)
92bc0e80 1519 {
64d29018
NC
1520 if (asect->reloc_count * sizeof (arelent) < asect->reloc_count)
1521 return -1;
dff55db0
TG
1522 res = bfd_malloc (asect->reloc_count * sizeof (arelent));
1523 if (res == NULL)
07d6d2b8 1524 return -1;
dff55db0
TG
1525
1526 if (bfd_mach_o_canonicalize_relocs (abfd, asect->rel_filepos,
07d6d2b8
AM
1527 asect->reloc_count, res, syms) < 0)
1528 {
1529 free (res);
1530 return -1;
1531 }
dff55db0 1532 asect->relocation = res;
92bc0e80
TG
1533 }
1534
dff55db0 1535 res = asect->relocation;
92bc0e80 1536 for (i = 0; i < asect->reloc_count; i++)
b32e07d7
TG
1537 rels[i] = &res[i];
1538 rels[i] = NULL;
92bc0e80 1539
b32e07d7
TG
1540 return i;
1541}
92bc0e80 1542
b32e07d7
TG
1543long
1544bfd_mach_o_get_dynamic_reloc_upper_bound (bfd *abfd)
1545{
1546 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
92bc0e80 1547
b32e07d7
TG
1548 if (mdata->dysymtab == NULL)
1549 return 1;
dff55db0 1550 return (mdata->dysymtab->nextrel + mdata->dysymtab->nlocrel + 1)
b32e07d7
TG
1551 * sizeof (arelent *);
1552}
92bc0e80 1553
b32e07d7
TG
1554long
1555bfd_mach_o_canonicalize_dynamic_reloc (bfd *abfd, arelent **rels,
07d6d2b8 1556 struct bfd_symbol **syms)
b32e07d7
TG
1557{
1558 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1559 bfd_mach_o_dysymtab_command *dysymtab = mdata->dysymtab;
1560 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
1561 unsigned long i;
1562 arelent *res;
1563
1564 if (dysymtab == NULL)
1565 return 0;
1566 if (dysymtab->nextrel == 0 && dysymtab->nlocrel == 0)
1567 return 0;
1568
1569 /* No need to go further if we don't know how to read relocs. */
bcb51645 1570 if (bed->_bfd_mach_o_canonicalize_one_reloc == NULL)
b32e07d7
TG
1571 return 0;
1572
dff55db0 1573 if (mdata->dyn_reloc_cache == NULL)
b32e07d7 1574 {
64d29018
NC
1575 if ((dysymtab->nextrel + dysymtab->nlocrel) * sizeof (arelent)
1576 < (dysymtab->nextrel + dysymtab->nlocrel))
1577 return -1;
1578
dff55db0 1579 res = bfd_malloc ((dysymtab->nextrel + dysymtab->nlocrel)
07d6d2b8 1580 * sizeof (arelent));
dff55db0 1581 if (res == NULL)
07d6d2b8 1582 return -1;
b32e07d7 1583
dff55db0 1584 if (bfd_mach_o_canonicalize_relocs (abfd, dysymtab->extreloff,
07d6d2b8
AM
1585 dysymtab->nextrel, res, syms) < 0)
1586 {
1587 free (res);
1588 return -1;
1589 }
dff55db0
TG
1590
1591 if (bfd_mach_o_canonicalize_relocs (abfd, dysymtab->locreloff,
07d6d2b8
AM
1592 dysymtab->nlocrel,
1593 res + dysymtab->nextrel, syms) < 0)
1594 {
1595 free (res);
1596 return -1;
1597 }
dff55db0
TG
1598
1599 mdata->dyn_reloc_cache = res;
b32e07d7
TG
1600 }
1601
dff55db0 1602 res = mdata->dyn_reloc_cache;
b32e07d7
TG
1603 for (i = 0; i < dysymtab->nextrel + dysymtab->nlocrel; i++)
1604 rels[i] = &res[i];
1605 rels[i] = NULL;
92bc0e80
TG
1606 return i;
1607}
1608
19765f52
IS
1609/* In addition to the need to byte-swap the symbol number, the bit positions
1610 of the fields in the relocation information vary per target endian-ness. */
1611
1612static void
1613bfd_mach_o_swap_out_non_scattered_reloc (bfd *abfd, unsigned char *fields,
1614 bfd_mach_o_reloc_info *rel)
1615{
1616 unsigned char info = 0;
1617
1618 BFD_ASSERT (rel->r_type <= 15);
1619 BFD_ASSERT (rel->r_length <= 3);
1620
1621 if (bfd_big_endian (abfd))
1622 {
1623 fields[0] = (rel->r_value >> 16) & 0xff;
1624 fields[1] = (rel->r_value >> 8) & 0xff;
1625 fields[2] = rel->r_value & 0xff;
1626 info |= rel->r_type << BFD_MACH_O_BE_TYPE_SHIFT;
1627 info |= rel->r_pcrel ? BFD_MACH_O_BE_PCREL : 0;
1628 info |= rel->r_length << BFD_MACH_O_BE_LENGTH_SHIFT;
1629 info |= rel->r_extern ? BFD_MACH_O_BE_EXTERN : 0;
1630 }
1631 else
1632 {
1633 fields[2] = (rel->r_value >> 16) & 0xff;
1634 fields[1] = (rel->r_value >> 8) & 0xff;
1635 fields[0] = rel->r_value & 0xff;
1636 info |= rel->r_type << BFD_MACH_O_LE_TYPE_SHIFT;
1637 info |= rel->r_pcrel ? BFD_MACH_O_LE_PCREL : 0;
1638 info |= rel->r_length << BFD_MACH_O_LE_LENGTH_SHIFT;
1639 info |= rel->r_extern ? BFD_MACH_O_LE_EXTERN : 0;
1640 }
1641 fields[3] = info;
1642}
1643
92bc0e80 1644static bfd_boolean
ab273af8 1645bfd_mach_o_write_relocs (bfd *abfd, bfd_mach_o_section *section)
92bc0e80 1646{
92bc0e80
TG
1647 unsigned int i;
1648 arelent **entries;
1649 asection *sec;
1650 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
1651
1652 sec = section->bfdsection;
1653 if (sec->reloc_count == 0)
1654 return TRUE;
1655
1656 if (bed->_bfd_mach_o_swap_reloc_out == NULL)
1657 return TRUE;
1658
92bc0e80
TG
1659 if (bfd_seek (abfd, section->reloff, SEEK_SET) != 0)
1660 return FALSE;
1661
1662 /* Convert and write. */
1663 entries = section->bfdsection->orelocation;
1664 for (i = 0; i < section->nreloc; i++)
1665 {
1666 arelent *rel = entries[i];
46d1c23b 1667 struct mach_o_reloc_info_external raw;
92bc0e80
TG
1668 bfd_mach_o_reloc_info info, *pinfo = &info;
1669
1670 /* Convert relocation to an intermediate representation. */
1671 if (!(*bed->_bfd_mach_o_swap_reloc_out) (rel, pinfo))
07d6d2b8 1672 return FALSE;
92bc0e80
TG
1673
1674 /* Lower the relocation info. */
1675 if (pinfo->r_scattered)
07d6d2b8
AM
1676 {
1677 unsigned long v;
1678
1679 v = BFD_MACH_O_SR_SCATTERED
1680 | (pinfo->r_pcrel ? BFD_MACH_O_SR_PCREL : 0)
1681 | BFD_MACH_O_SET_SR_LENGTH (pinfo->r_length)
1682 | BFD_MACH_O_SET_SR_TYPE (pinfo->r_type)
1683 | BFD_MACH_O_SET_SR_ADDRESS (pinfo->r_address);
1684 /* Note: scattered relocs have field in reverse order... */
1685 bfd_put_32 (abfd, v, raw.r_address);
1686 bfd_put_32 (abfd, pinfo->r_value, raw.r_symbolnum);
1687 }
92bc0e80 1688 else
07d6d2b8
AM
1689 {
1690 bfd_put_32 (abfd, pinfo->r_address, raw.r_address);
1691 bfd_mach_o_swap_out_non_scattered_reloc (abfd, raw.r_symbolnum,
19765f52 1692 pinfo);
07d6d2b8 1693 }
92bc0e80 1694
46d1c23b 1695 if (bfd_bwrite (&raw, BFD_MACH_O_RELENT_SIZE, abfd)
07d6d2b8
AM
1696 != BFD_MACH_O_RELENT_SIZE)
1697 return FALSE;
92bc0e80
TG
1698 }
1699 return TRUE;
1700}
1701
452216ab 1702static bfd_boolean
ab273af8 1703bfd_mach_o_write_section_32 (bfd *abfd, bfd_mach_o_section *section)
116c20d2 1704{
46d1c23b
TG
1705 struct mach_o_section_32_external raw;
1706
1707 memcpy (raw.sectname, section->sectname, 16);
72b5104c 1708 memcpy (raw.segname, section->segname, 16);
46d1c23b
TG
1709 bfd_h_put_32 (abfd, section->addr, raw.addr);
1710 bfd_h_put_32 (abfd, section->size, raw.size);
1711 bfd_h_put_32 (abfd, section->offset, raw.offset);
1712 bfd_h_put_32 (abfd, section->align, raw.align);
1713 bfd_h_put_32 (abfd, section->reloff, raw.reloff);
1714 bfd_h_put_32 (abfd, section->nreloc, raw.nreloc);
1715 bfd_h_put_32 (abfd, section->flags, raw.flags);
1716 bfd_h_put_32 (abfd, section->reserved1, raw.reserved1);
1717 bfd_h_put_32 (abfd, section->reserved2, raw.reserved2);
1718
1719 if (bfd_bwrite (&raw, BFD_MACH_O_SECTION_SIZE, abfd)
92bc0e80 1720 != BFD_MACH_O_SECTION_SIZE)
452216ab 1721 return FALSE;
116c20d2 1722
452216ab 1723 return TRUE;
116c20d2
NC
1724}
1725
452216ab 1726static bfd_boolean
ab273af8 1727bfd_mach_o_write_section_64 (bfd *abfd, bfd_mach_o_section *section)
116c20d2 1728{
46d1c23b
TG
1729 struct mach_o_section_64_external raw;
1730
1731 memcpy (raw.sectname, section->sectname, 16);
1732 memcpy (raw.segname, section->segname, 16);
1733 bfd_h_put_64 (abfd, section->addr, raw.addr);
1734 bfd_h_put_64 (abfd, section->size, raw.size);
1735 bfd_h_put_32 (abfd, section->offset, raw.offset);
1736 bfd_h_put_32 (abfd, section->align, raw.align);
1737 bfd_h_put_32 (abfd, section->reloff, raw.reloff);
1738 bfd_h_put_32 (abfd, section->nreloc, raw.nreloc);
1739 bfd_h_put_32 (abfd, section->flags, raw.flags);
1740 bfd_h_put_32 (abfd, section->reserved1, raw.reserved1);
1741 bfd_h_put_32 (abfd, section->reserved2, raw.reserved2);
1742 bfd_h_put_32 (abfd, section->reserved3, raw.reserved3);
1743
1744 if (bfd_bwrite (&raw, BFD_MACH_O_SECTION_64_SIZE, abfd)
92bc0e80 1745 != BFD_MACH_O_SECTION_64_SIZE)
452216ab 1746 return FALSE;
116c20d2 1747
452216ab 1748 return TRUE;
1e8a024a
TG
1749}
1750
452216ab 1751static bfd_boolean
ab273af8 1752bfd_mach_o_write_segment_32 (bfd *abfd, bfd_mach_o_load_command *command)
1e8a024a 1753{
46d1c23b 1754 struct mach_o_segment_command_32_external raw;
1e8a024a 1755 bfd_mach_o_segment_command *seg = &command->command.segment;
f1bde64c 1756 bfd_mach_o_section *sec;
1e8a024a 1757
c2f09c75
TG
1758 BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT);
1759
f1bde64c
TG
1760 for (sec = seg->sect_head; sec != NULL; sec = sec->next)
1761 if (!bfd_mach_o_write_relocs (abfd, sec))
452216ab 1762 return FALSE;
c2f09c75 1763
46d1c23b
TG
1764 memcpy (raw.segname, seg->segname, 16);
1765 bfd_h_put_32 (abfd, seg->vmaddr, raw.vmaddr);
1766 bfd_h_put_32 (abfd, seg->vmsize, raw.vmsize);
1767 bfd_h_put_32 (abfd, seg->fileoff, raw.fileoff);
1768 bfd_h_put_32 (abfd, seg->filesize, raw.filesize);
1769 bfd_h_put_32 (abfd, seg->maxprot, raw.maxprot);
1770 bfd_h_put_32 (abfd, seg->initprot, raw.initprot);
1771 bfd_h_put_32 (abfd, seg->nsects, raw.nsects);
1772 bfd_h_put_32 (abfd, seg->flags, raw.flags);
68ffbac6 1773
46d1c23b
TG
1774 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
1775 || bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
452216ab 1776 return FALSE;
1e8a024a 1777
f1bde64c 1778 for (sec = seg->sect_head; sec != NULL; sec = sec->next)
452216ab
TG
1779 if (!bfd_mach_o_write_section_32 (abfd, sec))
1780 return FALSE;
1e8a024a 1781
452216ab 1782 return TRUE;
116c20d2
NC
1783}
1784
452216ab 1785static bfd_boolean
ab273af8 1786bfd_mach_o_write_segment_64 (bfd *abfd, bfd_mach_o_load_command *command)
1e8a024a 1787{
46d1c23b 1788 struct mach_o_segment_command_64_external raw;
c2f09c75 1789 bfd_mach_o_segment_command *seg = &command->command.segment;
f1bde64c 1790 bfd_mach_o_section *sec;
c2f09c75
TG
1791
1792 BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT_64);
1793
f1bde64c
TG
1794 for (sec = seg->sect_head; sec != NULL; sec = sec->next)
1795 if (!bfd_mach_o_write_relocs (abfd, sec))
452216ab 1796 return FALSE;
c2f09c75 1797
46d1c23b
TG
1798 memcpy (raw.segname, seg->segname, 16);
1799 bfd_h_put_64 (abfd, seg->vmaddr, raw.vmaddr);
1800 bfd_h_put_64 (abfd, seg->vmsize, raw.vmsize);
1801 bfd_h_put_64 (abfd, seg->fileoff, raw.fileoff);
1802 bfd_h_put_64 (abfd, seg->filesize, raw.filesize);
1803 bfd_h_put_32 (abfd, seg->maxprot, raw.maxprot);
1804 bfd_h_put_32 (abfd, seg->initprot, raw.initprot);
1805 bfd_h_put_32 (abfd, seg->nsects, raw.nsects);
1806 bfd_h_put_32 (abfd, seg->flags, raw.flags);
1807
1808 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
1809 || bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
452216ab 1810 return FALSE;
c2f09c75 1811
f1bde64c 1812 for (sec = seg->sect_head; sec != NULL; sec = sec->next)
452216ab
TG
1813 if (!bfd_mach_o_write_section_64 (abfd, sec))
1814 return FALSE;
c2f09c75 1815
452216ab 1816 return TRUE;
1e8a024a
TG
1817}
1818
c2f09c75 1819static bfd_boolean
c9ffd2ea 1820bfd_mach_o_write_symtab_content (bfd *abfd, bfd_mach_o_symtab_command *sym)
116c20d2 1821{
046b007d 1822 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
116c20d2 1823 unsigned long i;
c2f09c75 1824 unsigned int wide = bfd_mach_o_wide_p (abfd);
c2f09c75
TG
1825 struct bfd_strtab_hash *strtab;
1826 asymbol **symbols = bfd_get_outsymbols (abfd);
c9ffd2ea 1827 int padlen;
c2f09c75
TG
1828
1829 /* Write the symbols first. */
1830 if (bfd_seek (abfd, sym->symoff, SEEK_SET) != 0)
1831 return FALSE;
1832
c2f09c75
TG
1833 strtab = _bfd_stringtab_init ();
1834 if (strtab == NULL)
1835 return FALSE;
116c20d2 1836
a4551119
TG
1837 if (sym->nsyms > 0)
1838 /* Although we don't strictly need to do this, for compatibility with
1839 Darwin system tools, actually output an empty string for the index
1840 0 entry. */
1841 _bfd_stringtab_add (strtab, "", TRUE, FALSE);
1842
116c20d2
NC
1843 for (i = 0; i < sym->nsyms; i++)
1844 {
91d6fa6a 1845 bfd_size_type str_index;
92bc0e80 1846 bfd_mach_o_asymbol *s = (bfd_mach_o_asymbol *)symbols[i];
68ffbac6 1847
92bc0e80 1848 if (s->symbol.name == 0 || s->symbol.name[0] == '\0')
7f307238 1849 /* An index of 0 always means the empty string. */
07d6d2b8 1850 str_index = 0;
c2f09c75 1851 else
07d6d2b8
AM
1852 {
1853 str_index = _bfd_stringtab_add (strtab, s->symbol.name, TRUE, FALSE);
7f307238 1854
07d6d2b8
AM
1855 if (str_index == (bfd_size_type) -1)
1856 goto err;
1857 }
46d1c23b 1858
c2f09c75 1859 if (wide)
07d6d2b8
AM
1860 {
1861 struct mach_o_nlist_64_external raw;
1862
1863 bfd_h_put_32 (abfd, str_index, raw.n_strx);
1864 bfd_h_put_8 (abfd, s->n_type, raw.n_type);
1865 bfd_h_put_8 (abfd, s->n_sect, raw.n_sect);
1866 bfd_h_put_16 (abfd, s->n_desc, raw.n_desc);
1867 bfd_h_put_64 (abfd, s->symbol.section->vma + s->symbol.value,
1868 raw.n_value);
1869
1870 if (bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
1871 goto err;
1872 }
c2f09c75 1873 else
07d6d2b8
AM
1874 {
1875 struct mach_o_nlist_external raw;
116c20d2 1876
07d6d2b8
AM
1877 bfd_h_put_32 (abfd, str_index, raw.n_strx);
1878 bfd_h_put_8 (abfd, s->n_type, raw.n_type);
1879 bfd_h_put_8 (abfd, s->n_sect, raw.n_sect);
1880 bfd_h_put_16 (abfd, s->n_desc, raw.n_desc);
1881 bfd_h_put_32 (abfd, s->symbol.section->vma + s->symbol.value,
1882 raw.n_value);
46d1c23b 1883
07d6d2b8
AM
1884 if (bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
1885 goto err;
1886 }
116c20d2 1887 }
c2f09c75 1888 sym->strsize = _bfd_stringtab_size (strtab);
92bc0e80
TG
1889 sym->stroff = mdata->filelen;
1890 mdata->filelen += sym->strsize;
116c20d2 1891
c9ffd2ea 1892 if (bfd_seek (abfd, sym->stroff, SEEK_SET) != 0)
64d29018 1893 goto err;
c9ffd2ea 1894
535b785f 1895 if (!_bfd_stringtab_emit (abfd, strtab))
c2f09c75 1896 goto err;
116c20d2 1897
c9ffd2ea
TG
1898 /* Pad string table. */
1899 padlen = bfd_mach_o_pad4 (abfd, sym->strsize);
1900 if (padlen < 0)
1901 return FALSE;
1902 mdata->filelen += padlen;
1903 sym->strsize += padlen;
116c20d2 1904
c2f09c75 1905 return TRUE;
116c20d2 1906
c2f09c75
TG
1907 err:
1908 _bfd_stringtab_free (strtab);
64d29018 1909 sym->strsize = 0;
c2f09c75 1910 return FALSE;
116c20d2
NC
1911}
1912
c9ffd2ea
TG
1913static bfd_boolean
1914bfd_mach_o_write_symtab (bfd *abfd, bfd_mach_o_load_command *command)
1915{
1916 bfd_mach_o_symtab_command *sym = &command->command.symtab;
1917 struct mach_o_symtab_command_external raw;
1918
1919 BFD_ASSERT (command->type == BFD_MACH_O_LC_SYMTAB);
1920
1921 /* The command. */
1922 bfd_h_put_32 (abfd, sym->symoff, raw.symoff);
1923 bfd_h_put_32 (abfd, sym->nsyms, raw.nsyms);
1924 bfd_h_put_32 (abfd, sym->stroff, raw.stroff);
1925 bfd_h_put_32 (abfd, sym->strsize, raw.strsize);
1926
1927 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
1928 || bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
1929 return FALSE;
1930
1931 return TRUE;
1932}
1933
1934/* Count the number of indirect symbols in the image.
1935 Requires that the sections are in their final order. */
1936
1937static unsigned int
1938bfd_mach_o_count_indirect_symbols (bfd *abfd, bfd_mach_o_data_struct *mdata)
1939{
1940 unsigned int i;
1941 unsigned int nisyms = 0;
1942
1943 for (i = 0; i < mdata->nsects; ++i)
1944 {
1945 bfd_mach_o_section *sec = mdata->sections[i];
1946
1947 switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
1948 {
1949 case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS:
1950 case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS:
1951 case BFD_MACH_O_S_SYMBOL_STUBS:
1952 nisyms += bfd_mach_o_section_get_nbr_indirect (abfd, sec);
1953 break;
1954 default:
1955 break;
1956 }
1957 }
1958 return nisyms;
1959}
1960
1961/* Create the dysymtab. */
1962
1963static bfd_boolean
1964bfd_mach_o_build_dysymtab (bfd *abfd, bfd_mach_o_dysymtab_command *cmd)
1965{
1966 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1967
1968 /* TODO:
1969 We are not going to try and fill these in yet and, moreover, we are
1970 going to bail if they are already set. */
1971 if (cmd->nmodtab != 0
1972 || cmd->ntoc != 0
1973 || cmd->nextrefsyms != 0)
1974 {
4eca0228
AM
1975 _bfd_error_handler (_("sorry: modtab, toc and extrefsyms are not yet"
1976 " implemented for dysymtab commands."));
c9ffd2ea
TG
1977 return FALSE;
1978 }
1979
1980 cmd->ilocalsym = 0;
1981
1982 if (bfd_get_symcount (abfd) > 0)
1983 {
1984 asymbol **symbols = bfd_get_outsymbols (abfd);
1985 unsigned long i;
1986
1987 /* Count the number of each kind of symbol. */
1988 for (i = 0; i < bfd_get_symcount (abfd); ++i)
1989 {
1990 bfd_mach_o_asymbol *s = (bfd_mach_o_asymbol *)symbols[i];
1991 if (s->n_type & (BFD_MACH_O_N_EXT | BFD_MACH_O_N_PEXT))
1992 break;
1993 }
1994 cmd->nlocalsym = i;
1995 cmd->iextdefsym = i;
1996 for (; i < bfd_get_symcount (abfd); ++i)
1997 {
1998 bfd_mach_o_asymbol *s = (bfd_mach_o_asymbol *)symbols[i];
1999 if ((s->n_type & BFD_MACH_O_N_TYPE) == BFD_MACH_O_N_UNDF)
2000 break;
2001 }
2002 cmd->nextdefsym = i - cmd->nlocalsym;
2003 cmd->iundefsym = cmd->nextdefsym + cmd->iextdefsym;
2004 cmd->nundefsym = bfd_get_symcount (abfd)
2005 - cmd->nlocalsym
2006 - cmd->nextdefsym;
2007 }
2008 else
2009 {
2010 cmd->nlocalsym = 0;
2011 cmd->iextdefsym = 0;
2012 cmd->nextdefsym = 0;
2013 cmd->iundefsym = 0;
2014 cmd->nundefsym = 0;
2015 }
2016
2017 cmd->nindirectsyms = bfd_mach_o_count_indirect_symbols (abfd, mdata);
2018 if (cmd->nindirectsyms > 0)
2019 {
2020 unsigned i;
2021 unsigned n;
2022
2023 mdata->filelen = FILE_ALIGN (mdata->filelen, 2);
2024 cmd->indirectsymoff = mdata->filelen;
2025 mdata->filelen += cmd->nindirectsyms * 4;
2026
64d29018
NC
2027 if (cmd->nindirectsyms * 4 < cmd->nindirectsyms)
2028 return FALSE;
c9ffd2ea
TG
2029 cmd->indirect_syms = bfd_zalloc (abfd, cmd->nindirectsyms * 4);
2030 if (cmd->indirect_syms == NULL)
07d6d2b8 2031 return FALSE;
c9ffd2ea
TG
2032
2033 n = 0;
2034 for (i = 0; i < mdata->nsects; ++i)
2035 {
2036 bfd_mach_o_section *sec = mdata->sections[i];
2037
2038 switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
2039 {
2040 case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS:
2041 case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS:
2042 case BFD_MACH_O_S_SYMBOL_STUBS:
2043 {
2044 unsigned j, num;
2045 bfd_mach_o_asymbol **isyms = sec->indirect_syms;
2046
2047 num = bfd_mach_o_section_get_nbr_indirect (abfd, sec);
2048 if (isyms == NULL || num == 0)
2049 break;
2050 /* Record the starting index in the reserved1 field. */
2051 sec->reserved1 = n;
2052 for (j = 0; j < num; j++, n++)
2053 {
2054 if (isyms[j] == NULL)
07d6d2b8 2055 cmd->indirect_syms[n] = BFD_MACH_O_INDIRECT_SYM_LOCAL;
c9ffd2ea
TG
2056 else if (isyms[j]->symbol.section == bfd_abs_section_ptr
2057 && ! (isyms[j]->n_type & BFD_MACH_O_N_EXT))
07d6d2b8 2058 cmd->indirect_syms[n] = BFD_MACH_O_INDIRECT_SYM_LOCAL
c9ffd2ea
TG
2059 | BFD_MACH_O_INDIRECT_SYM_ABS;
2060 else
07d6d2b8 2061 cmd->indirect_syms[n] = isyms[j]->symbol.udata.i;
c9ffd2ea
TG
2062 }
2063 }
2064 break;
2065 default:
2066 break;
2067 }
2068 }
2069 }
2070
2071 return TRUE;
2072}
2073
7f307238
IS
2074/* Write a dysymtab command.
2075 TODO: Possibly coalesce writes of smaller objects. */
2076
2077static bfd_boolean
2078bfd_mach_o_write_dysymtab (bfd *abfd, bfd_mach_o_load_command *command)
2079{
2080 bfd_mach_o_dysymtab_command *cmd = &command->command.dysymtab;
2081
2082 BFD_ASSERT (command->type == BFD_MACH_O_LC_DYSYMTAB);
2083
2084 if (cmd->nmodtab != 0)
2085 {
2086 unsigned int i;
2087
2088 if (bfd_seek (abfd, cmd->modtaboff, SEEK_SET) != 0)
2089 return FALSE;
2090
2091 for (i = 0; i < cmd->nmodtab; i++)
2092 {
2093 bfd_mach_o_dylib_module *module = &cmd->dylib_module[i];
2094 unsigned int iinit;
2095 unsigned int ninit;
2096
2097 iinit = module->iinit & 0xffff;
2098 iinit |= ((module->iterm & 0xffff) << 16);
2099
2100 ninit = module->ninit & 0xffff;
2101 ninit |= ((module->nterm & 0xffff) << 16);
2102
2103 if (bfd_mach_o_wide_p (abfd))
2104 {
2105 struct mach_o_dylib_module_64_external w;
2106
2107 bfd_h_put_32 (abfd, module->module_name_idx, &w.module_name);
2108 bfd_h_put_32 (abfd, module->iextdefsym, &w.iextdefsym);
2109 bfd_h_put_32 (abfd, module->nextdefsym, &w.nextdefsym);
2110 bfd_h_put_32 (abfd, module->irefsym, &w.irefsym);
2111 bfd_h_put_32 (abfd, module->nrefsym, &w.nrefsym);
2112 bfd_h_put_32 (abfd, module->ilocalsym, &w.ilocalsym);
2113 bfd_h_put_32 (abfd, module->nlocalsym, &w.nlocalsym);
2114 bfd_h_put_32 (abfd, module->iextrel, &w.iextrel);
2115 bfd_h_put_32 (abfd, module->nextrel, &w.nextrel);
2116 bfd_h_put_32 (abfd, iinit, &w.iinit_iterm);
2117 bfd_h_put_32 (abfd, ninit, &w.ninit_nterm);
2118 bfd_h_put_64 (abfd, module->objc_module_info_addr,
2119 &w.objc_module_info_addr);
2120 bfd_h_put_32 (abfd, module->objc_module_info_size,
2121 &w.objc_module_info_size);
2122
2123 if (bfd_bwrite ((void *) &w, sizeof (w), abfd) != sizeof (w))
2124 return FALSE;
2125 }
2126 else
2127 {
2128 struct mach_o_dylib_module_external n;
2129
2130 bfd_h_put_32 (abfd, module->module_name_idx, &n.module_name);
2131 bfd_h_put_32 (abfd, module->iextdefsym, &n.iextdefsym);
2132 bfd_h_put_32 (abfd, module->nextdefsym, &n.nextdefsym);
2133 bfd_h_put_32 (abfd, module->irefsym, &n.irefsym);
2134 bfd_h_put_32 (abfd, module->nrefsym, &n.nrefsym);
2135 bfd_h_put_32 (abfd, module->ilocalsym, &n.ilocalsym);
2136 bfd_h_put_32 (abfd, module->nlocalsym, &n.nlocalsym);
2137 bfd_h_put_32 (abfd, module->iextrel, &n.iextrel);
2138 bfd_h_put_32 (abfd, module->nextrel, &n.nextrel);
2139 bfd_h_put_32 (abfd, iinit, &n.iinit_iterm);
2140 bfd_h_put_32 (abfd, ninit, &n.ninit_nterm);
2141 bfd_h_put_32 (abfd, module->objc_module_info_addr,
2142 &n.objc_module_info_addr);
2143 bfd_h_put_32 (abfd, module->objc_module_info_size,
2144 &n.objc_module_info_size);
2145
2146 if (bfd_bwrite ((void *) &n, sizeof (n), abfd) != sizeof (n))
2147 return FALSE;
2148 }
2149 }
2150 }
2151
2152 if (cmd->ntoc != 0)
2153 {
2154 unsigned int i;
2155
2156 if (bfd_seek (abfd, cmd->tocoff, SEEK_SET) != 0)
2157 return FALSE;
2158
2159 for (i = 0; i < cmd->ntoc; i++)
2160 {
2161 struct mach_o_dylib_table_of_contents_external raw;
2162 bfd_mach_o_dylib_table_of_content *toc = &cmd->dylib_toc[i];
2163
2164 bfd_h_put_32 (abfd, toc->symbol_index, &raw.symbol_index);
2165 bfd_h_put_32 (abfd, toc->module_index, &raw.module_index);
2166
2167 if (bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
2168 return FALSE;
2169 }
2170 }
68ffbac6 2171
7f307238
IS
2172 if (cmd->nindirectsyms > 0)
2173 {
2174 unsigned int i;
2175
2176 if (bfd_seek (abfd, cmd->indirectsymoff, SEEK_SET) != 0)
2177 return FALSE;
2178
2179 for (i = 0; i < cmd->nindirectsyms; ++i)
2180 {
2181 unsigned char raw[4];
2182
2183 bfd_h_put_32 (abfd, cmd->indirect_syms[i], &raw);
2184 if (bfd_bwrite (raw, sizeof (raw), abfd) != sizeof (raw))
2185 return FALSE;
68ffbac6 2186 }
7f307238
IS
2187 }
2188
2189 if (cmd->nextrefsyms != 0)
2190 {
2191 unsigned int i;
2192
2193 if (bfd_seek (abfd, cmd->extrefsymoff, SEEK_SET) != 0)
2194 return FALSE;
2195
2196 for (i = 0; i < cmd->nextrefsyms; i++)
2197 {
2198 unsigned long v;
2199 unsigned char raw[4];
2200 bfd_mach_o_dylib_reference *ref = &cmd->ext_refs[i];
2201
2202 /* Fields isym and flags are written as bit-fields, thus we need
2203 a specific processing for endianness. */
2204
2205 if (bfd_big_endian (abfd))
2206 {
2207 v = ((ref->isym & 0xffffff) << 8);
2208 v |= ref->flags & 0xff;
2209 }
2210 else
2211 {
2212 v = ref->isym & 0xffffff;
2213 v |= ((ref->flags & 0xff) << 24);
2214 }
2215
2216 bfd_h_put_32 (abfd, v, raw);
2217 if (bfd_bwrite (raw, sizeof (raw), abfd) != sizeof (raw))
2218 return FALSE;
2219 }
2220 }
2221
2222 /* The command. */
2223 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0)
2224 return FALSE;
2225 else
2226 {
2227 struct mach_o_dysymtab_command_external raw;
2228
2229 bfd_h_put_32 (abfd, cmd->ilocalsym, &raw.ilocalsym);
2230 bfd_h_put_32 (abfd, cmd->nlocalsym, &raw.nlocalsym);
2231 bfd_h_put_32 (abfd, cmd->iextdefsym, &raw.iextdefsym);
2232 bfd_h_put_32 (abfd, cmd->nextdefsym, &raw.nextdefsym);
2233 bfd_h_put_32 (abfd, cmd->iundefsym, &raw.iundefsym);
2234 bfd_h_put_32 (abfd, cmd->nundefsym, &raw.nundefsym);
2235 bfd_h_put_32 (abfd, cmd->tocoff, &raw.tocoff);
2236 bfd_h_put_32 (abfd, cmd->ntoc, &raw.ntoc);
2237 bfd_h_put_32 (abfd, cmd->modtaboff, &raw.modtaboff);
2238 bfd_h_put_32 (abfd, cmd->nmodtab, &raw.nmodtab);
2239 bfd_h_put_32 (abfd, cmd->extrefsymoff, &raw.extrefsymoff);
2240 bfd_h_put_32 (abfd, cmd->nextrefsyms, &raw.nextrefsyms);
2241 bfd_h_put_32 (abfd, cmd->indirectsymoff, &raw.indirectsymoff);
2242 bfd_h_put_32 (abfd, cmd->nindirectsyms, &raw.nindirectsyms);
2243 bfd_h_put_32 (abfd, cmd->extreloff, &raw.extreloff);
2244 bfd_h_put_32 (abfd, cmd->nextrel, &raw.nextrel);
2245 bfd_h_put_32 (abfd, cmd->locreloff, &raw.locreloff);
2246 bfd_h_put_32 (abfd, cmd->nlocrel, &raw.nlocrel);
2247
2248 if (bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
2249 return FALSE;
2250 }
2251
2252 return TRUE;
2253}
2254
2255static unsigned
b22161d6 2256bfd_mach_o_primary_symbol_sort_key (bfd_mach_o_asymbol *s)
7f307238 2257{
b22161d6 2258 unsigned mtyp = s->n_type & BFD_MACH_O_N_TYPE;
68588f95
IS
2259
2260 /* Just leave debug symbols where they are (pretend they are local, and
2261 then they will just be sorted on position). */
b22161d6 2262 if (s->n_type & BFD_MACH_O_N_STAB)
68588f95
IS
2263 return 0;
2264
7f307238 2265 /* Local (we should never see an undefined local AFAICT). */
b22161d6 2266 if (! (s->n_type & (BFD_MACH_O_N_EXT | BFD_MACH_O_N_PEXT)))
7f307238
IS
2267 return 0;
2268
2269 /* Common symbols look like undefined externs. */
68588f95 2270 if (mtyp == BFD_MACH_O_N_UNDF)
7f307238
IS
2271 return 2;
2272
b22161d6 2273 /* A defined non-local, non-debug symbol. */
7f307238
IS
2274 return 1;
2275}
2276
2277static int
2278bfd_mach_o_cf_symbols (const void *a, const void *b)
2279{
2280 bfd_mach_o_asymbol *sa = *(bfd_mach_o_asymbol **) a;
2281 bfd_mach_o_asymbol *sb = *(bfd_mach_o_asymbol **) b;
2282 unsigned int soa, sob;
2283
b22161d6
IS
2284 soa = bfd_mach_o_primary_symbol_sort_key (sa);
2285 sob = bfd_mach_o_primary_symbol_sort_key (sb);
7f307238
IS
2286 if (soa < sob)
2287 return -1;
2288
2289 if (soa > sob)
2290 return 1;
2291
68588f95 2292 /* If it's local or stab, just preserve the input order. */
7f307238
IS
2293 if (soa == 0)
2294 {
2295 if (sa->symbol.udata.i < sb->symbol.udata.i)
07d6d2b8 2296 return -1;
7f307238 2297 if (sa->symbol.udata.i > sb->symbol.udata.i)
07d6d2b8 2298 return 1;
b22161d6
IS
2299
2300 /* This is probably an error. */
7f307238
IS
2301 return 0;
2302 }
2303
b22161d6
IS
2304 /* The second sort key is name. */
2305 return strcmp (sa->symbol.name, sb->symbol.name);
7f307238
IS
2306}
2307
2308/* Process the symbols.
2309
2310 This should be OK for single-module files - but it is not likely to work
2311 for multi-module shared libraries.
2312
2313 (a) If the application has not filled in the relevant mach-o fields, make
2314 an estimate.
2315
2316 (b) Order them, like this:
2317 ( i) local.
2318 (unsorted)
2319 ( ii) external defined
2320 (by name)
b22161d6 2321 (iii) external undefined/common
7f307238
IS
2322 (by name)
2323 ( iv) common
2324 (by name)
b22161d6 2325*/
92bc0e80
TG
2326
2327static bfd_boolean
b22161d6 2328bfd_mach_o_mangle_symbols (bfd *abfd)
92bc0e80
TG
2329{
2330 unsigned long i;
2331 asymbol **symbols = bfd_get_outsymbols (abfd);
2332
7f307238
IS
2333 if (symbols == NULL || bfd_get_symcount (abfd) == 0)
2334 return TRUE;
2335
92bc0e80
TG
2336 for (i = 0; i < bfd_get_symcount (abfd); i++)
2337 {
2338 bfd_mach_o_asymbol *s = (bfd_mach_o_asymbol *)symbols[i];
2339
b22161d6
IS
2340 /* We use this value, which is out-of-range as a symbol index, to signal
2341 that the mach-o-specific data are not filled in and need to be created
2342 from the bfd values. It is much preferable for the application to do
2343 this, since more meaningful diagnostics can be made that way. */
2344
2345 if (s->symbol.udata.i == SYM_MACHO_FIELDS_UNSET)
07d6d2b8
AM
2346 {
2347 /* No symbol information has been set - therefore determine
2348 it from the bfd symbol flags/info. */
2349 if (s->symbol.section == bfd_abs_section_ptr)
2350 s->n_type = BFD_MACH_O_N_ABS;
2351 else if (s->symbol.section == bfd_und_section_ptr)
2352 {
2353 s->n_type = BFD_MACH_O_N_UNDF;
2354 if (s->symbol.flags & BSF_WEAK)
2355 s->n_desc |= BFD_MACH_O_N_WEAK_REF;
2356 /* mach-o automatically makes undefined symbols extern. */
7f307238 2357 s->n_type |= BFD_MACH_O_N_EXT;
b22161d6 2358 s->symbol.flags |= BSF_GLOBAL;
07d6d2b8
AM
2359 }
2360 else if (s->symbol.section == bfd_com_section_ptr)
b22161d6 2361 {
07d6d2b8
AM
2362 s->n_type = BFD_MACH_O_N_UNDF | BFD_MACH_O_N_EXT;
2363 s->symbol.flags |= BSF_GLOBAL;
2364 }
2365 else
2366 s->n_type = BFD_MACH_O_N_SECT;
68ffbac6 2367
07d6d2b8
AM
2368 if (s->symbol.flags & BSF_GLOBAL)
2369 s->n_type |= BFD_MACH_O_N_EXT;
2370 }
92bc0e80 2371
7f307238 2372 /* Put the section index in, where required. */
68588f95 2373 if ((s->symbol.section != bfd_abs_section_ptr
07d6d2b8
AM
2374 && s->symbol.section != bfd_und_section_ptr
2375 && s->symbol.section != bfd_com_section_ptr)
2376 || ((s->n_type & BFD_MACH_O_N_STAB) != 0
2377 && s->symbol.name == NULL))
707e555b 2378 s->n_sect = s->symbol.section->output_section->target_index;
92bc0e80 2379
b22161d6
IS
2380 /* Number to preserve order for local and debug syms. */
2381 s->symbol.udata.i = i;
7f307238
IS
2382 }
2383
b22161d6
IS
2384 /* Sort the symbols. */
2385 qsort ((void *) symbols, (size_t) bfd_get_symcount (abfd),
2386 sizeof (asymbol *), bfd_mach_o_cf_symbols);
7f307238 2387
b22161d6
IS
2388 for (i = 0; i < bfd_get_symcount (abfd); ++i)
2389 {
2390 bfd_mach_o_asymbol *s = (bfd_mach_o_asymbol *)symbols[i];
2391 s->symbol.udata.i = i; /* renumber. */
7f307238
IS
2392 }
2393
2394 return TRUE;
2395}
2396
2397/* We build a flat table of sections, which can be re-ordered if necessary.
2398 Fill in the section number and other mach-o-specific data. */
2399
2400static bfd_boolean
2401bfd_mach_o_mangle_sections (bfd *abfd, bfd_mach_o_data_struct *mdata)
2402{
2403 asection *sec;
2404 unsigned target_index;
2405 unsigned nsect;
2406
2407 nsect = bfd_count_sections (abfd);
68ffbac6 2408
7f307238
IS
2409 /* Don't do it if it's already set - assume the application knows what it's
2410 doing. */
2411 if (mdata->nsects == nsect
2412 && (mdata->nsects == 0 || mdata->sections != NULL))
2413 return TRUE;
2414
a1165289
NC
2415 /* We need to check that this can be done... */
2416 if (nsect > 255)
2417 {
4eca0228
AM
2418 _bfd_error_handler (_("mach-o: there are too many sections (%u)"
2419 " maximum is 255,\n"), nsect);
a1165289
NC
2420 return FALSE;
2421 }
2422
7f307238 2423 mdata->nsects = nsect;
64d29018
NC
2424 mdata->sections = bfd_alloc2 (abfd,
2425 mdata->nsects, sizeof (bfd_mach_o_section *));
7f307238
IS
2426 if (mdata->sections == NULL)
2427 return FALSE;
2428
7f307238 2429 /* Create Mach-O sections.
68ffbac6 2430 Section type, attribute and align should have been set when the
7f307238
IS
2431 section was created - either read in or specified. */
2432 target_index = 0;
2433 for (sec = abfd->sections; sec; sec = sec->next)
2434 {
2435 unsigned bfd_align = bfd_get_section_alignment (abfd, sec);
2436 bfd_mach_o_section *msect = bfd_mach_o_get_mach_o_section (sec);
2437
2438 mdata->sections[target_index] = msect;
2439
2440 msect->addr = bfd_get_section_vma (abfd, sec);
2441 msect->size = bfd_get_section_size (sec);
2442
68ffbac6 2443 /* Use the largest alignment set, in case it was bumped after the
7f307238
IS
2444 section was created. */
2445 msect->align = msect->align > bfd_align ? msect->align : bfd_align;
2446
2447 msect->offset = 0;
2448 sec->target_index = ++target_index;
92bc0e80 2449 }
7f307238 2450
92bc0e80
TG
2451 return TRUE;
2452}
2453
154a1ee5 2454bfd_boolean
116c20d2 2455bfd_mach_o_write_contents (bfd *abfd)
3af9a47b 2456{
046b007d 2457 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
c9ffd2ea
TG
2458 bfd_mach_o_load_command *cmd;
2459 bfd_mach_o_symtab_command *symtab = NULL;
2460 bfd_mach_o_dysymtab_command *dysymtab = NULL;
2461 bfd_mach_o_segment_command *linkedit = NULL;
3af9a47b 2462
7f307238 2463 /* Make the commands, if not already present. */
c9ffd2ea
TG
2464 if (!abfd->output_has_begun && !bfd_mach_o_build_commands (abfd))
2465 return FALSE;
2466 abfd->output_has_begun = TRUE;
92bc0e80 2467
c9ffd2ea 2468 /* Write the header. */
154a1ee5 2469 if (!bfd_mach_o_write_header (abfd, &mdata->header))
b34976b6 2470 return FALSE;
3af9a47b 2471
c9ffd2ea
TG
2472 /* First pass: allocate the linkedit segment. */
2473 for (cmd = mdata->first_command; cmd != NULL; cmd = cmd->next)
2474 switch (cmd->type)
2475 {
2476 case BFD_MACH_O_LC_SEGMENT_64:
2477 case BFD_MACH_O_LC_SEGMENT:
2478 if (strcmp (cmd->command.segment.segname, "__LINKEDIT") == 0)
2479 linkedit = &cmd->command.segment;
2480 break;
2481 case BFD_MACH_O_LC_SYMTAB:
2482 symtab = &cmd->command.symtab;
2483 break;
2484 case BFD_MACH_O_LC_DYSYMTAB:
2485 dysymtab = &cmd->command.dysymtab;
2486 break;
2487 case BFD_MACH_O_LC_DYLD_INFO:
2488 {
2489 bfd_mach_o_dyld_info_command *di = &cmd->command.dyld_info;
2490
2491 if (di->rebase_size != 0)
2492 {
2493 di->rebase_off = mdata->filelen;
2494 mdata->filelen += di->rebase_size;
2495 }
2496 if (di->bind_size != 0)
2497 {
2498 di->bind_off = mdata->filelen;
2499 mdata->filelen += di->bind_size;
2500 }
2501 if (di->weak_bind_size != 0)
2502 {
2503 di->weak_bind_off = mdata->filelen;
2504 mdata->filelen += di->weak_bind_size;
2505 }
2506 if (di->lazy_bind_size != 0)
2507 {
2508 di->lazy_bind_off = mdata->filelen;
2509 mdata->filelen += di->lazy_bind_size;
2510 }
2511 if (di->export_size != 0)
2512 {
2513 di->export_off = mdata->filelen;
2514 mdata->filelen += di->export_size;
2515 }
2516 }
2517 break;
2518 case BFD_MACH_O_LC_LOAD_DYLIB:
2519 case BFD_MACH_O_LC_LOAD_DYLINKER:
2520 case BFD_MACH_O_LC_MAIN:
2521 /* Nothing to do. */
2522 break;
2523 default:
4eca0228 2524 _bfd_error_handler
d42c267e
AM
2525 (_("unable to allocate data for load command %#x"),
2526 cmd->type);
c9ffd2ea
TG
2527 break;
2528 }
2529
2530 /* Specially handle symtab and dysymtab. */
2531
2532 /* Pre-allocate the symbol table (but not the string table). The reason
2533 is that the dysymtab is after the symbol table but before the string
2534 table (required by the native strip tool). */
2535 if (symtab != NULL)
2536 {
2537 unsigned int symlen;
2538 unsigned int wide = bfd_mach_o_wide_p (abfd);
2539
2540 symlen = wide ? BFD_MACH_O_NLIST_64_SIZE : BFD_MACH_O_NLIST_SIZE;
2541
2542 /* Align for symbols. */
2543 mdata->filelen = FILE_ALIGN (mdata->filelen, wide ? 3 : 2);
2544 symtab->symoff = mdata->filelen;
2545
2546 symtab->nsyms = bfd_get_symcount (abfd);
2547 mdata->filelen += symtab->nsyms * symlen;
2548 }
2549
2550 /* Build the dysymtab. */
2551 if (dysymtab != NULL)
2552 if (!bfd_mach_o_build_dysymtab (abfd, dysymtab))
2553 return FALSE;
2554
2555 /* Write symtab and strtab. */
2556 if (symtab != NULL)
2557 if (!bfd_mach_o_write_symtab_content (abfd, symtab))
2558 return FALSE;
2559
2560 /* Adjust linkedit size. */
2561 if (linkedit != NULL)
2562 {
2563 /* bfd_vma pagemask = bfd_mach_o_get_backend_data (abfd)->page_size - 1; */
2564
2565 linkedit->vmsize = mdata->filelen - linkedit->fileoff;
2566 /* linkedit->vmsize = (linkedit->vmsize + pagemask) & ~pagemask; */
2567 linkedit->filesize = mdata->filelen - linkedit->fileoff;
2568
2569 linkedit->initprot = BFD_MACH_O_PROT_READ;
2570 linkedit->maxprot = BFD_MACH_O_PROT_READ | BFD_MACH_O_PROT_WRITE
2571 | BFD_MACH_O_PROT_EXECUTE;
2572 }
2573
2574 /* Second pass: write commands. */
2575 for (cmd = mdata->first_command; cmd != NULL; cmd = cmd->next)
3af9a47b 2576 {
46d1c23b 2577 struct mach_o_load_command_external raw;
3af9a47b
NC
2578 unsigned long typeflag;
2579
c9ffd2ea 2580 typeflag = cmd->type | (cmd->type_required ? BFD_MACH_O_LC_REQ_DYLD : 0);
3af9a47b 2581
46d1c23b 2582 bfd_h_put_32 (abfd, typeflag, raw.cmd);
c9ffd2ea 2583 bfd_h_put_32 (abfd, cmd->len, raw.cmdsize);
3af9a47b 2584
c9ffd2ea 2585 if (bfd_seek (abfd, cmd->offset, SEEK_SET) != 0
07d6d2b8 2586 || bfd_bwrite (&raw, BFD_MACH_O_LC_SIZE, abfd) != 8)
b34976b6 2587 return FALSE;
3af9a47b 2588
c9ffd2ea 2589 switch (cmd->type)
3af9a47b
NC
2590 {
2591 case BFD_MACH_O_LC_SEGMENT:
c9ffd2ea 2592 if (!bfd_mach_o_write_segment_32 (abfd, cmd))
1e8a024a
TG
2593 return FALSE;
2594 break;
2595 case BFD_MACH_O_LC_SEGMENT_64:
c9ffd2ea 2596 if (!bfd_mach_o_write_segment_64 (abfd, cmd))
b34976b6 2597 return FALSE;
3af9a47b
NC
2598 break;
2599 case BFD_MACH_O_LC_SYMTAB:
c9ffd2ea 2600 if (!bfd_mach_o_write_symtab (abfd, cmd))
b34976b6 2601 return FALSE;
3af9a47b 2602 break;
7f307238 2603 case BFD_MACH_O_LC_DYSYMTAB:
c9ffd2ea 2604 if (!bfd_mach_o_write_dysymtab (abfd, cmd))
7f307238
IS
2605 return FALSE;
2606 break;
3af9a47b
NC
2607 case BFD_MACH_O_LC_THREAD:
2608 case BFD_MACH_O_LC_UNIXTHREAD:
c9ffd2ea 2609 if (!bfd_mach_o_write_thread (abfd, cmd))
b34976b6 2610 return FALSE;
3af9a47b 2611 break;
3af9a47b 2612 case BFD_MACH_O_LC_LOAD_DYLIB:
c9ffd2ea
TG
2613 if (!bfd_mach_o_write_dylib (abfd, cmd))
2614 return FALSE;
2615 break;
3af9a47b 2616 case BFD_MACH_O_LC_LOAD_DYLINKER:
c9ffd2ea
TG
2617 if (!bfd_mach_o_write_dylinker (abfd, cmd))
2618 return FALSE;
2619 break;
2620 case BFD_MACH_O_LC_MAIN:
2621 if (!bfd_mach_o_write_main (abfd, cmd))
2622 return FALSE;
2623 break;
2624 case BFD_MACH_O_LC_DYLD_INFO:
2625 if (!bfd_mach_o_write_dyld_info (abfd, cmd))
2626 return FALSE;
3af9a47b
NC
2627 break;
2628 default:
4eca0228 2629 _bfd_error_handler
d42c267e
AM
2630 (_("unable to write unknown load command %#x"),
2631 cmd->type);
b34976b6 2632 return FALSE;
3af9a47b
NC
2633 }
2634 }
2635
b34976b6 2636 return TRUE;
3af9a47b
NC
2637}
2638
f1bde64c
TG
2639static void
2640bfd_mach_o_append_section_to_segment (bfd_mach_o_segment_command *seg,
07d6d2b8 2641 bfd_mach_o_section *s)
f1bde64c 2642{
f1bde64c
TG
2643 if (seg->sect_head == NULL)
2644 seg->sect_head = s;
2645 else
2646 seg->sect_tail->next = s;
2647 seg->sect_tail = s;
2648}
2649
2650/* Create section Mach-O flags from BFD flags. */
2651
2652static void
3cc27770
TG
2653bfd_mach_o_set_section_flags_from_bfd (bfd *abfd ATTRIBUTE_UNUSED,
2654 asection *sec)
f1bde64c
TG
2655{
2656 flagword bfd_flags;
2657 bfd_mach_o_section *s = bfd_mach_o_get_mach_o_section (sec);
2658
2659 /* Create default flags. */
2660 bfd_flags = bfd_get_section_flags (abfd, sec);
2661 if ((bfd_flags & SEC_CODE) == SEC_CODE)
2662 s->flags = BFD_MACH_O_S_ATTR_PURE_INSTRUCTIONS
2663 | BFD_MACH_O_S_ATTR_SOME_INSTRUCTIONS
2664 | BFD_MACH_O_S_REGULAR;
2665 else if ((bfd_flags & (SEC_ALLOC | SEC_LOAD)) == SEC_ALLOC)
2666 s->flags = BFD_MACH_O_S_ZEROFILL;
2667 else if (bfd_flags & SEC_DEBUGGING)
2668 s->flags = BFD_MACH_O_S_REGULAR | BFD_MACH_O_S_ATTR_DEBUG;
2669 else
2670 s->flags = BFD_MACH_O_S_REGULAR;
2671}
2672
7f307238 2673static bfd_boolean
c9ffd2ea 2674bfd_mach_o_build_obj_seg_command (bfd *abfd, bfd_mach_o_segment_command *seg)
7f307238 2675{
c9ffd2ea
TG
2676 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
2677 unsigned int i, j;
7f307238 2678
7f307238 2679 seg->vmaddr = 0;
7f307238 2680 seg->fileoff = mdata->filelen;
c9ffd2ea
TG
2681 seg->initprot = BFD_MACH_O_PROT_READ | BFD_MACH_O_PROT_WRITE
2682 | BFD_MACH_O_PROT_EXECUTE;
2683 seg->maxprot = seg->initprot;
7f307238 2684
68ffbac6 2685 /* Append sections to the segment.
09903f4b
IS
2686
2687 This is a little tedious, we have to honor the need to account zerofill
2688 sections after all the rest. This forces us to do the calculation of
68ffbac6 2689 total vmsize in three passes so that any alignment increments are
09903f4b 2690 properly accounted. */
7f307238
IS
2691 for (i = 0; i < mdata->nsects; ++i)
2692 {
2693 bfd_mach_o_section *s = mdata->sections[i];
2694 asection *sec = s->bfdsection;
2695
09903f4b
IS
2696 /* Although we account for zerofill section sizes in vm order, they are
2697 placed in the file in source sequence. */
c9ffd2ea 2698 bfd_mach_o_append_section_to_segment (seg, s);
e5081f2f 2699 s->offset = 0;
68ffbac6 2700
c9ffd2ea
TG
2701 /* Zerofill sections have zero file size & offset, the only content
2702 written to the file is the symbols. */
e5081f2f 2703 if ((s->flags & BFD_MACH_O_SECTION_TYPE_MASK) == BFD_MACH_O_S_ZEROFILL
07d6d2b8 2704 || ((s->flags & BFD_MACH_O_SECTION_TYPE_MASK)
c9ffd2ea 2705 == BFD_MACH_O_S_GB_ZEROFILL))
07d6d2b8 2706 continue;
e5081f2f 2707
c9ffd2ea
TG
2708 /* The Darwin system tools (in MH_OBJECT files, at least) always account
2709 sections, even those with zero size. */
e5081f2f 2710 if (s->size > 0)
c9ffd2ea 2711 {
09903f4b
IS
2712 seg->vmsize = FILE_ALIGN (seg->vmsize, s->align);
2713 seg->vmsize += s->size;
2714
c9ffd2ea
TG
2715 /* MH_OBJECT files have unaligned content. */
2716 if (1)
2717 {
2718 seg->filesize = FILE_ALIGN (seg->filesize, s->align);
07d6d2b8
AM
2719 mdata->filelen = FILE_ALIGN (mdata->filelen, s->align);
2720 }
09903f4b
IS
2721 seg->filesize += s->size;
2722
c9ffd2ea
TG
2723 /* The system tools write even zero-sized sections with an offset
2724 field set to the current file position. */
07d6d2b8 2725 s->offset = mdata->filelen;
c9ffd2ea 2726 }
7f307238
IS
2727
2728 sec->filepos = s->offset;
7f307238
IS
2729 mdata->filelen += s->size;
2730 }
2731
3cc27770 2732 /* Now pass through again, for zerofill, only now we just update the
c9ffd2ea
TG
2733 vmsize, and then for zerofill_GB. */
2734 for (j = 0; j < 2; j++)
09903f4b 2735 {
c9ffd2ea 2736 unsigned int stype;
68ffbac6 2737
c9ffd2ea
TG
2738 if (j == 0)
2739 stype = BFD_MACH_O_S_ZEROFILL;
2740 else
2741 stype = BFD_MACH_O_S_GB_ZEROFILL;
09903f4b 2742
c9ffd2ea
TG
2743 for (i = 0; i < mdata->nsects; ++i)
2744 {
2745 bfd_mach_o_section *s = mdata->sections[i];
2746
2747 if ((s->flags & BFD_MACH_O_SECTION_TYPE_MASK) != stype)
2748 continue;
2749
2750 if (s->size > 0)
2751 {
2752 seg->vmsize = FILE_ALIGN (seg->vmsize, s->align);
2753 seg->vmsize += s->size;
2754 }
09903f4b
IS
2755 }
2756 }
bb76d940 2757
09903f4b 2758 /* Allocate space for the relocations. */
707e555b 2759 mdata->filelen = FILE_ALIGN (mdata->filelen, 2);
bb76d940
IS
2760
2761 for (i = 0; i < mdata->nsects; ++i)
2762 {
2763 bfd_mach_o_section *ms = mdata->sections[i];
2764 asection *sec = ms->bfdsection;
68ffbac6 2765
c9ffd2ea
TG
2766 ms->nreloc = sec->reloc_count;
2767 if (ms->nreloc == 0)
07d6d2b8 2768 {
c9ffd2ea 2769 /* Clear nreloc and reloff if there is no relocs. */
bb76d940
IS
2770 ms->reloff = 0;
2771 continue;
07d6d2b8 2772 }
bb76d940
IS
2773 sec->rel_filepos = mdata->filelen;
2774 ms->reloff = sec->rel_filepos;
2775 mdata->filelen += sec->reloc_count * BFD_MACH_O_RELENT_SIZE;
2776 }
7f307238
IS
2777
2778 return TRUE;
2779}
2780
c9ffd2ea
TG
2781static bfd_boolean
2782bfd_mach_o_build_exec_seg_command (bfd *abfd, bfd_mach_o_segment_command *seg)
50d10658 2783{
c9ffd2ea 2784 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
50d10658 2785 unsigned int i;
c9ffd2ea
TG
2786 bfd_vma pagemask = bfd_mach_o_get_backend_data (abfd)->page_size - 1;
2787 bfd_vma vma;
2788 bfd_mach_o_section *s;
2789
2790 seg->vmsize = 0;
50d10658 2791
c9ffd2ea
TG
2792 seg->fileoff = mdata->filelen;
2793 seg->maxprot = 0;
2794 seg->initprot = 0;
2795 seg->flags = 0;
2796
2797 /* Append sections to the segment. We assume they are properly ordered
2798 by vma (but we check that). */
2799 vma = 0;
50d10658
IS
2800 for (i = 0; i < mdata->nsects; ++i)
2801 {
c9ffd2ea 2802 s = mdata->sections[i];
50d10658 2803
c9ffd2ea
TG
2804 /* Consider only sections for this segment. */
2805 if (strcmp (seg->segname, s->segname) != 0)
2806 continue;
50d10658 2807
c9ffd2ea 2808 bfd_mach_o_append_section_to_segment (seg, s);
7f307238 2809
86eafac0
NC
2810 if (s->addr < vma)
2811 {
4eca0228 2812 _bfd_error_handler
695344c0 2813 /* xgettext:c-format */
2dcf00ce
AM
2814 (_("section address (%#" PRIx64 ") "
2815 "below start of segment (%#" PRIx64 ")"),
2816 (uint64_t) s->addr, (uint64_t) vma);
86eafac0
NC
2817 return FALSE;
2818 }
2819
c9ffd2ea 2820 vma = s->addr + s->size;
7f307238
IS
2821 }
2822
c9ffd2ea
TG
2823 /* Set segment file offset: make it page aligned. */
2824 vma = seg->sect_head->addr;
2825 seg->vmaddr = vma & ~pagemask;
2826 if ((mdata->filelen & pagemask) > (vma & pagemask))
2827 mdata->filelen += pagemask + 1;
2828 seg->fileoff = mdata->filelen & ~pagemask;
2829 mdata->filelen = seg->fileoff + (vma & pagemask);
7f307238 2830
c9ffd2ea
TG
2831 /* Set section file offset. */
2832 for (s = seg->sect_head; s != NULL; s = s->next)
7f307238 2833 {
c9ffd2ea
TG
2834 asection *sec = s->bfdsection;
2835 flagword flags = bfd_get_section_flags (abfd, sec);
b22161d6 2836
c9ffd2ea
TG
2837 /* Adjust segment size. */
2838 seg->vmsize = FILE_ALIGN (seg->vmsize, s->align);
2839 seg->vmsize += s->size;
2840
2841 /* File offset and length. */
2842 seg->filesize = FILE_ALIGN (seg->filesize, s->align);
2843
2844 if ((s->flags & BFD_MACH_O_SECTION_TYPE_MASK) != BFD_MACH_O_S_ZEROFILL
07d6d2b8 2845 && ((s->flags & BFD_MACH_O_SECTION_TYPE_MASK)
c9ffd2ea 2846 != BFD_MACH_O_S_GB_ZEROFILL))
b22161d6 2847 {
c9ffd2ea
TG
2848 mdata->filelen = FILE_ALIGN (mdata->filelen, s->align);
2849
2850 s->offset = mdata->filelen;
2851 s->bfdsection->filepos = s->offset;
2852
2853 seg->filesize += s->size;
2854 mdata->filelen += s->size;
b22161d6 2855 }
c9ffd2ea 2856 else
b22161d6 2857 {
c9ffd2ea
TG
2858 s->offset = 0;
2859 s->bfdsection->filepos = 0;
2860 }
2861
2862 /* Set protection. */
2863 if (flags & SEC_LOAD)
2864 {
2865 if (flags & SEC_CODE)
2866 seg->initprot |= BFD_MACH_O_PROT_READ | BFD_MACH_O_PROT_EXECUTE;
2867 if ((flags & (SEC_DATA | SEC_READONLY)) == SEC_DATA)
2868 seg->initprot |= BFD_MACH_O_PROT_WRITE | BFD_MACH_O_PROT_READ;
b22161d6 2869 }
c9ffd2ea
TG
2870
2871 /* Relocs shouldn't appear in non-object files. */
2872 if (s->bfdsection->reloc_count != 0)
2873 return FALSE;
b22161d6 2874 }
c9ffd2ea
TG
2875
2876 /* Set maxprot. */
2877 if (seg->initprot != 0)
2878 seg->maxprot = BFD_MACH_O_PROT_READ | BFD_MACH_O_PROT_WRITE
2879 | BFD_MACH_O_PROT_EXECUTE;
b22161d6 2880 else
c9ffd2ea 2881 seg->maxprot = 0;
b22161d6 2882
c9ffd2ea
TG
2883 /* Round segment size (and file size). */
2884 seg->vmsize = (seg->vmsize + pagemask) & ~pagemask;
2885 seg->filesize = (seg->filesize + pagemask) & ~pagemask;
2886 mdata->filelen = (mdata->filelen + pagemask) & ~pagemask;
7f307238 2887
c9ffd2ea
TG
2888 return TRUE;
2889}
68ffbac6 2890
c9ffd2ea
TG
2891/* Layout the commands: set commands size and offset, set ncmds and sizeofcmds
2892 fields in header. */
68ffbac6 2893
86eafac0 2894static bfd_boolean
c9ffd2ea
TG
2895bfd_mach_o_layout_commands (bfd_mach_o_data_struct *mdata)
2896{
2897 unsigned wide = mach_o_wide_p (&mdata->header);
2898 unsigned int hdrlen;
2899 ufile_ptr offset;
2900 bfd_mach_o_load_command *cmd;
2901 unsigned int align;
86eafac0 2902 bfd_boolean ret = TRUE;
c9ffd2ea
TG
2903
2904 hdrlen = wide ? BFD_MACH_O_HEADER_64_SIZE : BFD_MACH_O_HEADER_SIZE;
2905 align = wide ? 8 - 1 : 4 - 1;
2906 offset = hdrlen;
2907 mdata->header.ncmds = 0;
50d10658 2908
c9ffd2ea
TG
2909 for (cmd = mdata->first_command; cmd; cmd = cmd->next)
2910 {
2911 mdata->header.ncmds++;
2912 cmd->offset = offset;
68ffbac6 2913
c9ffd2ea
TG
2914 switch (cmd->type)
2915 {
2916 case BFD_MACH_O_LC_SEGMENT_64:
2917 cmd->len = BFD_MACH_O_LC_SEGMENT_64_SIZE
2918 + BFD_MACH_O_SECTION_64_SIZE * cmd->command.segment.nsects;
2919 break;
2920 case BFD_MACH_O_LC_SEGMENT:
2921 cmd->len = BFD_MACH_O_LC_SEGMENT_SIZE
2922 + BFD_MACH_O_SECTION_SIZE * cmd->command.segment.nsects;
2923 break;
2924 case BFD_MACH_O_LC_SYMTAB:
2925 cmd->len = sizeof (struct mach_o_symtab_command_external)
2926 + BFD_MACH_O_LC_SIZE;
2927 break;
2928 case BFD_MACH_O_LC_DYSYMTAB:
2929 cmd->len = sizeof (struct mach_o_dysymtab_command_external)
2930 + BFD_MACH_O_LC_SIZE;
2931 break;
2932 case BFD_MACH_O_LC_LOAD_DYLIB:
2933 cmd->len = sizeof (struct mach_o_dylib_command_external)
2934 + BFD_MACH_O_LC_SIZE;
2935 cmd->command.dylib.name_offset = cmd->len;
2936 cmd->len += strlen (cmd->command.dylib.name_str);
2937 cmd->len = (cmd->len + align) & ~align;
2938 break;
2939 case BFD_MACH_O_LC_LOAD_DYLINKER:
2940 cmd->len = sizeof (struct mach_o_str_command_external)
2941 + BFD_MACH_O_LC_SIZE;
2942 cmd->command.dylinker.name_offset = cmd->len;
2943 cmd->len += strlen (cmd->command.dylinker.name_str);
2944 cmd->len = (cmd->len + align) & ~align;
2945 break;
2946 case BFD_MACH_O_LC_MAIN:
2947 cmd->len = sizeof (struct mach_o_entry_point_command_external)
2948 + BFD_MACH_O_LC_SIZE;
2949 break;
2950 case BFD_MACH_O_LC_DYLD_INFO:
2951 cmd->len = sizeof (struct mach_o_dyld_info_command_external)
2952 + BFD_MACH_O_LC_SIZE;
2953 break;
2954 default:
4eca0228 2955 _bfd_error_handler
d42c267e
AM
2956 (_("unable to layout unknown load command %#x"),
2957 cmd->type);
86eafac0 2958 ret = FALSE;
c9ffd2ea 2959 break;
7f307238 2960 }
c9ffd2ea
TG
2961
2962 BFD_ASSERT (cmd->len % (align + 1) == 0);
2963 offset += cmd->len;
7f307238 2964 }
c9ffd2ea
TG
2965 mdata->header.sizeofcmds = offset - hdrlen;
2966 mdata->filelen = offset;
86eafac0
NC
2967
2968 return ret;
c9ffd2ea 2969}
7f307238 2970
c9ffd2ea
TG
2971/* Subroutine of bfd_mach_o_build_commands: set type, name and nsects of a
2972 segment. */
2973
2974static void
2975bfd_mach_o_init_segment (bfd_mach_o_data_struct *mdata,
2976 bfd_mach_o_load_command *cmd,
2977 const char *segname, unsigned int nbr_sect)
2978{
2979 bfd_mach_o_segment_command *seg = &cmd->command.segment;
2980 unsigned wide = mach_o_wide_p (&mdata->header);
2981
2982 /* Init segment command. */
2983 cmd->type = wide ? BFD_MACH_O_LC_SEGMENT_64 : BFD_MACH_O_LC_SEGMENT;
2984 cmd->type_required = FALSE;
2985
2986 strcpy (seg->segname, segname);
2987 seg->nsects = nbr_sect;
2988
2989 seg->vmaddr = 0;
2990 seg->vmsize = 0;
2991
2992 seg->fileoff = 0;
2993 seg->filesize = 0;
2994 seg->maxprot = 0;
2995 seg->initprot = 0;
2996 seg->flags = 0;
2997 seg->sect_head = NULL;
2998 seg->sect_tail = NULL;
7f307238
IS
2999}
3000
3001/* Build Mach-O load commands (currently assuming an MH_OBJECT file).
3002 TODO: Other file formats, rebuilding symtab/dysymtab commands for strip
3003 and copy functionality. */
154a1ee5
TG
3004
3005bfd_boolean
3006bfd_mach_o_build_commands (bfd *abfd)
3007{
046b007d 3008 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
bbd56171 3009 unsigned wide = mach_o_wide_p (&mdata->header);
c9ffd2ea
TG
3010 unsigned int nbr_segcmd = 0;
3011 bfd_mach_o_load_command *commands;
3012 unsigned int nbr_commands;
bbd56171
IS
3013 int symtab_idx = -1;
3014 int dysymtab_idx = -1;
c9ffd2ea
TG
3015 int main_idx = -1;
3016 unsigned int i;
154a1ee5 3017
c9ffd2ea
TG
3018 /* Return now if already built. */
3019 if (mdata->header.ncmds != 0)
3020 return TRUE;
154a1ee5 3021
7f307238 3022 /* Fill in the file type, if not already set. */
7f307238 3023 if (mdata->header.filetype == 0)
154a1ee5 3024 {
7f307238 3025 if (abfd->flags & EXEC_P)
07d6d2b8 3026 mdata->header.filetype = BFD_MACH_O_MH_EXECUTE;
7f307238 3027 else if (abfd->flags & DYNAMIC)
07d6d2b8 3028 mdata->header.filetype = BFD_MACH_O_MH_DYLIB;
7f307238 3029 else
07d6d2b8 3030 mdata->header.filetype = BFD_MACH_O_MH_OBJECT;
154a1ee5 3031 }
7f307238
IS
3032
3033 /* If hasn't already been done, flatten sections list, and sort
3034 if/when required. Must be done before the symbol table is adjusted,
3035 since that depends on properly numbered sections. */
3036 if (mdata->nsects == 0 || mdata->sections == NULL)
3037 if (! bfd_mach_o_mangle_sections (abfd, mdata))
3038 return FALSE;
3039
3040 /* Order the symbol table, fill-in/check mach-o specific fields and
3041 partition out any indirect symbols. */
b22161d6 3042 if (!bfd_mach_o_mangle_symbols (abfd))
7f307238
IS
3043 return FALSE;
3044
c9ffd2ea
TG
3045 /* Segment commands. */
3046 if (mdata->header.filetype == BFD_MACH_O_MH_OBJECT)
3047 {
3048 /* Only one segment for all the sections. But the segment is
3049 optional if there is no sections. */
3050 nbr_segcmd = (mdata->nsects > 0) ? 1 : 0;
3051 }
3052 else
3053 {
3054 bfd_mach_o_section *prev_sect = NULL;
bbd56171 3055
c9ffd2ea
TG
3056 /* One pagezero segment and one linkedit segment. */
3057 nbr_segcmd = 2;
bbd56171 3058
c9ffd2ea
TG
3059 /* Create one segment for associated segment name in sections.
3060 Assume that sections with the same segment name are consecutive. */
3061 for (i = 0; i < mdata->nsects; i++)
3062 {
3063 bfd_mach_o_section *this_sect = mdata->sections[i];
bbd56171 3064
c9ffd2ea
TG
3065 if (prev_sect == NULL
3066 || strcmp (prev_sect->segname, this_sect->segname) != 0)
3067 {
3068 nbr_segcmd++;
3069 prev_sect = this_sect;
3070 }
3071 }
154a1ee5 3072 }
154a1ee5 3073
c9ffd2ea
TG
3074 nbr_commands = nbr_segcmd;
3075
3076 /* One command for the symbol table (only if there are symbols. */
7f307238 3077 if (bfd_get_symcount (abfd) > 0)
c9ffd2ea 3078 symtab_idx = nbr_commands++;
c2f09c75 3079
bbd56171
IS
3080 /* FIXME:
3081 This is a rather crude test for whether we should build a dysymtab. */
3082 if (bfd_mach_o_should_emit_dysymtab ()
3083 && bfd_get_symcount (abfd))
3084 {
bbd56171
IS
3085 /* If there should be a case where a dysymtab could be emitted without
3086 a symtab (seems improbable), this would need amending. */
c9ffd2ea 3087 dysymtab_idx = nbr_commands++;
bbd56171 3088 }
154a1ee5 3089
c9ffd2ea
TG
3090 /* Add an entry point command. */
3091 if (mdata->header.filetype == BFD_MACH_O_MH_EXECUTE
3092 && bfd_get_start_address (abfd) != 0)
3093 main_idx = nbr_commands++;
c2f09c75 3094
bbd56171 3095 /* Well, we must have a header, at least. */
c9ffd2ea 3096 mdata->filelen = wide ? BFD_MACH_O_HEADER_64_SIZE : BFD_MACH_O_HEADER_SIZE;
f1bde64c 3097
bbd56171 3098 /* A bit unusual, but no content is valid;
7f307238 3099 as -n empty.s -o empty.o */
c9ffd2ea
TG
3100 if (nbr_commands == 0)
3101 {
3102 /* Layout commands (well none...) and set headers command fields. */
86eafac0 3103 return bfd_mach_o_layout_commands (mdata);
c9ffd2ea 3104 }
f1bde64c 3105
c9ffd2ea
TG
3106 /* Create commands for segments (and symtabs), prepend them. */
3107 commands = bfd_zalloc (abfd, nbr_commands * sizeof (bfd_mach_o_load_command));
3108 if (commands == NULL)
7f307238 3109 return FALSE;
c9ffd2ea
TG
3110 for (i = 0; i < nbr_commands - 1; i++)
3111 commands[i].next = &commands[i + 1];
3112 commands[nbr_commands - 1].next = mdata->first_command;
3113 if (mdata->first_command == NULL)
3114 mdata->last_command = &commands[nbr_commands - 1];
3115 mdata->first_command = &commands[0];
3116
3117 if (mdata->header.filetype == BFD_MACH_O_MH_OBJECT && nbr_segcmd != 0)
3118 {
3119 /* For object file, there is only one segment. */
3120 bfd_mach_o_init_segment (mdata, &commands[0], "", mdata->nsects);
3121 }
3122 else if (nbr_segcmd != 0)
68ffbac6 3123 {
c9ffd2ea 3124 bfd_mach_o_load_command *cmd;
7f307238 3125
c9ffd2ea 3126 BFD_ASSERT (nbr_segcmd >= 2);
7f307238 3127
c9ffd2ea
TG
3128 /* The pagezero. */
3129 cmd = &commands[0];
3130 bfd_mach_o_init_segment (mdata, cmd, "__PAGEZERO", 0);
3131
3132 /* Segments from sections. */
3133 cmd++;
3134 for (i = 0; i < mdata->nsects;)
7f307238 3135 {
c9ffd2ea
TG
3136 const char *segname = mdata->sections[i]->segname;
3137 unsigned int nbr_sect = 1;
3138
3139 /* Count number of sections for this segment. */
3140 for (i++; i < mdata->nsects; i++)
3141 if (strcmp (mdata->sections[i]->segname, segname) == 0)
3142 nbr_sect++;
3143 else
3144 break;
3145
3146 bfd_mach_o_init_segment (mdata, cmd, segname, nbr_sect);
3147 cmd++;
7f307238 3148 }
bbd56171 3149
c9ffd2ea
TG
3150 /* The linkedit. */
3151 bfd_mach_o_init_segment (mdata, cmd, "__LINKEDIT", 0);
7f307238 3152 }
f1bde64c 3153
bbd56171 3154 if (symtab_idx >= 0)
7f307238
IS
3155 {
3156 /* Init symtab command. */
c9ffd2ea 3157 bfd_mach_o_load_command *cmd = &commands[symtab_idx];
68ffbac6 3158
bbd56171 3159 cmd->type = BFD_MACH_O_LC_SYMTAB;
bbd56171 3160 cmd->type_required = FALSE;
7f307238 3161 }
154a1ee5 3162
bbd56171
IS
3163 /* If required, setup symtab command, see comment above about the quality
3164 of this test. */
3165 if (dysymtab_idx >= 0)
7f307238 3166 {
c9ffd2ea 3167 bfd_mach_o_load_command *cmd = &commands[dysymtab_idx];
bbd56171 3168
7f307238 3169 cmd->type = BFD_MACH_O_LC_DYSYMTAB;
7f307238 3170 cmd->type_required = FALSE;
c9ffd2ea
TG
3171 }
3172
3173 /* Create the main command. */
3174 if (main_idx >= 0)
3175 {
3176 bfd_mach_o_load_command *cmd = &commands[main_idx];
7f307238 3177
c9ffd2ea
TG
3178 cmd->type = BFD_MACH_O_LC_MAIN;
3179 cmd->type_required = TRUE;
3180
3181 cmd->command.main.entryoff = 0;
3182 cmd->command.main.stacksize = 0;
154a1ee5 3183 }
154a1ee5 3184
c9ffd2ea 3185 /* Layout commands. */
86eafac0
NC
3186 if (! bfd_mach_o_layout_commands (mdata))
3187 return FALSE;
c9ffd2ea 3188
7f307238
IS
3189 /* So, now we have sized the commands and the filelen set to that.
3190 Now we can build the segment command and set the section file offsets. */
c9ffd2ea
TG
3191 if (mdata->header.filetype == BFD_MACH_O_MH_OBJECT)
3192 {
3193 for (i = 0; i < nbr_segcmd; i++)
3194 if (!bfd_mach_o_build_obj_seg_command
3195 (abfd, &commands[i].command.segment))
3196 return FALSE;
3197 }
3198 else
3199 {
3200 bfd_vma maxvma = 0;
7f307238 3201
c9ffd2ea
TG
3202 /* Skip pagezero and linkedit segments. */
3203 for (i = 1; i < nbr_segcmd - 1; i++)
3204 {
3205 bfd_mach_o_segment_command *seg = &commands[i].command.segment;
3206
3207 if (!bfd_mach_o_build_exec_seg_command (abfd, seg))
3208 return FALSE;
3209
3210 if (seg->vmaddr + seg->vmsize > maxvma)
3211 maxvma = seg->vmaddr + seg->vmsize;
3212 }
3213
3214 /* Set the size of __PAGEZERO. */
3215 commands[0].command.segment.vmsize =
3216 commands[1].command.segment.vmaddr;
3217
3218 /* Set the vma and fileoff of __LINKEDIT. */
3219 commands[nbr_segcmd - 1].command.segment.vmaddr = maxvma;
3220 commands[nbr_segcmd - 1].command.segment.fileoff = mdata->filelen;
3221
3222 /* Set entry point (once segments have been laid out). */
3223 if (main_idx >= 0)
3224 commands[main_idx].command.main.entryoff =
3225 bfd_get_start_address (abfd) - commands[1].command.segment.vmaddr;
3226 }
7f307238 3227
154a1ee5
TG
3228 return TRUE;
3229}
3230
3231/* Set the contents of a section. */
3232
3233bfd_boolean
3234bfd_mach_o_set_section_contents (bfd *abfd,
3235 asection *section,
3236 const void * location,
3237 file_ptr offset,
3238 bfd_size_type count)
3239{
3240 file_ptr pos;
3241
7f307238
IS
3242 /* Trying to write the first section contents will trigger the creation of
3243 the load commands if they are not already present. */
c9ffd2ea 3244 if (!abfd->output_has_begun && !bfd_mach_o_build_commands (abfd))
154a1ee5
TG
3245 return FALSE;
3246
3247 if (count == 0)
3248 return TRUE;
3249
3250 pos = section->filepos + offset;
3251 if (bfd_seek (abfd, pos, SEEK_SET) != 0
3252 || bfd_bwrite (location, count, abfd) != count)
3253 return FALSE;
3254
3255 return TRUE;
3256}
3257
3258int
116c20d2 3259bfd_mach_o_sizeof_headers (bfd *a ATTRIBUTE_UNUSED,
a6b96beb 3260 struct bfd_link_info *info ATTRIBUTE_UNUSED)
3af9a47b
NC
3261{
3262 return 0;
3263}
3264
3265/* Make an empty symbol. This is required only because
3266 bfd_make_section_anyway wants to create a symbol for the section. */
3267
154a1ee5 3268asymbol *
116c20d2 3269bfd_mach_o_make_empty_symbol (bfd *abfd)
3af9a47b 3270{
d3ce72d0
NC
3271 asymbol *new_symbol;
3272
3273 new_symbol = bfd_zalloc (abfd, sizeof (bfd_mach_o_asymbol));
3274 if (new_symbol == NULL)
3275 return new_symbol;
3276 new_symbol->the_bfd = abfd;
b22161d6 3277 new_symbol->udata.i = SYM_MACHO_FIELDS_UNSET;
d3ce72d0 3278 return new_symbol;
3af9a47b
NC
3279}
3280
154a1ee5 3281static bfd_boolean
47daa70f 3282bfd_mach_o_read_header (bfd *abfd, file_ptr hdr_off, bfd_mach_o_header *header)
3af9a47b 3283{
46d1c23b 3284 struct mach_o_header_external raw;
1e8a024a 3285 unsigned int size;
edeb6e24 3286 bfd_vma (*get32) (const void *) = NULL;
3af9a47b 3287
1e8a024a 3288 /* Just read the magic number. */
47daa70f 3289 if (bfd_seek (abfd, hdr_off, SEEK_SET) != 0
46d1c23b 3290 || bfd_bread (raw.magic, sizeof (raw.magic), abfd) != 4)
154a1ee5 3291 return FALSE;
3af9a47b 3292
46d1c23b 3293 if (bfd_getb32 (raw.magic) == BFD_MACH_O_MH_MAGIC)
3af9a47b
NC
3294 {
3295 header->byteorder = BFD_ENDIAN_BIG;
154a1ee5 3296 header->magic = BFD_MACH_O_MH_MAGIC;
1e8a024a 3297 header->version = 1;
3af9a47b
NC
3298 get32 = bfd_getb32;
3299 }
46d1c23b 3300 else if (bfd_getl32 (raw.magic) == BFD_MACH_O_MH_MAGIC)
3af9a47b 3301 {
a95a4550 3302 header->byteorder = BFD_ENDIAN_LITTLE;
154a1ee5 3303 header->magic = BFD_MACH_O_MH_MAGIC;
1e8a024a
TG
3304 header->version = 1;
3305 get32 = bfd_getl32;
3306 }
46d1c23b 3307 else if (bfd_getb32 (raw.magic) == BFD_MACH_O_MH_MAGIC_64)
1e8a024a
TG
3308 {
3309 header->byteorder = BFD_ENDIAN_BIG;
154a1ee5 3310 header->magic = BFD_MACH_O_MH_MAGIC_64;
1e8a024a
TG
3311 header->version = 2;
3312 get32 = bfd_getb32;
3313 }
46d1c23b 3314 else if (bfd_getl32 (raw.magic) == BFD_MACH_O_MH_MAGIC_64)
1e8a024a
TG
3315 {
3316 header->byteorder = BFD_ENDIAN_LITTLE;
154a1ee5 3317 header->magic = BFD_MACH_O_MH_MAGIC_64;
1e8a024a 3318 header->version = 2;
3af9a47b
NC
3319 get32 = bfd_getl32;
3320 }
3321 else
3322 {
3323 header->byteorder = BFD_ENDIAN_UNKNOWN;
154a1ee5 3324 return FALSE;
3af9a47b 3325 }
a95a4550 3326
1e8a024a 3327 /* Once the size of the header is known, read the full header. */
c2f09c75 3328 size = mach_o_wide_p (header) ?
154a1ee5 3329 BFD_MACH_O_HEADER_64_SIZE : BFD_MACH_O_HEADER_SIZE;
1e8a024a 3330
47daa70f 3331 if (bfd_seek (abfd, hdr_off, SEEK_SET) != 0
46d1c23b 3332 || bfd_bread (&raw, size, abfd) != size)
154a1ee5 3333 return FALSE;
1e8a024a 3334
46d1c23b
TG
3335 header->cputype = (*get32) (raw.cputype);
3336 header->cpusubtype = (*get32) (raw.cpusubtype);
3337 header->filetype = (*get32) (raw.filetype);
3338 header->ncmds = (*get32) (raw.ncmds);
3339 header->sizeofcmds = (*get32) (raw.sizeofcmds);
3340 header->flags = (*get32) (raw.flags);
3af9a47b 3341
c2f09c75 3342 if (mach_o_wide_p (header))
46d1c23b 3343 header->reserved = (*get32) (raw.reserved);
facf03f2
TG
3344 else
3345 header->reserved = 0;
1e8a024a 3346
154a1ee5 3347 return TRUE;
3af9a47b
NC
3348}
3349
f1bde64c
TG
3350bfd_boolean
3351bfd_mach_o_new_section_hook (bfd *abfd, asection *sec)
3352{
3353 bfd_mach_o_section *s;
a4551119 3354 unsigned bfdalign = bfd_get_section_alignment (abfd, sec);
f1bde64c
TG
3355
3356 s = bfd_mach_o_get_mach_o_section (sec);
3357 if (s == NULL)
3358 {
3359 flagword bfd_flags;
a4551119 3360 static const mach_o_section_name_xlat * xlat;
f1bde64c
TG
3361
3362 s = (bfd_mach_o_section *) bfd_zalloc (abfd, sizeof (*s));
3363 if (s == NULL)
3364 return FALSE;
3365 sec->used_by_bfd = s;
3366 s->bfdsection = sec;
3367
a4551119
TG
3368 /* Create the Darwin seg/sect name pair from the bfd name.
3369 If this is a canonical name for which a specific paiting exists
3370 there will also be defined flags, type, attribute and alignment
3371 values. */
3372 xlat = bfd_mach_o_convert_section_name_to_mach_o (abfd, sec, s);
3373 if (xlat != NULL)
3374 {
3375 s->flags = xlat->macho_sectype | xlat->macho_secattr;
68ffbac6 3376 s->align = xlat->sectalign > bfdalign ? xlat->sectalign
a4551119 3377 : bfdalign;
a253d456 3378 (void) bfd_set_section_alignment (abfd, sec, s->align);
a4551119
TG
3379 bfd_flags = bfd_get_section_flags (abfd, sec);
3380 if (bfd_flags == SEC_NO_FLAGS)
3381 bfd_set_section_flags (abfd, sec, xlat->bfd_flags);
3382 }
f1bde64c 3383 else
a4551119
TG
3384 /* Create default flags. */
3385 bfd_mach_o_set_section_flags_from_bfd (abfd, sec);
f1bde64c
TG
3386 }
3387
3388 return _bfd_generic_new_section_hook (abfd, sec);
3389}
3390
3391static void
3392bfd_mach_o_init_section_from_mach_o (bfd *abfd, asection *sec,
07d6d2b8 3393 unsigned long prot)
3af9a47b 3394{
117ed4f8 3395 flagword flags;
f1bde64c 3396 bfd_mach_o_section *section;
3af9a47b 3397
f1bde64c
TG
3398 flags = bfd_get_section_flags (abfd, sec);
3399 section = bfd_mach_o_get_mach_o_section (sec);
3af9a47b 3400
a4551119
TG
3401 /* TODO: see if we should use the xlat system for doing this by
3402 preference and fall back to this for unknown sections. */
3403
8462aec7 3404 if (flags == SEC_NO_FLAGS)
ef17cb22 3405 {
8462aec7
TG
3406 /* Try to guess flags. */
3407 if (section->flags & BFD_MACH_O_S_ATTR_DEBUG)
07d6d2b8 3408 flags = SEC_DEBUGGING;
8462aec7 3409 else
07d6d2b8
AM
3410 {
3411 flags = SEC_ALLOC;
3412 if ((section->flags & BFD_MACH_O_SECTION_TYPE_MASK)
3413 != BFD_MACH_O_S_ZEROFILL)
3414 {
3415 flags |= SEC_LOAD;
3416 if (prot & BFD_MACH_O_PROT_EXECUTE)
3417 flags |= SEC_CODE;
3418 if (prot & BFD_MACH_O_PROT_WRITE)
3419 flags |= SEC_DATA;
3420 else if (prot & BFD_MACH_O_PROT_READ)
3421 flags |= SEC_READONLY;
3422 }
3423 }
ef17cb22 3424 }
15e1c58a
TG
3425 else
3426 {
8462aec7 3427 if ((flags & SEC_DEBUGGING) == 0)
07d6d2b8 3428 flags |= SEC_ALLOC;
15e1c58a 3429 }
8462aec7
TG
3430
3431 if (section->offset != 0)
3432 flags |= SEC_HAS_CONTENTS;
92bc0e80
TG
3433 if (section->nreloc != 0)
3434 flags |= SEC_RELOC;
3435
f1bde64c
TG
3436 bfd_set_section_flags (abfd, sec, flags);
3437
3438 sec->vma = section->addr;
3439 sec->lma = section->addr;
3440 sec->size = section->size;
3441 sec->filepos = section->offset;
3442 sec->alignment_power = section->align;
3443 sec->segment_mark = 0;
3444 sec->reloc_count = section->nreloc;
3445 sec->rel_filepos = section->reloff;
3446}
3447
3448static asection *
3449bfd_mach_o_make_bfd_section (bfd *abfd,
07d6d2b8
AM
3450 const unsigned char *segname,
3451 const unsigned char *sectname)
f1bde64c
TG
3452{
3453 const char *sname;
3454 flagword flags;
a95a4550 3455
f1bde64c
TG
3456 bfd_mach_o_convert_section_name_to_bfd
3457 (abfd, (const char *)segname, (const char *)sectname, &sname, &flags);
3458 if (sname == NULL)
3459 return NULL;
3af9a47b 3460
f1bde64c 3461 return bfd_make_section_anyway_with_flags (abfd, sname, flags);
3af9a47b
NC
3462}
3463
f1bde64c 3464static asection *
47daa70f 3465bfd_mach_o_read_section_32 (bfd *abfd, unsigned long prot)
3af9a47b 3466{
46d1c23b 3467 struct mach_o_section_32_external raw;
f1bde64c
TG
3468 asection *sec;
3469 bfd_mach_o_section *section;
3af9a47b 3470
47daa70f
TG
3471 if (bfd_bread (&raw, BFD_MACH_O_SECTION_SIZE, abfd)
3472 != BFD_MACH_O_SECTION_SIZE)
f1bde64c 3473 return NULL;
a95a4550 3474
5a5cbf72 3475 sec = bfd_mach_o_make_bfd_section (abfd, raw.segname, raw.sectname);
f1bde64c
TG
3476 if (sec == NULL)
3477 return NULL;
3478
3479 section = bfd_mach_o_get_mach_o_section (sec);
3480 memcpy (section->segname, raw.segname, sizeof (raw.segname));
3481 section->segname[BFD_MACH_O_SEGNAME_SIZE] = 0;
3482 memcpy (section->sectname, raw.sectname, sizeof (raw.sectname));
69499dca 3483 section->sectname[BFD_MACH_O_SECTNAME_SIZE] = 0;
46d1c23b
TG
3484 section->addr = bfd_h_get_32 (abfd, raw.addr);
3485 section->size = bfd_h_get_32 (abfd, raw.size);
3486 section->offset = bfd_h_get_32 (abfd, raw.offset);
3487 section->align = bfd_h_get_32 (abfd, raw.align);
c86934ce
NC
3488 /* PR 17512: file: 0017eb76. */
3489 if (section->align > 64)
3490 {
4eca0228 3491 _bfd_error_handler
d42c267e 3492 (_("bfd_mach_o_read_section_32: overlarge alignment value: %#lx, "
4eca0228 3493 "using 32 instead"), section->align);
c86934ce
NC
3494 section->align = 32;
3495 }
46d1c23b
TG
3496 section->reloff = bfd_h_get_32 (abfd, raw.reloff);
3497 section->nreloc = bfd_h_get_32 (abfd, raw.nreloc);
3498 section->flags = bfd_h_get_32 (abfd, raw.flags);
3499 section->reserved1 = bfd_h_get_32 (abfd, raw.reserved1);
3500 section->reserved2 = bfd_h_get_32 (abfd, raw.reserved2);
1e8a024a 3501 section->reserved3 = 0;
1e8a024a 3502
f1bde64c 3503 bfd_mach_o_init_section_from_mach_o (abfd, sec, prot);
1e8a024a 3504
f1bde64c 3505 return sec;
1e8a024a
TG
3506}
3507
f1bde64c 3508static asection *
47daa70f 3509bfd_mach_o_read_section_64 (bfd *abfd, unsigned long prot)
1e8a024a 3510{
46d1c23b 3511 struct mach_o_section_64_external raw;
f1bde64c
TG
3512 asection *sec;
3513 bfd_mach_o_section *section;
1e8a024a 3514
47daa70f
TG
3515 if (bfd_bread (&raw, BFD_MACH_O_SECTION_64_SIZE, abfd)
3516 != BFD_MACH_O_SECTION_64_SIZE)
f1bde64c
TG
3517 return NULL;
3518
5a5cbf72 3519 sec = bfd_mach_o_make_bfd_section (abfd, raw.segname, raw.sectname);
f1bde64c
TG
3520 if (sec == NULL)
3521 return NULL;
1e8a024a 3522
f1bde64c
TG
3523 section = bfd_mach_o_get_mach_o_section (sec);
3524 memcpy (section->segname, raw.segname, sizeof (raw.segname));
3525 section->segname[BFD_MACH_O_SEGNAME_SIZE] = 0;
3526 memcpy (section->sectname, raw.sectname, sizeof (raw.sectname));
69499dca 3527 section->sectname[BFD_MACH_O_SECTNAME_SIZE] = 0;
46d1c23b
TG
3528 section->addr = bfd_h_get_64 (abfd, raw.addr);
3529 section->size = bfd_h_get_64 (abfd, raw.size);
3530 section->offset = bfd_h_get_32 (abfd, raw.offset);
3531 section->align = bfd_h_get_32 (abfd, raw.align);
c86934ce
NC
3532 if (section->align > 64)
3533 {
4eca0228 3534 _bfd_error_handler
d42c267e 3535 (_("bfd_mach_o_read_section_64: overlarge alignment value: %#lx, "
4eca0228 3536 "using 32 instead"), section->align);
c86934ce
NC
3537 section->align = 32;
3538 }
46d1c23b
TG
3539 section->reloff = bfd_h_get_32 (abfd, raw.reloff);
3540 section->nreloc = bfd_h_get_32 (abfd, raw.nreloc);
3541 section->flags = bfd_h_get_32 (abfd, raw.flags);
3542 section->reserved1 = bfd_h_get_32 (abfd, raw.reserved1);
3543 section->reserved2 = bfd_h_get_32 (abfd, raw.reserved2);
3544 section->reserved3 = bfd_h_get_32 (abfd, raw.reserved3);
3af9a47b 3545
f1bde64c 3546 bfd_mach_o_init_section_from_mach_o (abfd, sec, prot);
3af9a47b 3547
f1bde64c 3548 return sec;
3af9a47b
NC
3549}
3550
f1bde64c 3551static asection *
47daa70f 3552bfd_mach_o_read_section (bfd *abfd, unsigned long prot, unsigned int wide)
1e8a024a
TG
3553{
3554 if (wide)
47daa70f 3555 return bfd_mach_o_read_section_64 (abfd, prot);
1e8a024a 3556 else
47daa70f 3557 return bfd_mach_o_read_section_32 (abfd, prot);
1e8a024a
TG
3558}
3559
afbb9e17 3560static bfd_boolean
ab273af8 3561bfd_mach_o_read_symtab_symbol (bfd *abfd,
07d6d2b8
AM
3562 bfd_mach_o_symtab_command *sym,
3563 bfd_mach_o_asymbol *s,
3564 unsigned long i)
3af9a47b 3565{
046b007d 3566 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
c2f09c75 3567 unsigned int wide = mach_o_wide_p (&mdata->header);
046b007d
TG
3568 unsigned int symwidth =
3569 wide ? BFD_MACH_O_NLIST_64_SIZE : BFD_MACH_O_NLIST_SIZE;
92bc0e80 3570 unsigned int symoff = sym->symoff + (i * symwidth);
46d1c23b 3571 struct mach_o_nlist_64_external raw;
3af9a47b
NC
3572 unsigned char type = -1;
3573 unsigned char section = -1;
3574 short desc = -1;
1e8a024a 3575 symvalue value = -1;
3af9a47b
NC
3576 unsigned long stroff = -1;
3577 unsigned int symtype = -1;
3578
3579 BFD_ASSERT (sym->strtab != NULL);
3580
c2f09c75 3581 if (bfd_seek (abfd, symoff, SEEK_SET) != 0
46d1c23b 3582 || bfd_bread (&raw, symwidth, abfd) != symwidth)
3af9a47b 3583 {
4eca0228 3584 _bfd_error_handler
695344c0 3585 /* xgettext:c-format */
07d6d2b8
AM
3586 (_("bfd_mach_o_read_symtab_symbol: unable to read %d bytes at %u"),
3587 symwidth, symoff);
afbb9e17 3588 return FALSE;
3af9a47b
NC
3589 }
3590
46d1c23b
TG
3591 stroff = bfd_h_get_32 (abfd, raw.n_strx);
3592 type = bfd_h_get_8 (abfd, raw.n_type);
c2f09c75 3593 symtype = type & BFD_MACH_O_N_TYPE;
46d1c23b
TG
3594 section = bfd_h_get_8 (abfd, raw.n_sect);
3595 desc = bfd_h_get_16 (abfd, raw.n_desc);
1e8a024a 3596 if (wide)
46d1c23b 3597 value = bfd_h_get_64 (abfd, raw.n_value);
1e8a024a 3598 else
46d1c23b 3599 value = bfd_h_get_32 (abfd, raw.n_value);
3af9a47b
NC
3600
3601 if (stroff >= sym->strsize)
3602 {
4eca0228 3603 _bfd_error_handler
695344c0 3604 /* xgettext:c-format */
07d6d2b8
AM
3605 (_("bfd_mach_o_read_symtab_symbol: name out of range (%lu >= %u)"),
3606 stroff,
3607 sym->strsize);
afbb9e17 3608 return FALSE;
3af9a47b
NC
3609 }
3610
92bc0e80
TG
3611 s->symbol.the_bfd = abfd;
3612 s->symbol.name = sym->strtab + stroff;
3613 s->symbol.value = value;
3614 s->symbol.flags = 0x0;
b22161d6 3615 s->symbol.udata.i = i;
92bc0e80
TG
3616 s->n_type = type;
3617 s->n_sect = section;
3618 s->n_desc = desc;
3af9a47b
NC
3619
3620 if (type & BFD_MACH_O_N_STAB)
3621 {
92bc0e80
TG
3622 s->symbol.flags |= BSF_DEBUGGING;
3623 s->symbol.section = bfd_und_section_ptr;
15e1c58a
TG
3624 switch (type)
3625 {
3626 case N_FUN:
3627 case N_STSYM:
3628 case N_LCSYM:
3629 case N_BNSYM:
3630 case N_SLINE:
3631 case N_ENSYM:
3632 case N_ECOMM:
3633 case N_ECOML:
3634 case N_GSYM:
3635 if ((section > 0) && (section <= mdata->nsects))
3636 {
92bc0e80
TG
3637 s->symbol.section = mdata->sections[section - 1]->bfdsection;
3638 s->symbol.value =
07d6d2b8 3639 s->symbol.value - mdata->sections[section - 1]->addr;
15e1c58a
TG
3640 }
3641 break;
3642 }
3af9a47b
NC
3643 }
3644 else
3645 {
b22161d6 3646 if (type & (BFD_MACH_O_N_PEXT | BFD_MACH_O_N_EXT))
92bc0e80 3647 s->symbol.flags |= BSF_GLOBAL;
b22161d6 3648 else
92bc0e80 3649 s->symbol.flags |= BSF_LOCAL;
3af9a47b
NC
3650
3651 switch (symtype)
3652 {
3653 case BFD_MACH_O_N_UNDF:
07d6d2b8
AM
3654 if (type == (BFD_MACH_O_N_UNDF | BFD_MACH_O_N_EXT)
3655 && s->symbol.value != 0)
3656 {
3657 /* A common symbol. */
3658 s->symbol.section = bfd_com_section_ptr;
3659 s->symbol.flags = BSF_NO_FLAGS;
3660 }
3661 else
3662 {
3663 s->symbol.section = bfd_und_section_ptr;
3664 if (s->n_desc & BFD_MACH_O_N_WEAK_REF)
3665 s->symbol.flags |= BSF_WEAK;
3666 }
3af9a47b
NC
3667 break;
3668 case BFD_MACH_O_N_PBUD:
92bc0e80 3669 s->symbol.section = bfd_und_section_ptr;
3af9a47b
NC
3670 break;
3671 case BFD_MACH_O_N_ABS:
92bc0e80 3672 s->symbol.section = bfd_abs_section_ptr;
3af9a47b
NC
3673 break;
3674 case BFD_MACH_O_N_SECT:
3675 if ((section > 0) && (section <= mdata->nsects))
3676 {
92bc0e80
TG
3677 s->symbol.section = mdata->sections[section - 1]->bfdsection;
3678 s->symbol.value =
07d6d2b8 3679 s->symbol.value - mdata->sections[section - 1]->addr;
3af9a47b
NC
3680 }
3681 else
3682 {
3683 /* Mach-O uses 0 to mean "no section"; not an error. */
3684 if (section != 0)
3685 {
4eca0228 3686 _bfd_error_handler
695344c0 3687 /* xgettext:c-format */
4eca0228
AM
3688 (_("bfd_mach_o_read_symtab_symbol: "
3689 "symbol \"%s\" specified invalid section %d (max %lu): "
3690 "setting to undefined"),
3691 s->symbol.name, section, mdata->nsects);
3af9a47b 3692 }
92bc0e80 3693 s->symbol.section = bfd_und_section_ptr;
3af9a47b
NC
3694 }
3695 break;
3696 case BFD_MACH_O_N_INDR:
0596a831
TG
3697 /* FIXME: we don't follow the BFD convention as this indirect symbol
3698 won't be followed by the referenced one. This looks harmless
3699 unless we start using the linker. */
3700 s->symbol.flags |= BSF_INDIRECT;
3701 s->symbol.section = bfd_ind_section_ptr;
3702 s->symbol.value = 0;
3af9a47b
NC
3703 break;
3704 default:
4eca0228 3705 _bfd_error_handler
695344c0 3706 /* xgettext:c-format */
4eca0228
AM
3707 (_("bfd_mach_o_read_symtab_symbol: "
3708 "symbol \"%s\" specified invalid type field 0x%x: "
3709 "setting to undefined"), s->symbol.name, symtype);
92bc0e80 3710 s->symbol.section = bfd_und_section_ptr;
3af9a47b
NC
3711 break;
3712 }
3713 }
3714
afbb9e17 3715 return TRUE;
3af9a47b
NC
3716}
3717
c5012cd8 3718bfd_boolean
ab273af8 3719bfd_mach_o_read_symtab_strtab (bfd *abfd)
3af9a47b 3720{
046b007d
TG
3721 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3722 bfd_mach_o_symtab_command *sym = mdata->symtab;
3723
3724 /* Fail if there is no symtab. */
3725 if (sym == NULL)
afbb9e17 3726 return FALSE;
046b007d
TG
3727
3728 /* Success if already loaded. */
3729 if (sym->strtab)
afbb9e17 3730 return TRUE;
3af9a47b
NC
3731
3732 if (abfd->flags & BFD_IN_MEMORY)
3733 {
3734 struct bfd_in_memory *b;
3735
3736 b = (struct bfd_in_memory *) abfd->iostream;
3737
3738 if ((sym->stroff + sym->strsize) > b->size)
3739 {
3740 bfd_set_error (bfd_error_file_truncated);
afbb9e17 3741 return FALSE;
3af9a47b 3742 }
f075ee0c 3743 sym->strtab = (char *) b->buffer + sym->stroff;
3af9a47b 3744 }
046b007d 3745 else
3af9a47b 3746 {
8bdf0be1
NC
3747 /* See PR 21840 for a reproducer. */
3748 if ((sym->strsize + 1) == 0)
3749 return FALSE;
e7287c7f 3750 sym->strtab = bfd_alloc (abfd, sym->strsize + 1);
046b007d 3751 if (sym->strtab == NULL)
07d6d2b8 3752 return FALSE;
046b007d
TG
3753
3754 if (bfd_seek (abfd, sym->stroff, SEEK_SET) != 0
07d6d2b8
AM
3755 || bfd_bread (sym->strtab, sym->strsize, abfd) != sym->strsize)
3756 {
a1165289
NC
3757 /* PR 17512: file: 10888-1609-0.004. */
3758 bfd_release (abfd, sym->strtab);
3759 sym->strtab = NULL;
07d6d2b8
AM
3760 bfd_set_error (bfd_error_file_truncated);
3761 return FALSE;
3762 }
e7287c7f
NC
3763 /* Zero terminate the string table. */
3764 sym->strtab[sym->strsize] = 0;
3af9a47b
NC
3765 }
3766
afbb9e17 3767 return TRUE;
3af9a47b
NC
3768}
3769
c5012cd8 3770bfd_boolean
ab273af8 3771bfd_mach_o_read_symtab_symbols (bfd *abfd)
3af9a47b 3772{
046b007d
TG
3773 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3774 bfd_mach_o_symtab_command *sym = mdata->symtab;
3af9a47b 3775 unsigned long i;
3af9a47b 3776
092d27ff 3777 if (sym == NULL || sym->symbols)
0a9d414a
NC
3778 /* Return now if there are no symbols or if already loaded. */
3779 return TRUE;
046b007d 3780
64d29018 3781 sym->symbols = bfd_alloc2 (abfd, sym->nsyms, sizeof (bfd_mach_o_asymbol));
3af9a47b
NC
3782 if (sym->symbols == NULL)
3783 {
4eca0228
AM
3784 _bfd_error_handler (_("bfd_mach_o_read_symtab_symbols: "
3785 "unable to allocate memory for symbols"));
64d29018 3786 sym->nsyms = 0;
afbb9e17 3787 return FALSE;
3af9a47b 3788 }
a95a4550 3789
afbb9e17 3790 if (!bfd_mach_o_read_symtab_strtab (abfd))
64d29018 3791 goto fail;
3af9a47b
NC
3792
3793 for (i = 0; i < sym->nsyms; i++)
64d29018
NC
3794 if (!bfd_mach_o_read_symtab_symbol (abfd, sym, &sym->symbols[i], i))
3795 goto fail;
a95a4550 3796
afbb9e17 3797 return TRUE;
64d29018
NC
3798
3799 fail:
3800 bfd_release (abfd, sym->symbols);
3801 sym->symbols = NULL;
3802 sym->nsyms = 0;
3803 return FALSE;
3af9a47b
NC
3804}
3805
3806static const char *
116c20d2 3807bfd_mach_o_i386_flavour_string (unsigned int flavour)
3af9a47b
NC
3808{
3809 switch ((int) flavour)
3810 {
15e1c58a
TG
3811 case BFD_MACH_O_x86_THREAD_STATE32: return "x86_THREAD_STATE32";
3812 case BFD_MACH_O_x86_FLOAT_STATE32: return "x86_FLOAT_STATE32";
3813 case BFD_MACH_O_x86_EXCEPTION_STATE32: return "x86_EXCEPTION_STATE32";
3814 case BFD_MACH_O_x86_THREAD_STATE64: return "x86_THREAD_STATE64";
3815 case BFD_MACH_O_x86_FLOAT_STATE64: return "x86_FLOAT_STATE64";
3816 case BFD_MACH_O_x86_EXCEPTION_STATE64: return "x86_EXCEPTION_STATE64";
3817 case BFD_MACH_O_x86_THREAD_STATE: return "x86_THREAD_STATE";
3818 case BFD_MACH_O_x86_FLOAT_STATE: return "x86_FLOAT_STATE";
3819 case BFD_MACH_O_x86_EXCEPTION_STATE: return "x86_EXCEPTION_STATE";
3820 case BFD_MACH_O_x86_DEBUG_STATE32: return "x86_DEBUG_STATE32";
3821 case BFD_MACH_O_x86_DEBUG_STATE64: return "x86_DEBUG_STATE64";
3822 case BFD_MACH_O_x86_DEBUG_STATE: return "x86_DEBUG_STATE";
b32e07d7 3823 case BFD_MACH_O_x86_THREAD_STATE_NONE: return "x86_THREAD_STATE_NONE";
3af9a47b
NC
3824 default: return "UNKNOWN";
3825 }
3826}
3827
3828static const char *
116c20d2 3829bfd_mach_o_ppc_flavour_string (unsigned int flavour)
3af9a47b
NC
3830{
3831 switch ((int) flavour)
3832 {
b32e07d7
TG
3833 case BFD_MACH_O_PPC_THREAD_STATE: return "PPC_THREAD_STATE";
3834 case BFD_MACH_O_PPC_FLOAT_STATE: return "PPC_FLOAT_STATE";
3835 case BFD_MACH_O_PPC_EXCEPTION_STATE: return "PPC_EXCEPTION_STATE";
3836 case BFD_MACH_O_PPC_VECTOR_STATE: return "PPC_VECTOR_STATE";
3837 case BFD_MACH_O_PPC_THREAD_STATE64: return "PPC_THREAD_STATE64";
3838 case BFD_MACH_O_PPC_EXCEPTION_STATE64: return "PPC_EXCEPTION_STATE64";
3af9a47b
NC
3839 default: return "UNKNOWN";
3840 }
3841}
3842
452216ab 3843static bfd_boolean
ab273af8 3844bfd_mach_o_read_dylinker (bfd *abfd, bfd_mach_o_load_command *command)
3af9a47b
NC
3845{
3846 bfd_mach_o_dylinker_command *cmd = &command->command.dylinker;
46d1c23b 3847 struct mach_o_str_command_external raw;
3af9a47b 3848 unsigned int nameoff;
4525c51a 3849 unsigned int namelen;
3af9a47b 3850
47daa70f 3851 if (bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
452216ab 3852 return FALSE;
3af9a47b 3853
46d1c23b 3854 nameoff = bfd_h_get_32 (abfd, raw.str);
3af9a47b 3855
4525c51a
TG
3856 cmd->name_offset = nameoff;
3857 namelen = command->len - nameoff;
3858 nameoff += command->offset;
3859 cmd->name_str = bfd_alloc (abfd, namelen);
b32e07d7 3860 if (cmd->name_str == NULL)
452216ab 3861 return FALSE;
4525c51a
TG
3862 if (bfd_seek (abfd, nameoff, SEEK_SET) != 0
3863 || bfd_bread (cmd->name_str, namelen, abfd) != namelen)
452216ab
TG
3864 return FALSE;
3865 return TRUE;
3af9a47b
NC
3866}
3867
452216ab 3868static bfd_boolean
ab273af8 3869bfd_mach_o_read_dylib (bfd *abfd, bfd_mach_o_load_command *command)
3af9a47b 3870{
47daa70f 3871 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3af9a47b 3872 bfd_mach_o_dylib_command *cmd = &command->command.dylib;
46d1c23b 3873 struct mach_o_dylib_command_external raw;
3af9a47b 3874 unsigned int nameoff;
4525c51a 3875 unsigned int namelen;
3af9a47b 3876
046b007d
TG
3877 switch (command->type)
3878 {
3879 case BFD_MACH_O_LC_LOAD_DYLIB:
fbe383b9 3880 case BFD_MACH_O_LC_LAZY_LOAD_DYLIB:
046b007d 3881 case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
046b007d 3882 case BFD_MACH_O_LC_ID_DYLIB:
046b007d 3883 case BFD_MACH_O_LC_REEXPORT_DYLIB:
73017762 3884 case BFD_MACH_O_LC_LOAD_UPWARD_DYLIB:
046b007d
TG
3885 break;
3886 default:
b32e07d7 3887 BFD_FAIL ();
452216ab 3888 return FALSE;
046b007d 3889 }
3af9a47b 3890
47daa70f 3891 if (bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
452216ab 3892 return FALSE;
3af9a47b 3893
46d1c23b
TG
3894 nameoff = bfd_h_get_32 (abfd, raw.name);
3895 cmd->timestamp = bfd_h_get_32 (abfd, raw.timestamp);
3896 cmd->current_version = bfd_h_get_32 (abfd, raw.current_version);
3897 cmd->compatibility_version = bfd_h_get_32 (abfd, raw.compatibility_version);
3af9a47b
NC
3898
3899 cmd->name_offset = command->offset + nameoff;
4525c51a
TG
3900 namelen = command->len - nameoff;
3901 cmd->name_str = bfd_alloc (abfd, namelen);
b32e07d7 3902 if (cmd->name_str == NULL)
452216ab 3903 return FALSE;
47daa70f 3904 if (bfd_seek (abfd, mdata->hdr_offset + cmd->name_offset, SEEK_SET) != 0
4525c51a 3905 || bfd_bread (cmd->name_str, namelen, abfd) != namelen)
452216ab
TG
3906 return FALSE;
3907 return TRUE;
3af9a47b
NC
3908}
3909
452216ab 3910static bfd_boolean
7a79c514 3911bfd_mach_o_read_prebound_dylib (bfd *abfd,
07d6d2b8 3912 bfd_mach_o_load_command *command)
3af9a47b 3913{
7a79c514
TG
3914 bfd_mach_o_prebound_dylib_command *cmd = &command->command.prebound_dylib;
3915 struct mach_o_prebound_dylib_command_external raw;
3916 unsigned int nameoff;
3917 unsigned int modoff;
3918 unsigned int str_len;
3919 unsigned char *str;
3920
47daa70f 3921 if (bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
452216ab 3922 return FALSE;
7a79c514
TG
3923
3924 nameoff = bfd_h_get_32 (abfd, raw.name);
3925 modoff = bfd_h_get_32 (abfd, raw.linked_modules);
3926 if (nameoff > command->len || modoff > command->len)
452216ab 3927 return FALSE;
7a79c514
TG
3928
3929 str_len = command->len - sizeof (raw);
3930 str = bfd_alloc (abfd, str_len);
3931 if (str == NULL)
452216ab 3932 return FALSE;
7a79c514 3933 if (bfd_bread (str, str_len, abfd) != str_len)
452216ab 3934 return FALSE;
7a79c514
TG
3935
3936 cmd->name_offset = command->offset + nameoff;
3937 cmd->nmodules = bfd_h_get_32 (abfd, raw.nmodules);
3938 cmd->linked_modules_offset = command->offset + modoff;
3939
3940 cmd->name_str = (char *)str + nameoff - (sizeof (raw) + BFD_MACH_O_LC_SIZE);
3941 cmd->linked_modules = str + modoff - (sizeof (raw) + BFD_MACH_O_LC_SIZE);
452216ab 3942 return TRUE;
7a79c514
TG
3943}
3944
452216ab 3945static bfd_boolean
7a79c514
TG
3946bfd_mach_o_read_prebind_cksum (bfd *abfd,
3947 bfd_mach_o_load_command *command)
3948{
3949 bfd_mach_o_prebind_cksum_command *cmd = &command->command.prebind_cksum;
3950 struct mach_o_prebind_cksum_command_external raw;
3af9a47b 3951
47daa70f 3952 if (bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
452216ab 3953 return FALSE;
7a79c514
TG
3954
3955 cmd->cksum = bfd_get_32 (abfd, raw.cksum);
452216ab 3956 return TRUE;
7a79c514
TG
3957}
3958
452216ab 3959static bfd_boolean
7a79c514
TG
3960bfd_mach_o_read_twolevel_hints (bfd *abfd,
3961 bfd_mach_o_load_command *command)
3962{
3963 bfd_mach_o_twolevel_hints_command *cmd = &command->command.twolevel_hints;
3964 struct mach_o_twolevel_hints_command_external raw;
3965
47daa70f 3966 if (bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
452216ab 3967 return FALSE;
7a79c514
TG
3968
3969 cmd->offset = bfd_get_32 (abfd, raw.offset);
3970 cmd->nhints = bfd_get_32 (abfd, raw.nhints);
452216ab 3971 return TRUE;
3af9a47b
NC
3972}
3973
452216ab 3974static bfd_boolean
9f4a5bd1
TG
3975bfd_mach_o_read_fvmlib (bfd *abfd, bfd_mach_o_load_command *command)
3976{
3977 bfd_mach_o_fvmlib_command *fvm = &command->command.fvmlib;
3978 struct mach_o_fvmlib_command_external raw;
3979 unsigned int nameoff;
4525c51a 3980 unsigned int namelen;
9f4a5bd1 3981
47daa70f 3982 if (bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
452216ab 3983 return FALSE;
9f4a5bd1
TG
3984
3985 nameoff = bfd_h_get_32 (abfd, raw.name);
3986 fvm->minor_version = bfd_h_get_32 (abfd, raw.minor_version);
3987 fvm->header_addr = bfd_h_get_32 (abfd, raw.header_addr);
3988
3989 fvm->name_offset = command->offset + nameoff;
4525c51a
TG
3990 namelen = command->len - nameoff;
3991 fvm->name_str = bfd_alloc (abfd, namelen);
9f4a5bd1 3992 if (fvm->name_str == NULL)
452216ab 3993 return FALSE;
9f4a5bd1 3994 if (bfd_seek (abfd, fvm->name_offset, SEEK_SET) != 0
4525c51a 3995 || bfd_bread (fvm->name_str, namelen, abfd) != namelen)
452216ab
TG
3996 return FALSE;
3997 return TRUE;
9f4a5bd1
TG
3998}
3999
452216ab 4000static bfd_boolean
ab273af8 4001bfd_mach_o_read_thread (bfd *abfd, bfd_mach_o_load_command *command)
3af9a47b 4002{
b32e07d7 4003 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3af9a47b 4004 bfd_mach_o_thread_command *cmd = &command->command.thread;
92bc0e80 4005 unsigned int offset;
3af9a47b
NC
4006 unsigned int nflavours;
4007 unsigned int i;
4008
4009 BFD_ASSERT ((command->type == BFD_MACH_O_LC_THREAD)
4010 || (command->type == BFD_MACH_O_LC_UNIXTHREAD));
4011
b32e07d7 4012 /* Count the number of threads. */
3af9a47b
NC
4013 offset = 8;
4014 nflavours = 0;
4015 while (offset != command->len)
4016 {
46d1c23b
TG
4017 struct mach_o_thread_command_external raw;
4018
3af9a47b 4019 if (offset >= command->len)
452216ab 4020 return FALSE;
3af9a47b 4021
c2f09c75 4022 if (bfd_seek (abfd, command->offset + offset, SEEK_SET) != 0
07d6d2b8 4023 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
452216ab 4024 return FALSE;
3af9a47b 4025
46d1c23b 4026 offset += sizeof (raw) + bfd_h_get_32 (abfd, raw.count) * 4;
3af9a47b
NC
4027 nflavours++;
4028 }
4029
b32e07d7 4030 /* Allocate threads. */
64d29018
NC
4031 cmd->flavours = bfd_alloc2
4032 (abfd, nflavours, sizeof (bfd_mach_o_thread_flavour));
3af9a47b 4033 if (cmd->flavours == NULL)
452216ab 4034 return FALSE;
3af9a47b
NC
4035 cmd->nflavours = nflavours;
4036
4037 offset = 8;
4038 nflavours = 0;
4039 while (offset != command->len)
4040 {
46d1c23b
TG
4041 struct mach_o_thread_command_external raw;
4042
3af9a47b 4043 if (offset >= command->len)
452216ab 4044 return FALSE;
3af9a47b
NC
4045
4046 if (nflavours >= cmd->nflavours)
452216ab 4047 return FALSE;
3af9a47b 4048
c2f09c75 4049 if (bfd_seek (abfd, command->offset + offset, SEEK_SET) != 0
07d6d2b8 4050 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
452216ab 4051 return FALSE;
3af9a47b 4052
46d1c23b
TG
4053 cmd->flavours[nflavours].flavour = bfd_h_get_32 (abfd, raw.flavour);
4054 cmd->flavours[nflavours].offset = command->offset + offset + sizeof (raw);
4055 cmd->flavours[nflavours].size = bfd_h_get_32 (abfd, raw.count) * 4;
4056 offset += cmd->flavours[nflavours].size + sizeof (raw);
3af9a47b
NC
4057 nflavours++;
4058 }
4059
4060 for (i = 0; i < nflavours; i++)
4061 {
4062 asection *bfdsec;
4063 unsigned int snamelen;
4064 char *sname;
4065 const char *flavourstr;
4066 const char *prefix = "LC_THREAD";
a95a4550
AM
4067 unsigned int j = 0;
4068
3af9a47b
NC
4069 switch (mdata->header.cputype)
4070 {
4071 case BFD_MACH_O_CPU_TYPE_POWERPC:
1e8a024a 4072 case BFD_MACH_O_CPU_TYPE_POWERPC_64:
707e555b
TG
4073 flavourstr =
4074 bfd_mach_o_ppc_flavour_string (cmd->flavours[i].flavour);
3af9a47b
NC
4075 break;
4076 case BFD_MACH_O_CPU_TYPE_I386:
1e8a024a 4077 case BFD_MACH_O_CPU_TYPE_X86_64:
707e555b
TG
4078 flavourstr =
4079 bfd_mach_o_i386_flavour_string (cmd->flavours[i].flavour);
3af9a47b
NC
4080 break;
4081 default:
4082 flavourstr = "UNKNOWN_ARCHITECTURE";
4083 break;
4084 }
a95a4550 4085
3af9a47b 4086 snamelen = strlen (prefix) + 1 + 20 + 1 + strlen (flavourstr) + 1;
116c20d2 4087 sname = bfd_alloc (abfd, snamelen);
3af9a47b 4088 if (sname == NULL)
452216ab 4089 return FALSE;
3af9a47b
NC
4090
4091 for (;;)
4092 {
a95a4550
AM
4093 sprintf (sname, "%s.%s.%u", prefix, flavourstr, j);
4094 if (bfd_get_section_by_name (abfd, sname) == NULL)
3af9a47b 4095 break;
a95a4550 4096 j++;
3af9a47b
NC
4097 }
4098
117ed4f8 4099 bfdsec = bfd_make_section_with_flags (abfd, sname, SEC_HAS_CONTENTS);
a95a4550 4100
3af9a47b
NC
4101 bfdsec->vma = 0;
4102 bfdsec->lma = 0;
eea6121a 4103 bfdsec->size = cmd->flavours[i].size;
3af9a47b
NC
4104 bfdsec->filepos = cmd->flavours[i].offset;
4105 bfdsec->alignment_power = 0x0;
3af9a47b
NC
4106
4107 cmd->section = bfdsec;
4108 }
4109
452216ab 4110 return TRUE;
3af9a47b
NC
4111}
4112
452216ab 4113static bfd_boolean
ab273af8 4114bfd_mach_o_read_dysymtab (bfd *abfd, bfd_mach_o_load_command *command)
3af9a47b 4115{
046b007d 4116 bfd_mach_o_dysymtab_command *cmd = &command->command.dysymtab;
b32e07d7 4117 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3af9a47b
NC
4118
4119 BFD_ASSERT (command->type == BFD_MACH_O_LC_DYSYMTAB);
4120
46d1c23b
TG
4121 {
4122 struct mach_o_dysymtab_command_external raw;
4123
47daa70f 4124 if (bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
452216ab 4125 return FALSE;
3af9a47b 4126
46d1c23b
TG
4127 cmd->ilocalsym = bfd_h_get_32 (abfd, raw.ilocalsym);
4128 cmd->nlocalsym = bfd_h_get_32 (abfd, raw.nlocalsym);
4129 cmd->iextdefsym = bfd_h_get_32 (abfd, raw.iextdefsym);
4130 cmd->nextdefsym = bfd_h_get_32 (abfd, raw.nextdefsym);
4131 cmd->iundefsym = bfd_h_get_32 (abfd, raw.iundefsym);
4132 cmd->nundefsym = bfd_h_get_32 (abfd, raw.nundefsym);
4133 cmd->tocoff = bfd_h_get_32 (abfd, raw.tocoff);
4134 cmd->ntoc = bfd_h_get_32 (abfd, raw.ntoc);
4135 cmd->modtaboff = bfd_h_get_32 (abfd, raw.modtaboff);
4136 cmd->nmodtab = bfd_h_get_32 (abfd, raw.nmodtab);
4137 cmd->extrefsymoff = bfd_h_get_32 (abfd, raw.extrefsymoff);
4138 cmd->nextrefsyms = bfd_h_get_32 (abfd, raw.nextrefsyms);
4139 cmd->indirectsymoff = bfd_h_get_32 (abfd, raw.indirectsymoff);
4140 cmd->nindirectsyms = bfd_h_get_32 (abfd, raw.nindirectsyms);
4141 cmd->extreloff = bfd_h_get_32 (abfd, raw.extreloff);
4142 cmd->nextrel = bfd_h_get_32 (abfd, raw.nextrel);
4143 cmd->locreloff = bfd_h_get_32 (abfd, raw.locreloff);
4144 cmd->nlocrel = bfd_h_get_32 (abfd, raw.nlocrel);
4145 }
046b007d
TG
4146
4147 if (cmd->nmodtab != 0)
4148 {
046b007d
TG
4149 unsigned int i;
4150 int wide = bfd_mach_o_wide_p (abfd);
4151 unsigned int module_len = wide ? 56 : 52;
4152
4153 cmd->dylib_module =
07d6d2b8 4154 bfd_alloc2 (abfd, cmd->nmodtab, sizeof (bfd_mach_o_dylib_module));
046b007d 4155 if (cmd->dylib_module == NULL)
07d6d2b8 4156 return FALSE;
046b007d
TG
4157
4158 if (bfd_seek (abfd, cmd->modtaboff, SEEK_SET) != 0)
07d6d2b8 4159 return FALSE;
046b007d
TG
4160
4161 for (i = 0; i < cmd->nmodtab; i++)
07d6d2b8
AM
4162 {
4163 bfd_mach_o_dylib_module *module = &cmd->dylib_module[i];
4164 unsigned long v;
4165 unsigned char buf[56];
4166
4167 if (bfd_bread ((void *) buf, module_len, abfd) != module_len)
4168 return FALSE;
4169
4170 module->module_name_idx = bfd_h_get_32 (abfd, buf + 0);
4171 module->iextdefsym = bfd_h_get_32 (abfd, buf + 4);
4172 module->nextdefsym = bfd_h_get_32 (abfd, buf + 8);
4173 module->irefsym = bfd_h_get_32 (abfd, buf + 12);
4174 module->nrefsym = bfd_h_get_32 (abfd, buf + 16);
4175 module->ilocalsym = bfd_h_get_32 (abfd, buf + 20);
4176 module->nlocalsym = bfd_h_get_32 (abfd, buf + 24);
4177 module->iextrel = bfd_h_get_32 (abfd, buf + 28);
4178 module->nextrel = bfd_h_get_32 (abfd, buf + 32);
4179 v = bfd_h_get_32 (abfd, buf +36);
4180 module->iinit = v & 0xffff;
4181 module->iterm = (v >> 16) & 0xffff;
4182 v = bfd_h_get_32 (abfd, buf + 40);
4183 module->ninit = v & 0xffff;
4184 module->nterm = (v >> 16) & 0xffff;
4185 if (wide)
4186 {
4187 module->objc_module_info_size = bfd_h_get_32 (abfd, buf + 44);
4188 module->objc_module_info_addr = bfd_h_get_64 (abfd, buf + 48);
4189 }
4190 else
4191 {
4192 module->objc_module_info_addr = bfd_h_get_32 (abfd, buf + 44);
4193 module->objc_module_info_size = bfd_h_get_32 (abfd, buf + 48);
4194 }
4195 }
046b007d 4196 }
afbb9e17 4197
046b007d
TG
4198 if (cmd->ntoc != 0)
4199 {
64d29018 4200 unsigned long i;
046b007d 4201
64d29018 4202 cmd->dylib_toc = bfd_alloc2
07d6d2b8 4203 (abfd, cmd->ntoc, sizeof (bfd_mach_o_dylib_table_of_content));
046b007d 4204 if (cmd->dylib_toc == NULL)
07d6d2b8 4205 return FALSE;
046b007d
TG
4206
4207 if (bfd_seek (abfd, cmd->tocoff, SEEK_SET) != 0)
07d6d2b8 4208 return FALSE;
046b007d
TG
4209
4210 for (i = 0; i < cmd->ntoc; i++)
07d6d2b8
AM
4211 {
4212 struct mach_o_dylib_table_of_contents_external raw;
4213 bfd_mach_o_dylib_table_of_content *toc = &cmd->dylib_toc[i];
046b007d 4214
07d6d2b8
AM
4215 if (bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
4216 return FALSE;
046b007d 4217
07d6d2b8
AM
4218 toc->symbol_index = bfd_h_get_32 (abfd, raw.symbol_index);
4219 toc->module_index = bfd_h_get_32 (abfd, raw.module_index);
4220 }
046b007d
TG
4221 }
4222
4223 if (cmd->nindirectsyms != 0)
4224 {
046b007d
TG
4225 unsigned int i;
4226
64d29018 4227 cmd->indirect_syms = bfd_alloc2
07d6d2b8 4228 (abfd, cmd->nindirectsyms, sizeof (unsigned int));
046b007d 4229 if (cmd->indirect_syms == NULL)
07d6d2b8 4230 return FALSE;
046b007d
TG
4231
4232 if (bfd_seek (abfd, cmd->indirectsymoff, SEEK_SET) != 0)
07d6d2b8 4233 return FALSE;
046b007d
TG
4234
4235 for (i = 0; i < cmd->nindirectsyms; i++)
07d6d2b8
AM
4236 {
4237 unsigned char raw[4];
4238 unsigned int *is = &cmd->indirect_syms[i];
046b007d 4239
07d6d2b8
AM
4240 if (bfd_bread (raw, sizeof (raw), abfd) != sizeof (raw))
4241 return FALSE;
046b007d 4242
07d6d2b8
AM
4243 *is = bfd_h_get_32 (abfd, raw);
4244 }
046b007d
TG
4245 }
4246
4247 if (cmd->nextrefsyms != 0)
4248 {
046b007d
TG
4249 unsigned long v;
4250 unsigned int i;
4251
64d29018 4252 cmd->ext_refs = bfd_alloc2
07d6d2b8 4253 (abfd, cmd->nextrefsyms, sizeof (bfd_mach_o_dylib_reference));
046b007d 4254 if (cmd->ext_refs == NULL)
07d6d2b8 4255 return FALSE;
046b007d
TG
4256
4257 if (bfd_seek (abfd, cmd->extrefsymoff, SEEK_SET) != 0)
07d6d2b8 4258 return FALSE;
046b007d
TG
4259
4260 for (i = 0; i < cmd->nextrefsyms; i++)
07d6d2b8
AM
4261 {
4262 unsigned char raw[4];
4263 bfd_mach_o_dylib_reference *ref = &cmd->ext_refs[i];
4264
4265 if (bfd_bread (raw, sizeof (raw), abfd) != sizeof (raw))
4266 return FALSE;
4267
4268 /* Fields isym and flags are written as bit-fields, thus we need
4269 a specific processing for endianness. */
4270 v = bfd_h_get_32 (abfd, raw);
4271 if (bfd_big_endian (abfd))
4272 {
4273 ref->isym = (v >> 8) & 0xffffff;
4274 ref->flags = v & 0xff;
4275 }
4276 else
4277 {
4278 ref->isym = v & 0xffffff;
4279 ref->flags = (v >> 24) & 0xff;
4280 }
4281 }
046b007d 4282 }
3af9a47b 4283
b32e07d7 4284 if (mdata->dysymtab)
452216ab 4285 return FALSE;
b32e07d7
TG
4286 mdata->dysymtab = cmd;
4287
452216ab 4288 return TRUE;
3af9a47b
NC
4289}
4290
452216ab 4291static bfd_boolean
ab273af8 4292bfd_mach_o_read_symtab (bfd *abfd, bfd_mach_o_load_command *command)
3af9a47b 4293{
046b007d
TG
4294 bfd_mach_o_symtab_command *symtab = &command->command.symtab;
4295 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
46d1c23b 4296 struct mach_o_symtab_command_external raw;
3af9a47b
NC
4297
4298 BFD_ASSERT (command->type == BFD_MACH_O_LC_SYMTAB);
4299
47daa70f 4300 if (bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
452216ab 4301 return FALSE;
a95a4550 4302
46d1c23b
TG
4303 symtab->symoff = bfd_h_get_32 (abfd, raw.symoff);
4304 symtab->nsyms = bfd_h_get_32 (abfd, raw.nsyms);
4305 symtab->stroff = bfd_h_get_32 (abfd, raw.stroff);
4306 symtab->strsize = bfd_h_get_32 (abfd, raw.strsize);
046b007d
TG
4307 symtab->symbols = NULL;
4308 symtab->strtab = NULL;
3af9a47b 4309
046b007d 4310 if (symtab->nsyms != 0)
15e1c58a
TG
4311 abfd->flags |= HAS_SYMS;
4312
046b007d 4313 if (mdata->symtab)
452216ab 4314 return FALSE;
046b007d 4315 mdata->symtab = symtab;
452216ab 4316 return TRUE;
3af9a47b
NC
4317}
4318
452216ab 4319static bfd_boolean
ab273af8 4320bfd_mach_o_read_uuid (bfd *abfd, bfd_mach_o_load_command *command)
15e1c58a
TG
4321{
4322 bfd_mach_o_uuid_command *cmd = &command->command.uuid;
15e1c58a
TG
4323
4324 BFD_ASSERT (command->type == BFD_MACH_O_LC_UUID);
4325
47daa70f 4326 if (bfd_bread (cmd->uuid, 16, abfd) != 16)
452216ab 4327 return FALSE;
15e1c58a 4328
452216ab 4329 return TRUE;
15e1c58a
TG
4330}
4331
452216ab 4332static bfd_boolean
ab273af8 4333bfd_mach_o_read_linkedit (bfd *abfd, bfd_mach_o_load_command *command)
046b007d
TG
4334{
4335 bfd_mach_o_linkedit_command *cmd = &command->command.linkedit;
46d1c23b 4336 struct mach_o_linkedit_data_command_external raw;
046b007d 4337
47daa70f 4338 if (bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
452216ab 4339 return FALSE;
046b007d 4340
46d1c23b
TG
4341 cmd->dataoff = bfd_get_32 (abfd, raw.dataoff);
4342 cmd->datasize = bfd_get_32 (abfd, raw.datasize);
452216ab 4343 return TRUE;
046b007d
TG
4344}
4345
452216ab 4346static bfd_boolean
ab273af8 4347bfd_mach_o_read_str (bfd *abfd, bfd_mach_o_load_command *command)
046b007d
TG
4348{
4349 bfd_mach_o_str_command *cmd = &command->command.str;
46d1c23b 4350 struct mach_o_str_command_external raw;
046b007d
TG
4351 unsigned long off;
4352
47daa70f 4353 if (bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
452216ab 4354 return FALSE;
046b007d 4355
46d1c23b 4356 off = bfd_get_32 (abfd, raw.str);
046b007d
TG
4357 cmd->stroff = command->offset + off;
4358 cmd->str_len = command->len - off;
4359 cmd->str = bfd_alloc (abfd, cmd->str_len);
4360 if (cmd->str == NULL)
452216ab 4361 return FALSE;
046b007d 4362 if (bfd_seek (abfd, cmd->stroff, SEEK_SET) != 0
91d6fa6a 4363 || bfd_bread ((void *) cmd->str, cmd->str_len, abfd) != cmd->str_len)
452216ab
TG
4364 return FALSE;
4365 return TRUE;
046b007d
TG
4366}
4367
c9ffd2ea
TG
4368static unsigned char *
4369bfd_mach_o_alloc_and_read (bfd *abfd, unsigned int off, unsigned int size)
4370{
4371 unsigned char *buf;
4372
4373 buf = bfd_alloc (abfd, size);
4374 if (buf == NULL)
4375 return NULL;
4376 if (bfd_seek (abfd, off, SEEK_SET) != 0
4377 || bfd_bread (buf, size, abfd) != size)
4378 return NULL;
4379 return buf;
4380}
4381
4382static bfd_boolean
4383bfd_mach_o_read_dyld_content (bfd *abfd, bfd_mach_o_dyld_info_command *cmd)
4384{
4385 /* Read rebase content. */
4386 if (cmd->rebase_content == NULL && cmd->rebase_size != 0)
4387 {
4388 cmd->rebase_content =
4389 bfd_mach_o_alloc_and_read (abfd, cmd->rebase_off, cmd->rebase_size);
4390 if (cmd->rebase_content == NULL)
4391 return FALSE;
4392 }
4393
4394 /* Read bind content. */
4395 if (cmd->bind_content == NULL && cmd->bind_size != 0)
4396 {
4397 cmd->bind_content =
4398 bfd_mach_o_alloc_and_read (abfd, cmd->bind_off, cmd->bind_size);
4399 if (cmd->bind_content == NULL)
4400 return FALSE;
4401 }
4402
4403 /* Read weak bind content. */
4404 if (cmd->weak_bind_content == NULL && cmd->weak_bind_size != 0)
4405 {
4406 cmd->weak_bind_content = bfd_mach_o_alloc_and_read
4407 (abfd, cmd->weak_bind_off, cmd->weak_bind_size);
4408 if (cmd->weak_bind_content == NULL)
4409 return FALSE;
4410 }
4411
4412 /* Read lazy bind content. */
4413 if (cmd->lazy_bind_content == NULL && cmd->lazy_bind_size != 0)
4414 {
4415 cmd->lazy_bind_content = bfd_mach_o_alloc_and_read
4416 (abfd, cmd->lazy_bind_off, cmd->lazy_bind_size);
4417 if (cmd->lazy_bind_content == NULL)
4418 return FALSE;
4419 }
4420
4421 /* Read export content. */
4422 if (cmd->export_content == NULL && cmd->export_size != 0)
4423 {
4424 cmd->export_content = bfd_mach_o_alloc_and_read
4425 (abfd, cmd->export_off, cmd->export_size);
4426 if (cmd->export_content == NULL)
4427 return FALSE;
4428 }
4429
4430 return TRUE;
4431}
4432
452216ab 4433static bfd_boolean
ab273af8 4434bfd_mach_o_read_dyld_info (bfd *abfd, bfd_mach_o_load_command *command)
ad86f1fb
TG
4435{
4436 bfd_mach_o_dyld_info_command *cmd = &command->command.dyld_info;
46d1c23b 4437 struct mach_o_dyld_info_command_external raw;
ad86f1fb 4438
47daa70f 4439 if (bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
452216ab 4440 return FALSE;
ad86f1fb 4441
46d1c23b
TG
4442 cmd->rebase_off = bfd_get_32 (abfd, raw.rebase_off);
4443 cmd->rebase_size = bfd_get_32 (abfd, raw.rebase_size);
c9ffd2ea 4444 cmd->rebase_content = NULL;
46d1c23b
TG
4445 cmd->bind_off = bfd_get_32 (abfd, raw.bind_off);
4446 cmd->bind_size = bfd_get_32 (abfd, raw.bind_size);
c9ffd2ea 4447 cmd->bind_content = NULL;
46d1c23b
TG
4448 cmd->weak_bind_off = bfd_get_32 (abfd, raw.weak_bind_off);
4449 cmd->weak_bind_size = bfd_get_32 (abfd, raw.weak_bind_size);
c9ffd2ea 4450 cmd->weak_bind_content = NULL;
46d1c23b
TG
4451 cmd->lazy_bind_off = bfd_get_32 (abfd, raw.lazy_bind_off);
4452 cmd->lazy_bind_size = bfd_get_32 (abfd, raw.lazy_bind_size);
c9ffd2ea 4453 cmd->lazy_bind_content = NULL;
46d1c23b
TG
4454 cmd->export_off = bfd_get_32 (abfd, raw.export_off);
4455 cmd->export_size = bfd_get_32 (abfd, raw.export_size);
c9ffd2ea 4456 cmd->export_content = NULL;
452216ab 4457 return TRUE;
ad86f1fb
TG
4458}
4459
edbdea0e
TG
4460static bfd_boolean
4461bfd_mach_o_read_version_min (bfd *abfd, bfd_mach_o_load_command *command)
4462{
4463 bfd_mach_o_version_min_command *cmd = &command->command.version_min;
4464 struct mach_o_version_min_command_external raw;
4465 unsigned int ver;
4466
47daa70f 4467 if (bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
edbdea0e
TG
4468 return FALSE;
4469
4470 ver = bfd_get_32 (abfd, raw.version);
4471 cmd->rel = ver >> 16;
4472 cmd->maj = ver >> 8;
4473 cmd->min = ver;
4474 cmd->reserved = bfd_get_32 (abfd, raw.reserved);
4475 return TRUE;
4476}
4477
fc55a902
TG
4478static bfd_boolean
4479bfd_mach_o_read_encryption_info (bfd *abfd, bfd_mach_o_load_command *command)
4480{
4481 bfd_mach_o_encryption_info_command *cmd = &command->command.encryption_info;
4482 struct mach_o_encryption_info_command_external raw;
4483
47daa70f
TG
4484 if (bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
4485 return FALSE;
4486
4487 cmd->cryptoff = bfd_get_32 (abfd, raw.cryptoff);
4488 cmd->cryptsize = bfd_get_32 (abfd, raw.cryptsize);
4489 cmd->cryptid = bfd_get_32 (abfd, raw.cryptid);
4490 return TRUE;
4491}
4492
4493static bfd_boolean
4494bfd_mach_o_read_encryption_info_64 (bfd *abfd, bfd_mach_o_load_command *command)
4495{
4496 bfd_mach_o_encryption_info_command *cmd = &command->command.encryption_info;
4497 struct mach_o_encryption_info_64_command_external raw;
4498
4499 if (bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
fc55a902
TG
4500 return FALSE;
4501
4502 cmd->cryptoff = bfd_get_32 (abfd, raw.cryptoff);
4503 cmd->cryptsize = bfd_get_32 (abfd, raw.cryptsize);
4504 cmd->cryptid = bfd_get_32 (abfd, raw.cryptid);
4505 return TRUE;
4506}
4507
1778ad74
TG
4508static bfd_boolean
4509bfd_mach_o_read_main (bfd *abfd, bfd_mach_o_load_command *command)
4510{
4511 bfd_mach_o_main_command *cmd = &command->command.main;
4512 struct mach_o_entry_point_command_external raw;
4513
47daa70f 4514 if (bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
1778ad74
TG
4515 return FALSE;
4516
4517 cmd->entryoff = bfd_get_64 (abfd, raw.entryoff);
4518 cmd->stacksize = bfd_get_64 (abfd, raw.stacksize);
4519 return TRUE;
4520}
4521
4522static bfd_boolean
4523bfd_mach_o_read_source_version (bfd *abfd, bfd_mach_o_load_command *command)
4524{
4525 bfd_mach_o_source_version_command *cmd = &command->command.source_version;
4526 struct mach_o_source_version_command_external raw;
4527 bfd_uint64_t ver;
4528
47daa70f 4529 if (bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
1778ad74
TG
4530 return FALSE;
4531
4532 ver = bfd_get_64 (abfd, raw.version);
4533 /* Note: we use a serie of shift to avoid shift > 32 (for which gcc
4534 generates warnings) in case of the host doesn't support 64 bit
4535 integers. */
4536 cmd->e = ver & 0x3ff;
4537 ver >>= 10;
4538 cmd->d = ver & 0x3ff;
4539 ver >>= 10;
4540 cmd->c = ver & 0x3ff;
4541 ver >>= 10;
4542 cmd->b = ver & 0x3ff;
4543 ver >>= 10;
4544 cmd->a = ver & 0xffffff;
4545 return TRUE;
4546}
4547
452216ab 4548static bfd_boolean
ab273af8 4549bfd_mach_o_read_segment (bfd *abfd,
07d6d2b8
AM
4550 bfd_mach_o_load_command *command,
4551 unsigned int wide)
3af9a47b 4552{
3af9a47b
NC
4553 bfd_mach_o_segment_command *seg = &command->command.segment;
4554 unsigned long i;
a95a4550 4555
1e8a024a
TG
4556 if (wide)
4557 {
46d1c23b
TG
4558 struct mach_o_segment_command_64_external raw;
4559
1e8a024a 4560 BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT_64);
3af9a47b 4561
47daa70f 4562 if (bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
07d6d2b8 4563 return FALSE;
3af9a47b 4564
46d1c23b 4565 memcpy (seg->segname, raw.segname, 16);
15e1c58a 4566 seg->segname[16] = '\0';
1e8a024a 4567
46d1c23b
TG
4568 seg->vmaddr = bfd_h_get_64 (abfd, raw.vmaddr);
4569 seg->vmsize = bfd_h_get_64 (abfd, raw.vmsize);
4570 seg->fileoff = bfd_h_get_64 (abfd, raw.fileoff);
4571 seg->filesize = bfd_h_get_64 (abfd, raw.filesize);
4572 seg->maxprot = bfd_h_get_32 (abfd, raw.maxprot);
4573 seg->initprot = bfd_h_get_32 (abfd, raw.initprot);
4574 seg->nsects = bfd_h_get_32 (abfd, raw.nsects);
4575 seg->flags = bfd_h_get_32 (abfd, raw.flags);
1e8a024a
TG
4576 }
4577 else
4578 {
46d1c23b
TG
4579 struct mach_o_segment_command_32_external raw;
4580
1e8a024a
TG
4581 BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT);
4582
47daa70f 4583 if (bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
07d6d2b8 4584 return FALSE;
1e8a024a 4585
46d1c23b 4586 memcpy (seg->segname, raw.segname, 16);
15e1c58a 4587 seg->segname[16] = '\0';
1e8a024a 4588
46d1c23b
TG
4589 seg->vmaddr = bfd_h_get_32 (abfd, raw.vmaddr);
4590 seg->vmsize = bfd_h_get_32 (abfd, raw.vmsize);
4591 seg->fileoff = bfd_h_get_32 (abfd, raw.fileoff);
4592 seg->filesize = bfd_h_get_32 (abfd, raw.filesize);
4593 seg->maxprot = bfd_h_get_32 (abfd, raw.maxprot);
4594 seg->initprot = bfd_h_get_32 (abfd, raw.initprot);
4595 seg->nsects = bfd_h_get_32 (abfd, raw.nsects);
4596 seg->flags = bfd_h_get_32 (abfd, raw.flags);
1e8a024a 4597 }
9d4b6009
TG
4598 seg->sect_head = NULL;
4599 seg->sect_tail = NULL;
3af9a47b 4600
f1bde64c 4601 for (i = 0; i < seg->nsects; i++)
3af9a47b 4602 {
f1bde64c 4603 asection *sec;
a95a4550 4604
47daa70f 4605 sec = bfd_mach_o_read_section (abfd, seg->initprot, wide);
f1bde64c 4606 if (sec == NULL)
07d6d2b8 4607 return FALSE;
f1bde64c 4608
c9ffd2ea
TG
4609 bfd_mach_o_append_section_to_segment
4610 (seg, bfd_mach_o_get_mach_o_section (sec));
3af9a47b
NC
4611 }
4612
452216ab 4613 return TRUE;
3af9a47b
NC
4614}
4615
452216ab 4616static bfd_boolean
ab273af8 4617bfd_mach_o_read_segment_32 (bfd *abfd, bfd_mach_o_load_command *command)
1e8a024a 4618{
ab273af8 4619 return bfd_mach_o_read_segment (abfd, command, 0);
1e8a024a
TG
4620}
4621
452216ab 4622static bfd_boolean
ab273af8 4623bfd_mach_o_read_segment_64 (bfd *abfd, bfd_mach_o_load_command *command)
1e8a024a 4624{
ab273af8 4625 return bfd_mach_o_read_segment (abfd, command, 1);
1e8a024a
TG
4626}
4627
452216ab 4628static bfd_boolean
ab273af8 4629bfd_mach_o_read_command (bfd *abfd, bfd_mach_o_load_command *command)
3af9a47b 4630{
47daa70f 4631 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
46d1c23b
TG
4632 struct mach_o_load_command_external raw;
4633 unsigned int cmd;
3af9a47b 4634
046b007d 4635 /* Read command type and length. */
47daa70f 4636 if (bfd_seek (abfd, mdata->hdr_offset + command->offset, SEEK_SET) != 0
46d1c23b 4637 || bfd_bread (&raw, BFD_MACH_O_LC_SIZE, abfd) != BFD_MACH_O_LC_SIZE)
452216ab 4638 return FALSE;
3af9a47b 4639
46d1c23b
TG
4640 cmd = bfd_h_get_32 (abfd, raw.cmd);
4641 command->type = cmd & ~BFD_MACH_O_LC_REQ_DYLD;
4642 command->type_required = cmd & BFD_MACH_O_LC_REQ_DYLD ? TRUE : FALSE;
4643 command->len = bfd_h_get_32 (abfd, raw.cmdsize);
3af9a47b
NC
4644
4645 switch (command->type)
4646 {
4647 case BFD_MACH_O_LC_SEGMENT:
452216ab
TG
4648 if (!bfd_mach_o_read_segment_32 (abfd, command))
4649 return FALSE;
1e8a024a
TG
4650 break;
4651 case BFD_MACH_O_LC_SEGMENT_64:
452216ab
TG
4652 if (!bfd_mach_o_read_segment_64 (abfd, command))
4653 return FALSE;
3af9a47b
NC
4654 break;
4655 case BFD_MACH_O_LC_SYMTAB:
452216ab
TG
4656 if (!bfd_mach_o_read_symtab (abfd, command))
4657 return FALSE;
3af9a47b
NC
4658 break;
4659 case BFD_MACH_O_LC_SYMSEG:
4660 break;
4661 case BFD_MACH_O_LC_THREAD:
4662 case BFD_MACH_O_LC_UNIXTHREAD:
452216ab
TG
4663 if (!bfd_mach_o_read_thread (abfd, command))
4664 return FALSE;
3af9a47b
NC
4665 break;
4666 case BFD_MACH_O_LC_LOAD_DYLINKER:
4667 case BFD_MACH_O_LC_ID_DYLINKER:
10be66a4 4668 case BFD_MACH_O_LC_DYLD_ENVIRONMENT:
452216ab
TG
4669 if (!bfd_mach_o_read_dylinker (abfd, command))
4670 return FALSE;
3af9a47b
NC
4671 break;
4672 case BFD_MACH_O_LC_LOAD_DYLIB:
fbe383b9 4673 case BFD_MACH_O_LC_LAZY_LOAD_DYLIB:
3af9a47b
NC
4674 case BFD_MACH_O_LC_ID_DYLIB:
4675 case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
046b007d 4676 case BFD_MACH_O_LC_REEXPORT_DYLIB:
73017762 4677 case BFD_MACH_O_LC_LOAD_UPWARD_DYLIB:
452216ab
TG
4678 if (!bfd_mach_o_read_dylib (abfd, command))
4679 return FALSE;
3af9a47b
NC
4680 break;
4681 case BFD_MACH_O_LC_PREBOUND_DYLIB:
452216ab
TG
4682 if (!bfd_mach_o_read_prebound_dylib (abfd, command))
4683 return FALSE;
3af9a47b
NC
4684 break;
4685 case BFD_MACH_O_LC_LOADFVMLIB:
4686 case BFD_MACH_O_LC_IDFVMLIB:
452216ab
TG
4687 if (!bfd_mach_o_read_fvmlib (abfd, command))
4688 return FALSE;
9f4a5bd1 4689 break;
3af9a47b
NC
4690 case BFD_MACH_O_LC_IDENT:
4691 case BFD_MACH_O_LC_FVMFILE:
4692 case BFD_MACH_O_LC_PREPAGE:
4693 case BFD_MACH_O_LC_ROUTINES:
9b02d212 4694 case BFD_MACH_O_LC_ROUTINES_64:
046b007d 4695 break;
3af9a47b 4696 case BFD_MACH_O_LC_SUB_FRAMEWORK:
046b007d
TG
4697 case BFD_MACH_O_LC_SUB_UMBRELLA:
4698 case BFD_MACH_O_LC_SUB_LIBRARY:
4699 case BFD_MACH_O_LC_SUB_CLIENT:
0c9b2b4c 4700 case BFD_MACH_O_LC_RPATH:
452216ab 4701 if (!bfd_mach_o_read_str (abfd, command))
07d6d2b8 4702 return FALSE;
3af9a47b
NC
4703 break;
4704 case BFD_MACH_O_LC_DYSYMTAB:
452216ab
TG
4705 if (!bfd_mach_o_read_dysymtab (abfd, command))
4706 return FALSE;
3af9a47b 4707 break;
3af9a47b 4708 case BFD_MACH_O_LC_PREBIND_CKSUM:
452216ab
TG
4709 if (!bfd_mach_o_read_prebind_cksum (abfd, command))
4710 return FALSE;
7a79c514
TG
4711 break;
4712 case BFD_MACH_O_LC_TWOLEVEL_HINTS:
452216ab
TG
4713 if (!bfd_mach_o_read_twolevel_hints (abfd, command))
4714 return FALSE;
3af9a47b 4715 break;
15e1c58a 4716 case BFD_MACH_O_LC_UUID:
452216ab
TG
4717 if (!bfd_mach_o_read_uuid (abfd, command))
4718 return FALSE;
15e1c58a
TG
4719 break;
4720 case BFD_MACH_O_LC_CODE_SIGNATURE:
846b9259 4721 case BFD_MACH_O_LC_SEGMENT_SPLIT_INFO:
edbdea0e 4722 case BFD_MACH_O_LC_FUNCTION_STARTS:
1778ad74
TG
4723 case BFD_MACH_O_LC_DATA_IN_CODE:
4724 case BFD_MACH_O_LC_DYLIB_CODE_SIGN_DRS:
47daa70f 4725 case BFD_MACH_O_LC_LINKER_OPTIMIZATION_HINT:
452216ab
TG
4726 if (!bfd_mach_o_read_linkedit (abfd, command))
4727 return FALSE;
15e1c58a 4728 break;
fc55a902
TG
4729 case BFD_MACH_O_LC_ENCRYPTION_INFO:
4730 if (!bfd_mach_o_read_encryption_info (abfd, command))
452216ab 4731 return FALSE;
fc55a902 4732 break;
47daa70f
TG
4733 case BFD_MACH_O_LC_ENCRYPTION_INFO_64:
4734 if (!bfd_mach_o_read_encryption_info_64 (abfd, command))
4735 return FALSE;
4736 break;
ad86f1fb 4737 case BFD_MACH_O_LC_DYLD_INFO:
452216ab
TG
4738 if (!bfd_mach_o_read_dyld_info (abfd, command))
4739 return FALSE;
ad86f1fb 4740 break;
edbdea0e
TG
4741 case BFD_MACH_O_LC_VERSION_MIN_MACOSX:
4742 case BFD_MACH_O_LC_VERSION_MIN_IPHONEOS:
47daa70f 4743 case BFD_MACH_O_LC_VERSION_MIN_WATCHOS:
edbdea0e 4744 if (!bfd_mach_o_read_version_min (abfd, command))
452216ab 4745 return FALSE;
edbdea0e 4746 break;
1778ad74
TG
4747 case BFD_MACH_O_LC_MAIN:
4748 if (!bfd_mach_o_read_main (abfd, command))
452216ab 4749 return FALSE;
1778ad74
TG
4750 break;
4751 case BFD_MACH_O_LC_SOURCE_VERSION:
4752 if (!bfd_mach_o_read_source_version (abfd, command))
452216ab 4753 return FALSE;
1778ad74 4754 break;
3af9a47b 4755 default:
86eafac0 4756 command->len = 0;
871b3ab2 4757 _bfd_error_handler (_("%pB: unknown load command %#x"),
d42c267e 4758 abfd, command->type);
86eafac0 4759 return FALSE;
3af9a47b
NC
4760 }
4761
452216ab 4762 return TRUE;
3af9a47b
NC
4763}
4764
4765static void
116c20d2 4766bfd_mach_o_flatten_sections (bfd *abfd)
3af9a47b 4767{
046b007d 4768 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
c9ffd2ea 4769 bfd_mach_o_load_command *cmd;
3af9a47b 4770 long csect = 0;
a95a4550 4771
15e1c58a 4772 /* Count total number of sections. */
3af9a47b
NC
4773 mdata->nsects = 0;
4774
c9ffd2ea 4775 for (cmd = mdata->first_command; cmd != NULL; cmd = cmd->next)
3af9a47b 4776 {
c9ffd2ea
TG
4777 if (cmd->type == BFD_MACH_O_LC_SEGMENT
4778 || cmd->type == BFD_MACH_O_LC_SEGMENT_64)
3af9a47b 4779 {
c9ffd2ea 4780 bfd_mach_o_segment_command *seg = &cmd->command.segment;
e84d6fca 4781
3af9a47b
NC
4782 mdata->nsects += seg->nsects;
4783 }
4784 }
4785
15e1c58a 4786 /* Allocate sections array. */
64d29018
NC
4787 mdata->sections = bfd_alloc2 (abfd,
4788 mdata->nsects, sizeof (bfd_mach_o_section *));
15e1c58a
TG
4789
4790 /* Fill the array. */
3af9a47b
NC
4791 csect = 0;
4792
c9ffd2ea 4793 for (cmd = mdata->first_command; cmd != NULL; cmd = cmd->next)
3af9a47b 4794 {
c9ffd2ea
TG
4795 if (cmd->type == BFD_MACH_O_LC_SEGMENT
4796 || cmd->type == BFD_MACH_O_LC_SEGMENT_64)
3af9a47b 4797 {
c9ffd2ea 4798 bfd_mach_o_segment_command *seg = &cmd->command.segment;
07d6d2b8 4799 bfd_mach_o_section *sec;
3af9a47b
NC
4800
4801 BFD_ASSERT (csect + seg->nsects <= mdata->nsects);
4802
07d6d2b8 4803 for (sec = seg->sect_head; sec != NULL; sec = sec->next)
f1bde64c 4804 mdata->sections[csect++] = sec;
3af9a47b
NC
4805 }
4806 }
4807}
4808
afbb9e17 4809static bfd_boolean
116c20d2 4810bfd_mach_o_scan_start_address (bfd *abfd)
3af9a47b 4811{
046b007d 4812 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
c9ffd2ea
TG
4813 bfd_mach_o_thread_command *thr = NULL;
4814 bfd_mach_o_load_command *cmd;
3af9a47b
NC
4815 unsigned long i;
4816
c9ffd2ea
TG
4817 for (cmd = mdata->first_command; cmd != NULL; cmd = cmd->next)
4818 if (cmd->type == BFD_MACH_O_LC_THREAD
4819 || cmd->type == BFD_MACH_O_LC_UNIXTHREAD)
afbb9e17 4820 {
07d6d2b8
AM
4821 thr = &cmd->command.thread;
4822 break;
afbb9e17 4823 }
c9ffd2ea 4824 else if (cmd->type == BFD_MACH_O_LC_MAIN && mdata->nsects > 1)
c0fd7846 4825 {
c9ffd2ea 4826 bfd_mach_o_main_command *main_cmd = &cmd->command.main;
c0fd7846 4827 bfd_mach_o_section *text_sect = mdata->sections[0];
c9ffd2ea 4828
c0fd7846
TG
4829 if (text_sect)
4830 {
4831 abfd->start_address = main_cmd->entryoff
4832 + (text_sect->addr - text_sect->offset);
4833 return TRUE;
4834 }
4835 }
3af9a47b 4836
5ee43bc4 4837 /* An object file has no start address, so do not fail if not found. */
c9ffd2ea 4838 if (thr == NULL)
5ee43bc4 4839 return TRUE;
3af9a47b 4840
afbb9e17 4841 /* FIXME: create a subtarget hook ? */
c9ffd2ea 4842 for (i = 0; i < thr->nflavours; i++)
3af9a47b 4843 {
a95a4550 4844 if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_I386)
c9ffd2ea 4845 && (thr->flavours[i].flavour == BFD_MACH_O_x86_THREAD_STATE32))
3af9a47b
NC
4846 {
4847 unsigned char buf[4];
4848
c9ffd2ea 4849 if (bfd_seek (abfd, thr->flavours[i].offset + 40, SEEK_SET) != 0
07d6d2b8 4850 || bfd_bread (buf, 4, abfd) != 4)
afbb9e17 4851 return FALSE;
3af9a47b
NC
4852
4853 abfd->start_address = bfd_h_get_32 (abfd, buf);
4854 }
a95a4550 4855 else if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_POWERPC)
c9ffd2ea 4856 && (thr->flavours[i].flavour == BFD_MACH_O_PPC_THREAD_STATE))
3af9a47b
NC
4857 {
4858 unsigned char buf[4];
4859
c9ffd2ea 4860 if (bfd_seek (abfd, thr->flavours[i].offset + 0, SEEK_SET) != 0
07d6d2b8 4861 || bfd_bread (buf, 4, abfd) != 4)
afbb9e17 4862 return FALSE;
3af9a47b
NC
4863
4864 abfd->start_address = bfd_h_get_32 (abfd, buf);
4865 }
1e8a024a 4866 else if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_POWERPC_64)
07d6d2b8
AM
4867 && (thr->flavours[i].flavour == BFD_MACH_O_PPC_THREAD_STATE64))
4868 {
4869 unsigned char buf[8];
1e8a024a 4870
07d6d2b8
AM
4871 if (bfd_seek (abfd, thr->flavours[i].offset + 0, SEEK_SET) != 0
4872 || bfd_bread (buf, 8, abfd) != 8)
4873 return FALSE;
1e8a024a 4874
07d6d2b8
AM
4875 abfd->start_address = bfd_h_get_64 (abfd, buf);
4876 }
1e8a024a 4877 else if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_X86_64)
07d6d2b8
AM
4878 && (thr->flavours[i].flavour == BFD_MACH_O_x86_THREAD_STATE64))
4879 {
4880 unsigned char buf[8];
1e8a024a 4881
07d6d2b8
AM
4882 if (bfd_seek (abfd, thr->flavours[i].offset + (16 * 8), SEEK_SET) != 0
4883 || bfd_bread (buf, 8, abfd) != 8)
4884 return FALSE;
1e8a024a 4885
07d6d2b8
AM
4886 abfd->start_address = bfd_h_get_64 (abfd, buf);
4887 }
3af9a47b
NC
4888 }
4889
afbb9e17 4890 return TRUE;
3af9a47b
NC
4891}
4892
42fa0891
TG
4893bfd_boolean
4894bfd_mach_o_set_arch_mach (bfd *abfd,
07d6d2b8
AM
4895 enum bfd_architecture arch,
4896 unsigned long machine)
42fa0891
TG
4897{
4898 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
4899
4900 /* If this isn't the right architecture for this backend, and this
4901 isn't the generic backend, fail. */
4902 if (arch != bed->arch
4903 && arch != bfd_arch_unknown
4904 && bed->arch != bfd_arch_unknown)
4905 return FALSE;
4906
4907 return bfd_default_set_arch_mach (abfd, arch, machine);
4908}
4909
afbb9e17 4910static bfd_boolean
116c20d2
NC
4911bfd_mach_o_scan (bfd *abfd,
4912 bfd_mach_o_header *header,
4913 bfd_mach_o_data_struct *mdata)
3af9a47b
NC
4914{
4915 unsigned int i;
3af9a47b
NC
4916 enum bfd_architecture cputype;
4917 unsigned long cpusubtype;
1e8a024a
TG
4918 unsigned int hdrsize;
4919
c2f09c75 4920 hdrsize = mach_o_wide_p (header) ?
154a1ee5 4921 BFD_MACH_O_HEADER_64_SIZE : BFD_MACH_O_HEADER_SIZE;
3af9a47b 4922
3af9a47b 4923 mdata->header = *header;
3af9a47b 4924
154a1ee5 4925 abfd->flags = abfd->flags & BFD_IN_MEMORY;
15e1c58a
TG
4926 switch (header->filetype)
4927 {
4928 case BFD_MACH_O_MH_OBJECT:
4929 abfd->flags |= HAS_RELOC;
4930 break;
4931 case BFD_MACH_O_MH_EXECUTE:
4932 abfd->flags |= EXEC_P;
4933 break;
4934 case BFD_MACH_O_MH_DYLIB:
4935 case BFD_MACH_O_MH_BUNDLE:
4936 abfd->flags |= DYNAMIC;
4937 break;
4938 }
4939
3af9a47b
NC
4940 abfd->tdata.mach_o_data = mdata;
4941
e84d6fca
AM
4942 bfd_mach_o_convert_architecture (header->cputype, header->cpusubtype,
4943 &cputype, &cpusubtype);
3af9a47b
NC
4944 if (cputype == bfd_arch_unknown)
4945 {
4eca0228 4946 _bfd_error_handler
695344c0 4947 /* xgettext:c-format */
07d6d2b8
AM
4948 (_("bfd_mach_o_scan: unknown architecture 0x%lx/0x%lx"),
4949 header->cputype, header->cpusubtype);
afbb9e17 4950 return FALSE;
3af9a47b
NC
4951 }
4952
4953 bfd_set_arch_mach (abfd, cputype, cpusubtype);
a95a4550 4954
3af9a47b
NC
4955 if (header->ncmds != 0)
4956 {
c9ffd2ea
TG
4957 bfd_mach_o_load_command *cmd;
4958
4959 mdata->first_command = NULL;
4960 mdata->last_command = NULL;
64d29018
NC
4961
4962 cmd = bfd_alloc2 (abfd, header->ncmds, sizeof (bfd_mach_o_load_command));
c9ffd2ea 4963 if (cmd == NULL)
afbb9e17 4964 return FALSE;
a95a4550 4965
3af9a47b
NC
4966 for (i = 0; i < header->ncmds; i++)
4967 {
c9ffd2ea
TG
4968 bfd_mach_o_load_command *cur = &cmd[i];
4969
4970 bfd_mach_o_append_command (abfd, cur);
3af9a47b
NC
4971
4972 if (i == 0)
1e8a024a 4973 cur->offset = hdrsize;
3af9a47b
NC
4974 else
4975 {
c9ffd2ea 4976 bfd_mach_o_load_command *prev = &cmd[i - 1];
3af9a47b
NC
4977 cur->offset = prev->offset + prev->len;
4978 }
4979
452216ab 4980 if (!bfd_mach_o_read_command (abfd, cur))
afbb9e17 4981 return FALSE;
a95a4550 4982 }
3af9a47b
NC
4983 }
4984
c0fd7846
TG
4985 /* Sections should be flatten before scanning start address. */
4986 bfd_mach_o_flatten_sections (abfd);
4987 if (!bfd_mach_o_scan_start_address (abfd))
afbb9e17 4988 return FALSE;
3af9a47b 4989
afbb9e17 4990 return TRUE;
3af9a47b
NC
4991}
4992
b34976b6 4993bfd_boolean
154a1ee5 4994bfd_mach_o_mkobject_init (bfd *abfd)
3af9a47b
NC
4995{
4996 bfd_mach_o_data_struct *mdata = NULL;
4997
b30a5d18 4998 mdata = bfd_zalloc (abfd, sizeof (bfd_mach_o_data_struct));
3af9a47b 4999 if (mdata == NULL)
b34976b6 5000 return FALSE;
3af9a47b
NC
5001 abfd->tdata.mach_o_data = mdata;
5002
5003 mdata->header.magic = 0;
5004 mdata->header.cputype = 0;
5005 mdata->header.cpusubtype = 0;
5006 mdata->header.filetype = 0;
5007 mdata->header.ncmds = 0;
5008 mdata->header.sizeofcmds = 0;
5009 mdata->header.flags = 0;
5010 mdata->header.byteorder = BFD_ENDIAN_UNKNOWN;
c9ffd2ea
TG
5011 mdata->first_command = NULL;
5012 mdata->last_command = NULL;
3af9a47b
NC
5013 mdata->nsects = 0;
5014 mdata->sections = NULL;
4434114c 5015 mdata->dyn_reloc_cache = NULL;
3af9a47b 5016
b34976b6 5017 return TRUE;
3af9a47b
NC
5018}
5019
42fa0891
TG
5020static bfd_boolean
5021bfd_mach_o_gen_mkobject (bfd *abfd)
5022{
5023 bfd_mach_o_data_struct *mdata;
5024
5025 if (!bfd_mach_o_mkobject_init (abfd))
5026 return FALSE;
5027
5028 mdata = bfd_mach_o_get_data (abfd);
5029 mdata->header.magic = BFD_MACH_O_MH_MAGIC;
5030 mdata->header.cputype = 0;
5031 mdata->header.cpusubtype = 0;
5032 mdata->header.byteorder = abfd->xvec->byteorder;
5033 mdata->header.version = 1;
5034
5035 return TRUE;
5036}
5037
3af9a47b 5038const bfd_target *
154a1ee5 5039bfd_mach_o_header_p (bfd *abfd,
47daa70f 5040 file_ptr hdr_off,
07d6d2b8
AM
5041 bfd_mach_o_filetype filetype,
5042 bfd_mach_o_cpu_type cputype)
3af9a47b
NC
5043{
5044 bfd_mach_o_header header;
c9ba0c87 5045 bfd_mach_o_data_struct *mdata;
3af9a47b 5046
47daa70f 5047 if (!bfd_mach_o_read_header (abfd, hdr_off, &header))
e84d6fca 5048 goto wrong;
3af9a47b 5049
e84d6fca
AM
5050 if (! (header.byteorder == BFD_ENDIAN_BIG
5051 || header.byteorder == BFD_ENDIAN_LITTLE))
3af9a47b 5052 {
d42c267e
AM
5053 _bfd_error_handler (_("unknown header byte-order value %#x"),
5054 header.byteorder);
e84d6fca 5055 goto wrong;
3af9a47b
NC
5056 }
5057
e84d6fca
AM
5058 if (! ((header.byteorder == BFD_ENDIAN_BIG
5059 && abfd->xvec->byteorder == BFD_ENDIAN_BIG
5060 && abfd->xvec->header_byteorder == BFD_ENDIAN_BIG)
5061 || (header.byteorder == BFD_ENDIAN_LITTLE
5062 && abfd->xvec->byteorder == BFD_ENDIAN_LITTLE
5063 && abfd->xvec->header_byteorder == BFD_ENDIAN_LITTLE)))
5064 goto wrong;
3af9a47b 5065
154a1ee5
TG
5066 /* Check cputype and filetype.
5067 In case of wildcard, do not accept magics that are handled by existing
5068 targets. */
5069 if (cputype)
5070 {
5071 if (header.cputype != cputype)
07d6d2b8 5072 goto wrong;
154a1ee5 5073 }
26954155
TG
5074 else
5075 {
5076#ifndef BFD64
5077 /* Do not recognize 64 architectures if not configured for 64bit targets.
5078 This could happen only for generic targets. */
5079 if (mach_o_wide_p (&header))
5080 goto wrong;
5081#endif
5082 }
b22161d6 5083
154a1ee5
TG
5084 if (filetype)
5085 {
5086 if (header.filetype != filetype)
07d6d2b8 5087 goto wrong;
154a1ee5
TG
5088 }
5089 else
5090 {
5091 switch (header.filetype)
07d6d2b8
AM
5092 {
5093 case BFD_MACH_O_MH_CORE:
5094 /* Handled by core_p */
5095 goto wrong;
5096 default:
5097 break;
5098 }
154a1ee5
TG
5099 }
5100
c9ba0c87
AM
5101 mdata = (bfd_mach_o_data_struct *) bfd_zalloc (abfd, sizeof (*mdata));
5102 if (mdata == NULL)
e84d6fca 5103 goto fail;
47daa70f 5104 mdata->hdr_offset = hdr_off;
3af9a47b 5105
c9ba0c87 5106 if (!bfd_mach_o_scan (abfd, &header, mdata))
e84d6fca 5107 goto wrong;
a95a4550 5108
3af9a47b 5109 return abfd->xvec;
e84d6fca
AM
5110
5111 wrong:
5112 bfd_set_error (bfd_error_wrong_format);
5113
5114 fail:
e84d6fca 5115 return NULL;
3af9a47b
NC
5116}
5117
154a1ee5
TG
5118static const bfd_target *
5119bfd_mach_o_gen_object_p (bfd *abfd)
3af9a47b 5120{
47daa70f 5121 return bfd_mach_o_header_p (abfd, 0, 0, 0);
154a1ee5 5122}
e84d6fca 5123
154a1ee5
TG
5124static const bfd_target *
5125bfd_mach_o_gen_core_p (bfd *abfd)
5126{
47daa70f 5127 return bfd_mach_o_header_p (abfd, 0, BFD_MACH_O_MH_CORE, 0);
3af9a47b
NC
5128}
5129
3cc27770
TG
5130/* Return the base address of ABFD, ie the address at which the image is
5131 mapped. The possible initial pagezero is ignored. */
5132
5133bfd_vma
5134bfd_mach_o_get_base_address (bfd *abfd)
5135{
5136 bfd_mach_o_data_struct *mdata;
c9ffd2ea 5137 bfd_mach_o_load_command *cmd;
3cc27770
TG
5138
5139 /* Check for Mach-O. */
5140 if (!bfd_mach_o_valid (abfd))
5141 return 0;
5142 mdata = bfd_mach_o_get_data (abfd);
5143
c9ffd2ea 5144 for (cmd = mdata->first_command; cmd != NULL; cmd = cmd->next)
3cc27770 5145 {
3cc27770
TG
5146 if ((cmd->type == BFD_MACH_O_LC_SEGMENT
5147 || cmd->type == BFD_MACH_O_LC_SEGMENT_64))
5148 {
5149 struct bfd_mach_o_segment_command *segcmd = &cmd->command.segment;
5150
5151 if (segcmd->initprot != 0)
5152 return segcmd->vmaddr;
5153 }
5154 }
5155 return 0;
5156}
5157
3af9a47b
NC
5158typedef struct mach_o_fat_archentry
5159{
5160 unsigned long cputype;
5161 unsigned long cpusubtype;
5162 unsigned long offset;
5163 unsigned long size;
5164 unsigned long align;
3af9a47b
NC
5165} mach_o_fat_archentry;
5166
5167typedef struct mach_o_fat_data_struct
5168{
5169 unsigned long magic;
5170 unsigned long nfat_arch;
5171 mach_o_fat_archentry *archentries;
5172} mach_o_fat_data_struct;
5173
5174const bfd_target *
47daa70f 5175bfd_mach_o_fat_archive_p (bfd *abfd)
3af9a47b 5176{
e84d6fca 5177 mach_o_fat_data_struct *adata = NULL;
46d1c23b 5178 struct mach_o_fat_header_external hdr;
3af9a47b
NC
5179 unsigned long i;
5180
c2f09c75 5181 if (bfd_seek (abfd, 0, SEEK_SET) != 0
46d1c23b 5182 || bfd_bread (&hdr, sizeof (hdr), abfd) != sizeof (hdr))
e84d6fca 5183 goto error;
3af9a47b 5184
116c20d2 5185 adata = bfd_alloc (abfd, sizeof (mach_o_fat_data_struct));
3af9a47b 5186 if (adata == NULL)
e84d6fca 5187 goto error;
a95a4550 5188
46d1c23b
TG
5189 adata->magic = bfd_getb32 (hdr.magic);
5190 adata->nfat_arch = bfd_getb32 (hdr.nfat_arch);
3af9a47b 5191 if (adata->magic != 0xcafebabe)
e84d6fca 5192 goto error;
27cc28f9
AS
5193 /* Avoid matching Java bytecode files, which have the same magic number.
5194 In the Java bytecode file format this field contains the JVM version,
5195 which starts at 43.0. */
5196 if (adata->nfat_arch > 30)
5197 goto error;
3af9a47b 5198
c2f09c75 5199 adata->archentries =
64d29018 5200 bfd_alloc2 (abfd, adata->nfat_arch, sizeof (mach_o_fat_archentry));
3af9a47b 5201 if (adata->archentries == NULL)
e84d6fca 5202 goto error;
3af9a47b
NC
5203
5204 for (i = 0; i < adata->nfat_arch; i++)
5205 {
46d1c23b
TG
5206 struct mach_o_fat_arch_external arch;
5207 if (bfd_bread (&arch, sizeof (arch), abfd) != sizeof (arch))
e84d6fca 5208 goto error;
46d1c23b
TG
5209 adata->archentries[i].cputype = bfd_getb32 (arch.cputype);
5210 adata->archentries[i].cpusubtype = bfd_getb32 (arch.cpusubtype);
5211 adata->archentries[i].offset = bfd_getb32 (arch.offset);
5212 adata->archentries[i].size = bfd_getb32 (arch.size);
5213 adata->archentries[i].align = bfd_getb32 (arch.align);
3af9a47b
NC
5214 }
5215
5216 abfd->tdata.mach_o_fat_data = adata;
64d29018 5217
3af9a47b 5218 return abfd->xvec;
e84d6fca
AM
5219
5220 error:
5221 if (adata != NULL)
5222 bfd_release (abfd, adata);
5223 bfd_set_error (bfd_error_wrong_format);
5224 return NULL;
3af9a47b
NC
5225}
5226
a4e241ca
TG
5227/* Set the filename for a fat binary member ABFD, whose bfd architecture is
5228 ARCH_TYPE/ARCH_SUBTYPE and corresponding entry in header is ENTRY.
5229 Set arelt_data and origin fields too. */
5230
5231static void
5232bfd_mach_o_fat_member_init (bfd *abfd,
07d6d2b8
AM
5233 enum bfd_architecture arch_type,
5234 unsigned long arch_subtype,
5235 mach_o_fat_archentry *entry)
a4e241ca
TG
5236{
5237 struct areltdata *areltdata;
5238 /* Create the member filename. Use ARCH_NAME. */
5239 const bfd_arch_info_type *ap = bfd_lookup_arch (arch_type, arch_subtype);
5240
5241 if (ap)
5242 {
5243 /* Use the architecture name if known. */
1be5090b 5244 abfd->filename = xstrdup (ap->printable_name);
a4e241ca
TG
5245 }
5246 else
5247 {
5248 /* Forge a uniq id. */
5249 const size_t namelen = 2 + 8 + 1 + 2 + 8 + 1;
1be5090b 5250 char *name = xmalloc (namelen);
a4e241ca 5251 snprintf (name, namelen, "0x%lx-0x%lx",
07d6d2b8 5252 entry->cputype, entry->cpusubtype);
a4e241ca
TG
5253 abfd->filename = name;
5254 }
5255
06e7acd7 5256 areltdata = bfd_zmalloc (sizeof (struct areltdata));
a4e241ca
TG
5257 areltdata->parsed_size = entry->size;
5258 abfd->arelt_data = areltdata;
5259 abfd->iostream = NULL;
5260 abfd->origin = entry->offset;
5261}
5262
3af9a47b 5263bfd *
47daa70f 5264bfd_mach_o_fat_openr_next_archived_file (bfd *archive, bfd *prev)
3af9a47b 5265{
e84d6fca 5266 mach_o_fat_data_struct *adata;
3af9a47b
NC
5267 mach_o_fat_archentry *entry = NULL;
5268 unsigned long i;
15e1c58a 5269 bfd *nbfd;
15e1c58a
TG
5270 enum bfd_architecture arch_type;
5271 unsigned long arch_subtype;
3af9a47b 5272
e84d6fca 5273 adata = (mach_o_fat_data_struct *) archive->tdata.mach_o_fat_data;
3af9a47b
NC
5274 BFD_ASSERT (adata != NULL);
5275
5276 /* Find index of previous entry. */
5277 if (prev == NULL)
a4e241ca
TG
5278 {
5279 /* Start at first one. */
5280 i = 0;
5281 }
3af9a47b
NC
5282 else
5283 {
a4e241ca 5284 /* Find index of PREV. */
3af9a47b
NC
5285 for (i = 0; i < adata->nfat_arch; i++)
5286 {
15e1c58a 5287 if (adata->archentries[i].offset == prev->origin)
3af9a47b
NC
5288 break;
5289 }
5290
5291 if (i == adata->nfat_arch)
5292 {
5293 /* Not found. */
5294 bfd_set_error (bfd_error_bad_value);
a95a4550 5295 return NULL;
3af9a47b 5296 }
a4e241ca
TG
5297
5298 /* Get next entry. */
5299 i++;
5300 }
a95a4550 5301
3af9a47b
NC
5302 if (i >= adata->nfat_arch)
5303 {
5304 bfd_set_error (bfd_error_no_more_archived_files);
5305 return NULL;
5306 }
5307
5308 entry = &adata->archentries[i];
15e1c58a
TG
5309 nbfd = _bfd_new_bfd_contained_in (archive);
5310 if (nbfd == NULL)
5311 return NULL;
5312
15e1c58a
TG
5313 bfd_mach_o_convert_architecture (entry->cputype, entry->cpusubtype,
5314 &arch_type, &arch_subtype);
846b9259 5315
a4e241ca
TG
5316 bfd_mach_o_fat_member_init (nbfd, arch_type, arch_subtype, entry);
5317
846b9259 5318 bfd_set_arch_mach (nbfd, arch_type, arch_subtype);
3af9a47b 5319
15e1c58a 5320 return nbfd;
3af9a47b
NC
5321}
5322
15bbba8d
TG
5323/* Analogous to stat call. */
5324
5325static int
5326bfd_mach_o_fat_stat_arch_elt (bfd *abfd, struct stat *buf)
5327{
5328 if (abfd->arelt_data == NULL)
5329 {
5330 bfd_set_error (bfd_error_invalid_operation);
5331 return -1;
5332 }
5333
5334 buf->st_mtime = 0;
5335 buf->st_uid = 0;
5336 buf->st_gid = 0;
5337 buf->st_mode = 0644;
5338 buf->st_size = arelt_size (abfd);
5339
5340 return 0;
5341}
5342
846b9259
TG
5343/* If ABFD format is FORMAT and architecture is ARCH, return it.
5344 If ABFD is a fat image containing a member that corresponds to FORMAT
5345 and ARCH, returns it.
5346 In other case, returns NULL.
5347 This function allows transparent uses of fat images. */
a4e241ca 5348
846b9259
TG
5349bfd *
5350bfd_mach_o_fat_extract (bfd *abfd,
5351 bfd_format format,
5352 const bfd_arch_info_type *arch)
5353{
5354 bfd *res;
5355 mach_o_fat_data_struct *adata;
5356 unsigned int i;
5357
5358 if (bfd_check_format (abfd, format))
5359 {
5360 if (bfd_get_arch_info (abfd) == arch)
5361 return abfd;
5362 return NULL;
5363 }
5364 if (!bfd_check_format (abfd, bfd_archive)
5365 || abfd->xvec != &mach_o_fat_vec)
5366 return NULL;
c2f09c75 5367
846b9259
TG
5368 /* This is a Mach-O fat image. */
5369 adata = (mach_o_fat_data_struct *) abfd->tdata.mach_o_fat_data;
5370 BFD_ASSERT (adata != NULL);
5371
5372 for (i = 0; i < adata->nfat_arch; i++)
5373 {
5374 struct mach_o_fat_archentry *e = &adata->archentries[i];
5375 enum bfd_architecture cpu_type;
5376 unsigned long cpu_subtype;
5377
5378 bfd_mach_o_convert_architecture (e->cputype, e->cpusubtype,
5379 &cpu_type, &cpu_subtype);
5380 if (cpu_type != arch->arch || cpu_subtype != arch->mach)
5381 continue;
5382
5383 /* The architecture is found. */
5384 res = _bfd_new_bfd_contained_in (abfd);
5385 if (res == NULL)
5386 return NULL;
5387
a4e241ca 5388 bfd_mach_o_fat_member_init (res, cpu_type, cpu_subtype, e);
846b9259
TG
5389
5390 if (bfd_check_format (res, format))
5391 {
5392 BFD_ASSERT (bfd_get_arch_info (res) == arch);
5393 return res;
5394 }
5395 bfd_close (res);
5396 return NULL;
5397 }
5398
5399 return NULL;
5400}
5401
3af9a47b 5402int
116c20d2
NC
5403bfd_mach_o_lookup_command (bfd *abfd,
5404 bfd_mach_o_load_command_type type,
5405 bfd_mach_o_load_command **mcommand)
3af9a47b 5406{
c9ffd2ea
TG
5407 struct mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
5408 struct bfd_mach_o_load_command *cmd;
5409 unsigned int num;
3af9a47b 5410
c9ffd2ea 5411 BFD_ASSERT (mdata != NULL);
3af9a47b
NC
5412 BFD_ASSERT (mcommand != NULL);
5413
5414 num = 0;
c9ffd2ea 5415 for (cmd = mdata->first_command; cmd != NULL; cmd = cmd->next)
3af9a47b 5416 {
3af9a47b
NC
5417 if (cmd->type != type)
5418 continue;
5419
5420 if (num == 0)
c9ffd2ea 5421 *mcommand = cmd;
3af9a47b
NC
5422 num++;
5423 }
5424
3af9a47b
NC
5425 return num;
5426}
5427
5428unsigned long
116c20d2 5429bfd_mach_o_stack_addr (enum bfd_mach_o_cpu_type type)
3af9a47b
NC
5430{
5431 switch (type)
5432 {
5433 case BFD_MACH_O_CPU_TYPE_MC680x0:
5434 return 0x04000000;
3af9a47b
NC
5435 case BFD_MACH_O_CPU_TYPE_POWERPC:
5436 return 0xc0000000;
5437 case BFD_MACH_O_CPU_TYPE_I386:
5438 return 0xc0000000;
5439 case BFD_MACH_O_CPU_TYPE_SPARC:
5440 return 0xf0000000;
3af9a47b 5441 case BFD_MACH_O_CPU_TYPE_HPPA:
e84d6fca 5442 return 0xc0000000 - 0x04000000;
3af9a47b
NC
5443 default:
5444 return 0;
5445 }
5446}
5447
ab76eeaf
IS
5448/* The following two tables should be kept, as far as possible, in order of
5449 most frequently used entries to optimize their use from gas. */
5450
c5012cd8 5451const bfd_mach_o_xlat_name bfd_mach_o_section_type_name[] =
046b007d
TG
5452{
5453 { "regular", BFD_MACH_O_S_REGULAR},
ab76eeaf 5454 { "coalesced", BFD_MACH_O_S_COALESCED},
046b007d
TG
5455 { "zerofill", BFD_MACH_O_S_ZEROFILL},
5456 { "cstring_literals", BFD_MACH_O_S_CSTRING_LITERALS},
5457 { "4byte_literals", BFD_MACH_O_S_4BYTE_LITERALS},
5458 { "8byte_literals", BFD_MACH_O_S_8BYTE_LITERALS},
ab76eeaf 5459 { "16byte_literals", BFD_MACH_O_S_16BYTE_LITERALS},
046b007d 5460 { "literal_pointers", BFD_MACH_O_S_LITERAL_POINTERS},
046b007d
TG
5461 { "mod_init_func_pointers", BFD_MACH_O_S_MOD_INIT_FUNC_POINTERS},
5462 { "mod_fini_func_pointers", BFD_MACH_O_S_MOD_FINI_FUNC_POINTERS},
046b007d
TG
5463 { "gb_zerofill", BFD_MACH_O_S_GB_ZEROFILL},
5464 { "interposing", BFD_MACH_O_S_INTERPOSING},
046b007d 5465 { "dtrace_dof", BFD_MACH_O_S_DTRACE_DOF},
ab76eeaf
IS
5466 { "non_lazy_symbol_pointers", BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS},
5467 { "lazy_symbol_pointers", BFD_MACH_O_S_LAZY_SYMBOL_POINTERS},
a4551119 5468 { "symbol_stubs", BFD_MACH_O_S_SYMBOL_STUBS},
046b007d
TG
5469 { "lazy_dylib_symbol_pointers", BFD_MACH_O_S_LAZY_DYLIB_SYMBOL_POINTERS},
5470 { NULL, 0}
5471};
5472
c5012cd8 5473const bfd_mach_o_xlat_name bfd_mach_o_section_attribute_name[] =
046b007d 5474{
ab76eeaf
IS
5475 { "pure_instructions", BFD_MACH_O_S_ATTR_PURE_INSTRUCTIONS },
5476 { "some_instructions", BFD_MACH_O_S_ATTR_SOME_INSTRUCTIONS },
046b007d
TG
5477 { "loc_reloc", BFD_MACH_O_S_ATTR_LOC_RELOC },
5478 { "ext_reloc", BFD_MACH_O_S_ATTR_EXT_RELOC },
046b007d 5479 { "debug", BFD_MACH_O_S_ATTR_DEBUG },
046b007d
TG
5480 { "live_support", BFD_MACH_O_S_ATTR_LIVE_SUPPORT },
5481 { "no_dead_strip", BFD_MACH_O_S_ATTR_NO_DEAD_STRIP },
5482 { "strip_static_syms", BFD_MACH_O_S_ATTR_STRIP_STATIC_SYMS },
5483 { "no_toc", BFD_MACH_O_S_ATTR_NO_TOC },
a4551119 5484 { "self_modifying_code", BFD_MACH_O_S_SELF_MODIFYING_CODE },
ab76eeaf 5485 { "modifying_code", BFD_MACH_O_S_SELF_MODIFYING_CODE },
046b007d
TG
5486 { NULL, 0}
5487};
5488
a4551119 5489/* Get the section type from NAME. Return 256 if NAME is unknown. */
53d58d96
TG
5490
5491unsigned int
ab76eeaf 5492bfd_mach_o_get_section_type_from_name (bfd *abfd, const char *name)
53d58d96 5493{
afbb9e17 5494 const bfd_mach_o_xlat_name *x;
ab76eeaf 5495 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
53d58d96
TG
5496
5497 for (x = bfd_mach_o_section_type_name; x->name; x++)
5498 if (strcmp (x->name, name) == 0)
ab76eeaf
IS
5499 {
5500 /* We found it... does the target support it? */
5501 if (bed->bfd_mach_o_section_type_valid_for_target == NULL
5502 || bed->bfd_mach_o_section_type_valid_for_target (x->val))
5503 return x->val; /* OK. */
5504 else
5505 break; /* Not supported. */
5506 }
a4551119
TG
5507 /* Maximum section ID = 0xff. */
5508 return 256;
53d58d96
TG
5509}
5510
5511/* Get the section attribute from NAME. Return -1 if NAME is unknown. */
5512
5513unsigned int
5514bfd_mach_o_get_section_attribute_from_name (const char *name)
5515{
afbb9e17 5516 const bfd_mach_o_xlat_name *x;
53d58d96
TG
5517
5518 for (x = bfd_mach_o_section_attribute_name; x->name; x++)
5519 if (strcmp (x->name, name) == 0)
5520 return x->val;
5521 return (unsigned int)-1;
5522}
5523
3af9a47b 5524int
116c20d2
NC
5525bfd_mach_o_core_fetch_environment (bfd *abfd,
5526 unsigned char **rbuf,
5527 unsigned int *rlen)
3af9a47b 5528{
046b007d 5529 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3af9a47b 5530 unsigned long stackaddr = bfd_mach_o_stack_addr (mdata->header.cputype);
c9ffd2ea 5531 bfd_mach_o_load_command *cmd;
3af9a47b 5532
c9ffd2ea 5533 for (cmd = mdata->first_command; cmd != NULL; cmd = cmd->next)
3af9a47b 5534 {
c9ffd2ea 5535 bfd_mach_o_segment_command *seg;
3af9a47b 5536
c9ffd2ea 5537 if (cmd->type != BFD_MACH_O_LC_SEGMENT)
3af9a47b
NC
5538 continue;
5539
c9ffd2ea 5540 seg = &cmd->command.segment;
3af9a47b
NC
5541
5542 if ((seg->vmaddr + seg->vmsize) == stackaddr)
5543 {
5544 unsigned long start = seg->fileoff;
5545 unsigned long end = seg->fileoff + seg->filesize;
5546 unsigned char *buf = bfd_malloc (1024);
5547 unsigned long size = 1024;
5548
5549 for (;;)
5550 {
5551 bfd_size_type nread = 0;
5552 unsigned long offset;
5553 int found_nonnull = 0;
5554
5555 if (size > (end - start))
5556 size = (end - start);
5557
515ef31d
NC
5558 buf = bfd_realloc_or_free (buf, size);
5559 if (buf == NULL)
5560 return -1;
c2f09c75
TG
5561
5562 if (bfd_seek (abfd, end - size, SEEK_SET) != 0)
07d6d2b8
AM
5563 {
5564 free (buf);
5565 return -1;
5566 }
c2f09c75 5567
3af9a47b 5568 nread = bfd_bread (buf, size, abfd);
a95a4550 5569
3af9a47b 5570 if (nread != size)
515ef31d
NC
5571 {
5572 free (buf);
5573 return -1;
5574 }
a95a4550 5575
3af9a47b
NC
5576 for (offset = 4; offset <= size; offset += 4)
5577 {
e84d6fca 5578 unsigned long val;
3af9a47b 5579
e84d6fca 5580 val = *((unsigned long *) (buf + size - offset));
3af9a47b
NC
5581 if (! found_nonnull)
5582 {
5583 if (val != 0)
5584 found_nonnull = 1;
5585 }
5586 else if (val == 0x0)
5587 {
e84d6fca
AM
5588 unsigned long bottom;
5589 unsigned long top;
3af9a47b 5590
e84d6fca
AM
5591 bottom = seg->fileoff + seg->filesize - offset;
5592 top = seg->fileoff + seg->filesize - 4;
3af9a47b
NC
5593 *rbuf = bfd_malloc (top - bottom);
5594 *rlen = top - bottom;
5595
5596 memcpy (*rbuf, buf + size - *rlen, *rlen);
515ef31d 5597 free (buf);
3af9a47b
NC
5598 return 0;
5599 }
5600 }
5601
5602 if (size == (end - start))
5603 break;
5604
5605 size *= 2;
5606 }
515ef31d
NC
5607
5608 free (buf);
3af9a47b
NC
5609 }
5610 }
5611
5612 return -1;
5613}
5614
5615char *
116c20d2 5616bfd_mach_o_core_file_failing_command (bfd *abfd)
3af9a47b
NC
5617{
5618 unsigned char *buf = NULL;
5619 unsigned int len = 0;
452216ab 5620 int ret;
3af9a47b
NC
5621
5622 ret = bfd_mach_o_core_fetch_environment (abfd, &buf, &len);
5623 if (ret < 0)
5624 return NULL;
5625
f075ee0c 5626 return (char *) buf;
3af9a47b
NC
5627}
5628
5629int
116c20d2 5630bfd_mach_o_core_file_failing_signal (bfd *abfd ATTRIBUTE_UNUSED)
3af9a47b
NC
5631{
5632 return 0;
5633}
5634
2ca7691a
TG
5635static bfd_mach_o_uuid_command *
5636bfd_mach_o_lookup_uuid_command (bfd *abfd)
5637{
09fe2662 5638 bfd_mach_o_load_command *uuid_cmd = NULL;
2ca7691a 5639 int ncmd = bfd_mach_o_lookup_command (abfd, BFD_MACH_O_LC_UUID, &uuid_cmd);
09fe2662 5640 if (ncmd != 1 || uuid_cmd == NULL)
2ca7691a
TG
5641 return FALSE;
5642 return &uuid_cmd->command.uuid;
5643}
5644
5645/* Return true if ABFD is a dSYM file and its UUID matches UUID_CMD. */
5646
5647static bfd_boolean
5648bfd_mach_o_dsym_for_uuid_p (bfd *abfd, const bfd_mach_o_uuid_command *uuid_cmd)
5649{
5650 bfd_mach_o_uuid_command *dsym_uuid_cmd;
5651
5652 BFD_ASSERT (abfd);
5653 BFD_ASSERT (uuid_cmd);
5654
5655 if (!bfd_check_format (abfd, bfd_object))
5656 return FALSE;
5657
5658 if (bfd_get_flavour (abfd) != bfd_target_mach_o_flavour
5659 || bfd_mach_o_get_data (abfd) == NULL
5660 || bfd_mach_o_get_data (abfd)->header.filetype != BFD_MACH_O_MH_DSYM)
5661 return FALSE;
5662
5663 dsym_uuid_cmd = bfd_mach_o_lookup_uuid_command (abfd);
5664 if (dsym_uuid_cmd == NULL)
5665 return FALSE;
5666
5667 if (memcmp (uuid_cmd->uuid, dsym_uuid_cmd->uuid,
07d6d2b8 5668 sizeof (uuid_cmd->uuid)) != 0)
2ca7691a
TG
5669 return FALSE;
5670
5671 return TRUE;
5672}
5673
5674/* Find a BFD in DSYM_FILENAME which matches ARCH and UUID_CMD.
5675 The caller is responsible for closing the returned BFD object and
5676 its my_archive if the returned BFD is in a fat dSYM. */
5677
5678static bfd *
5679bfd_mach_o_find_dsym (const char *dsym_filename,
07d6d2b8
AM
5680 const bfd_mach_o_uuid_command *uuid_cmd,
5681 const bfd_arch_info_type *arch)
2ca7691a
TG
5682{
5683 bfd *base_dsym_bfd, *dsym_bfd;
5684
5685 BFD_ASSERT (uuid_cmd);
5686
5687 base_dsym_bfd = bfd_openr (dsym_filename, NULL);
5688 if (base_dsym_bfd == NULL)
5689 return NULL;
5690
5691 dsym_bfd = bfd_mach_o_fat_extract (base_dsym_bfd, bfd_object, arch);
5692 if (bfd_mach_o_dsym_for_uuid_p (dsym_bfd, uuid_cmd))
5693 return dsym_bfd;
5694
5695 bfd_close (dsym_bfd);
5696 if (base_dsym_bfd != dsym_bfd)
5697 bfd_close (base_dsym_bfd);
5698
5699 return NULL;
5700}
5701
5702/* Return a BFD created from a dSYM file for ABFD.
5703 The caller is responsible for closing the returned BFD object, its
5704 filename, and its my_archive if the returned BFD is in a fat dSYM. */
5705
5706static bfd *
5707bfd_mach_o_follow_dsym (bfd *abfd)
5708{
5709 char *dsym_filename;
5710 bfd_mach_o_uuid_command *uuid_cmd;
5711 bfd *dsym_bfd, *base_bfd = abfd;
5712 const char *base_basename;
5713
5714 if (abfd == NULL || bfd_get_flavour (abfd) != bfd_target_mach_o_flavour)
5715 return NULL;
5716
b0cffb47 5717 if (abfd->my_archive && !bfd_is_thin_archive (abfd->my_archive))
2ca7691a
TG
5718 base_bfd = abfd->my_archive;
5719 /* BFD may have been opened from a stream. */
5720 if (base_bfd->filename == NULL)
5721 {
5722 bfd_set_error (bfd_error_invalid_operation);
5723 return NULL;
5724 }
5725 base_basename = lbasename (base_bfd->filename);
5726
5727 uuid_cmd = bfd_mach_o_lookup_uuid_command (abfd);
5728 if (uuid_cmd == NULL)
5729 return NULL;
5730
5731 /* TODO: We assume the DWARF file has the same as the binary's.
5732 It seems apple's GDB checks all files in the dSYM bundle directory.
5733 http://opensource.apple.com/source/gdb/gdb-1708/src/gdb/macosx/macosx-tdep.c
5734 */
5735 dsym_filename = (char *)bfd_malloc (strlen (base_bfd->filename)
07d6d2b8
AM
5736 + strlen (dsym_subdir) + 1
5737 + strlen (base_basename) + 1);
2ca7691a 5738 sprintf (dsym_filename, "%s%s/%s",
07d6d2b8 5739 base_bfd->filename, dsym_subdir, base_basename);
2ca7691a
TG
5740
5741 dsym_bfd = bfd_mach_o_find_dsym (dsym_filename, uuid_cmd,
07d6d2b8 5742 bfd_get_arch_info (abfd));
2ca7691a
TG
5743 if (dsym_bfd == NULL)
5744 free (dsym_filename);
5745
5746 return dsym_bfd;
5747}
5748
d9071b0c
TG
5749bfd_boolean
5750bfd_mach_o_find_nearest_line (bfd *abfd,
d9071b0c 5751 asymbol **symbols,
fb167eb2 5752 asection *section,
d9071b0c
TG
5753 bfd_vma offset,
5754 const char **filename_ptr,
5755 const char **functionname_ptr,
fb167eb2
AM
5756 unsigned int *line_ptr,
5757 unsigned int *discriminator_ptr)
d9071b0c
TG
5758{
5759 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
2ca7691a 5760 if (mdata == NULL)
d9071b0c 5761 return FALSE;
2ca7691a
TG
5762 switch (mdata->header.filetype)
5763 {
5764 case BFD_MACH_O_MH_OBJECT:
5765 break;
5766 case BFD_MACH_O_MH_EXECUTE:
5767 case BFD_MACH_O_MH_DYLIB:
5768 case BFD_MACH_O_MH_BUNDLE:
5769 case BFD_MACH_O_MH_KEXT_BUNDLE:
5770 if (mdata->dwarf2_find_line_info == NULL)
07d6d2b8
AM
5771 {
5772 mdata->dsym_bfd = bfd_mach_o_follow_dsym (abfd);
5773 /* When we couldn't find dSYM for this binary, we look for
5774 the debug information in the binary itself. In this way,
5775 we won't try finding separated dSYM again because
5776 mdata->dwarf2_find_line_info will be filled. */
5777 if (! mdata->dsym_bfd)
5778 break;
5779 if (! _bfd_dwarf2_slurp_debug_info (abfd, mdata->dsym_bfd,
5780 dwarf_debug_sections, symbols,
5781 &mdata->dwarf2_find_line_info,
93ee1e36 5782 FALSE))
07d6d2b8
AM
5783 return FALSE;
5784 }
2ca7691a
TG
5785 break;
5786 default:
5787 return FALSE;
5788 }
fb167eb2
AM
5789 return _bfd_dwarf2_find_nearest_line (abfd, symbols, NULL, section, offset,
5790 filename_ptr, functionname_ptr,
5791 line_ptr, discriminator_ptr,
5792 dwarf_debug_sections, 0,
5793 &mdata->dwarf2_find_line_info);
d9071b0c
TG
5794}
5795
5796bfd_boolean
5797bfd_mach_o_close_and_cleanup (bfd *abfd)
5798{
5799 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
5800 if (bfd_get_format (abfd) == bfd_object && mdata != NULL)
4434114c
TG
5801 {
5802 _bfd_dwarf2_cleanup_debug_info (abfd, &mdata->dwarf2_find_line_info);
5803 bfd_mach_o_free_cached_info (abfd);
2ca7691a 5804 if (mdata->dsym_bfd != NULL)
07d6d2b8
AM
5805 {
5806 bfd *fat_bfd = mdata->dsym_bfd->my_archive;
cf466c2a
NC
5807#if 0
5808 /* FIXME: PR 19435: This calculation to find the memory allocated by
5809 bfd_mach_o_follow_dsym for the filename does not always end up
5810 selecting the correct pointer. Unfortunately this problem is
5811 very hard to reproduce on a non Mach-O native system, so until it
5812 can be traced and fixed on such a system, this code will remain
5813 commented out. This does mean that there will be a memory leak,
5814 but it is small, and happens when we are closing down, so it
c244074c 5815 should not matter too much. */
07d6d2b8
AM
5816 char *dsym_filename = (char *)(fat_bfd
5817 ? fat_bfd->filename
5818 : mdata->dsym_bfd->filename);
cf466c2a 5819#endif
07d6d2b8
AM
5820 bfd_close (mdata->dsym_bfd);
5821 mdata->dsym_bfd = NULL;
5822 if (fat_bfd)
5823 bfd_close (fat_bfd);
cf466c2a 5824#if 0
07d6d2b8 5825 free (dsym_filename);
cf466c2a 5826#endif
07d6d2b8 5827 }
4434114c 5828 }
dff55db0 5829
d9071b0c
TG
5830 return _bfd_generic_close_and_cleanup (abfd);
5831}
5832
dff55db0
TG
5833bfd_boolean bfd_mach_o_free_cached_info (bfd *abfd)
5834{
5835 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
5836 asection *asect;
5837 free (mdata->dyn_reloc_cache);
5838 mdata->dyn_reloc_cache = NULL;
5839 for (asect = abfd->sections; asect != NULL; asect = asect->next)
5840 {
5841 free (asect->relocation);
5842 asect->relocation = NULL;
5843 }
5844
5845 return TRUE;
5846}
5847
68ffbac6 5848#define bfd_mach_o_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup
92bc0e80
TG
5849#define bfd_mach_o_bfd_reloc_name_lookup _bfd_norelocs_bfd_reloc_name_lookup
5850
bcb51645 5851#define bfd_mach_o_canonicalize_one_reloc NULL
92bc0e80 5852#define bfd_mach_o_swap_reloc_out NULL
b32e07d7 5853#define bfd_mach_o_print_thread NULL
a4551119 5854#define bfd_mach_o_tgt_seg_table NULL
ab76eeaf 5855#define bfd_mach_o_section_type_valid_for_tgt NULL
92bc0e80 5856
07d6d2b8
AM
5857#define TARGET_NAME mach_o_be_vec
5858#define TARGET_STRING "mach-o-be"
42fa0891 5859#define TARGET_ARCHITECTURE bfd_arch_unknown
4384b284 5860#define TARGET_PAGESIZE 1
07d6d2b8
AM
5861#define TARGET_BIG_ENDIAN 1
5862#define TARGET_ARCHIVE 0
b93a1992 5863#define TARGET_PRIORITY 1
3af9a47b
NC
5864#include "mach-o-target.c"
5865
5866#undef TARGET_NAME
5867#undef TARGET_STRING
42fa0891 5868#undef TARGET_ARCHITECTURE
4384b284 5869#undef TARGET_PAGESIZE
3af9a47b
NC
5870#undef TARGET_BIG_ENDIAN
5871#undef TARGET_ARCHIVE
b93a1992 5872#undef TARGET_PRIORITY
3af9a47b 5873
07d6d2b8
AM
5874#define TARGET_NAME mach_o_le_vec
5875#define TARGET_STRING "mach-o-le"
42fa0891 5876#define TARGET_ARCHITECTURE bfd_arch_unknown
4384b284 5877#define TARGET_PAGESIZE 1
07d6d2b8
AM
5878#define TARGET_BIG_ENDIAN 0
5879#define TARGET_ARCHIVE 0
b93a1992 5880#define TARGET_PRIORITY 1
3af9a47b
NC
5881
5882#include "mach-o-target.c"
5883
5884#undef TARGET_NAME
5885#undef TARGET_STRING
42fa0891 5886#undef TARGET_ARCHITECTURE
4384b284 5887#undef TARGET_PAGESIZE
3af9a47b
NC
5888#undef TARGET_BIG_ENDIAN
5889#undef TARGET_ARCHIVE
b93a1992 5890#undef TARGET_PRIORITY
3af9a47b 5891
8f95b6e4 5892/* Not yet handled: creating an archive. */
07d6d2b8 5893#define bfd_mach_o_mkarchive _bfd_noarchive_mkarchive
8f95b6e4 5894
d00dd7dc 5895#define bfd_mach_o_close_and_cleanup _bfd_bool_bfd_true
47daa70f 5896
8f95b6e4 5897/* Not used. */
07d6d2b8 5898#define bfd_mach_o_generic_stat_arch_elt bfd_mach_o_fat_stat_arch_elt
47daa70f
TG
5899#define bfd_mach_o_openr_next_archived_file bfd_mach_o_fat_openr_next_archived_file
5900#define bfd_mach_o_archive_p bfd_mach_o_fat_archive_p
8f95b6e4 5901
07d6d2b8
AM
5902#define TARGET_NAME mach_o_fat_vec
5903#define TARGET_STRING "mach-o-fat"
42fa0891 5904#define TARGET_ARCHITECTURE bfd_arch_unknown
4384b284 5905#define TARGET_PAGESIZE 1
07d6d2b8
AM
5906#define TARGET_BIG_ENDIAN 1
5907#define TARGET_ARCHIVE 1
b93a1992 5908#define TARGET_PRIORITY 0
3af9a47b
NC
5909
5910#include "mach-o-target.c"
5911
5912#undef TARGET_NAME
5913#undef TARGET_STRING
42fa0891 5914#undef TARGET_ARCHITECTURE
4384b284 5915#undef TARGET_PAGESIZE
3af9a47b
NC
5916#undef TARGET_BIG_ENDIAN
5917#undef TARGET_ARCHIVE
b93a1992 5918#undef TARGET_PRIORITY