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