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