OLD | NEW |
1 /* Mach-O support for BFD. | 1 /* Mach-O support for BFD. |
2 Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, | 2 Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, |
3 2009, 2010, 2011 | 3 2009, 2010, 2011, 2012 |
4 Free Software Foundation, Inc. | 4 Free Software Foundation, Inc. |
5 | 5 |
6 This file is part of BFD, the Binary File Descriptor library. | 6 This file is part of BFD, the Binary File Descriptor library. |
7 | 7 |
8 This program is free software; you can redistribute it and/or modify | 8 This program is free software; you can redistribute it and/or modify |
9 it under the terms of the GNU General Public License as published by | 9 it under the terms of the GNU General Public License as published by |
10 the Free Software Foundation; either version 3 of the License, or | 10 the Free Software Foundation; either version 3 of the License, or |
11 (at your option) any later version. | 11 (at your option) any later version. |
12 | 12 |
13 This program is distributed in the hope that it will be useful, | 13 This program is distributed in the hope that it will be useful, |
14 but WITHOUT ANY WARRANTY; without even the implied warranty of | 14 but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 GNU General Public License for more details. | 16 GNU General Public License for more details. |
17 | 17 |
18 You should have received a copy of the GNU General Public License | 18 You should have received a copy of the GNU General Public License |
19 along with this program; if not, write to the Free Software | 19 along with this program; if not, write to the Free Software |
20 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, | 20 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, |
21 MA 02110-1301, USA. */ | 21 MA 02110-1301, USA. */ |
22 | 22 |
23 #include "sysdep.h" | 23 #include "sysdep.h" |
24 #include "mach-o.h" | 24 #include "mach-o.h" |
25 #include "bfd.h" | 25 #include "bfd.h" |
26 #include "libbfd.h" | 26 #include "libbfd.h" |
27 #include "libiberty.h" | 27 #include "libiberty.h" |
28 #include "aout/stab_gnu.h" | 28 #include "aout/stab_gnu.h" |
29 #include "mach-o/reloc.h" | 29 #include "mach-o/reloc.h" |
30 #include "mach-o/external.h" | 30 #include "mach-o/external.h" |
31 #include <ctype.h> | 31 #include <ctype.h> |
| 32 #include <stdlib.h> |
| 33 #include <string.h> |
32 | 34 |
33 #define bfd_mach_o_object_p bfd_mach_o_gen_object_p | 35 #define bfd_mach_o_object_p bfd_mach_o_gen_object_p |
34 #define bfd_mach_o_core_p bfd_mach_o_gen_core_p | 36 #define bfd_mach_o_core_p bfd_mach_o_gen_core_p |
35 #define bfd_mach_o_mkobject bfd_mach_o_gen_mkobject | 37 #define bfd_mach_o_mkobject bfd_mach_o_gen_mkobject |
36 | 38 |
37 #define FILE_ALIGN(off, algn) \ | 39 #define FILE_ALIGN(off, algn) \ |
38 (((off) + ((file_ptr) 1 << (algn)) - 1) & ((file_ptr) -1 << (algn))) | 40 (((off) + ((file_ptr) 1 << (algn)) - 1) & ((file_ptr) -1 << (algn))) |
39 | 41 |
40 unsigned int | 42 unsigned int |
41 bfd_mach_o_version (bfd *abfd) | 43 bfd_mach_o_version (bfd *abfd) |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
80 static INLINE bfd_boolean | 82 static INLINE bfd_boolean |
81 bfd_mach_o_wide_p (bfd *abfd) | 83 bfd_mach_o_wide_p (bfd *abfd) |
82 { | 84 { |
83 return mach_o_wide_p (&bfd_mach_o_get_data (abfd)->header); | 85 return mach_o_wide_p (&bfd_mach_o_get_data (abfd)->header); |
84 } | 86 } |
85 | 87 |
86 /* Tables to translate well known Mach-O segment/section names to bfd | 88 /* Tables to translate well known Mach-O segment/section names to bfd |
87 names. Use of canonical names (such as .text or .debug_frame) is required | 89 names. Use of canonical names (such as .text or .debug_frame) is required |
88 by gdb. */ | 90 by gdb. */ |
89 | 91 |
90 struct mach_o_section_name_xlat | 92 /* __TEXT Segment. */ |
91 { | 93 static const mach_o_section_name_xlat text_section_names_xlat[] = |
92 const char *bfd_name; | 94 { |
93 const char *mach_o_name; | 95 {» ".text",» » » » "__text",» |
94 flagword flags; | 96 » SEC_CODE | SEC_LOAD,» » » BFD_MACH_O_S_REGULAR, |
95 }; | 97 » BFD_MACH_O_S_ATTR_PURE_INSTRUCTIONS,» 0}, |
96 | 98 {» ".const",» » » » "__const", |
97 static const struct mach_o_section_name_xlat dwarf_section_names_xlat[] = | 99 » SEC_READONLY | SEC_DATA | SEC_LOAD,» BFD_MACH_O_S_REGULAR, |
98 { | 100 » BFD_MACH_O_S_ATTR_NONE,»» » 0}, |
99 { ".debug_frame", "__debug_frame", SEC_DEBUGGING }, | 101 {» ".static_const",» » » "__static_const", |
100 { ".debug_info", "__debug_info", SEC_DEBUGGING }, | 102 » SEC_READONLY | SEC_DATA | SEC_LOAD,» BFD_MACH_O_S_REGULAR, |
101 { ".debug_abbrev", "__debug_abbrev", SEC_DEBUGGING }, | 103 » BFD_MACH_O_S_ATTR_NONE,»» » 0}, |
102 { ".debug_aranges", "__debug_aranges", SEC_DEBUGGING }, | 104 {» ".cstring",» » » » "__cstring", |
103 { ".debug_macinfo", "__debug_macinfo", SEC_DEBUGGING }, | 105 » SEC_READONLY | SEC_DATA | SEC_LOAD | SEC_MERGE | SEC_STRINGS, |
104 { ".debug_line", "__debug_line", SEC_DEBUGGING }, | 106 » » » » » » BFD_MACH_O_S_CSTRING_LITERALS, |
105 { ".debug_loc", "__debug_loc", SEC_DEBUGGING }, | 107 » BFD_MACH_O_S_ATTR_NONE,»» » 0}, |
106 { ".debug_pubnames", "__debug_pubnames", SEC_DEBUGGING }, | 108 {» ".literal4",» » » » "__literal4", |
107 { ".debug_pubtypes", "__debug_pubtypes", SEC_DEBUGGING }, | 109 » SEC_READONLY | SEC_DATA | SEC_LOAD,» BFD_MACH_O_S_4BYTE_LITERALS, |
108 { ".debug_str", "__debug_str", SEC_DEBUGGING }, | 110 » BFD_MACH_O_S_ATTR_NONE,»» » 2}, |
109 { ".debug_ranges", "__debug_ranges", SEC_DEBUGGING }, | 111 {» ".literal8",» » » » "__literal8", |
110 { NULL, NULL, 0} | 112 » SEC_READONLY | SEC_DATA | SEC_LOAD,» BFD_MACH_O_S_8BYTE_LITERALS, |
111 }; | 113 » BFD_MACH_O_S_ATTR_NONE,»» » 3}, |
112 | 114 {» ".literal16",» » » » "__literal16", |
113 static const struct mach_o_section_name_xlat text_section_names_xlat[] = | 115 » SEC_READONLY | SEC_DATA | SEC_LOAD,» BFD_MACH_O_S_16BYTE_LITERALS, |
114 { | 116 » BFD_MACH_O_S_ATTR_NONE,»» » 4}, |
115 { ".text", "__text", SEC_CODE | SEC_LOAD }, | 117 {» ".constructor",»» » » "__constructor", |
116 { ".const", "__const", SEC_READONLY | SEC_DATA | SEC_LOAD }, | 118 » SEC_CODE | SEC_LOAD,» » » BFD_MACH_O_S_REGULAR, |
117 { ".cstring", "__cstring", SEC_READONLY | SEC_DATA | SEC_LOAD }, | 119 » BFD_MACH_O_S_ATTR_NONE,»» » 0}, |
118 { ".eh_frame", "__eh_frame", SEC_READONLY | SEC_LOAD }, | 120 {» ".destructor",» » » » "__destructor", |
119 { NULL, NULL, 0} | 121 » SEC_CODE | SEC_LOAD,» » » BFD_MACH_O_S_REGULAR, |
120 }; | 122 » BFD_MACH_O_S_ATTR_NONE,»» » 0}, |
121 | 123 {» ".eh_frame",» » » » "__eh_frame", |
122 static const struct mach_o_section_name_xlat data_section_names_xlat[] = | 124 » SEC_READONLY | SEC_DATA | SEC_LOAD,» BFD_MACH_O_S_COALESCED, |
123 { | 125 » BFD_MACH_O_S_ATTR_LIVE_SUPPORT |
124 { ".data", "__data", SEC_DATA | SEC_LOAD }, | 126 » | BFD_MACH_O_S_ATTR_STRIP_STATIC_SYMS |
125 { ".const_data", "__const", SEC_DATA | SEC_LOAD }, | 127 » | BFD_MACH_O_S_ATTR_NO_TOC,» » 2}, |
126 { ".dyld", "__dyld", SEC_DATA | SEC_LOAD }, | 128 { NULL, NULL, 0, 0, 0, 0} |
127 { ".lazy_symbol_ptr", "__la_symbol_ptr", SEC_DATA | SEC_LOAD }, | 129 }; |
128 { ".non_lazy_symbol_ptr", "__nl_symbol_ptr", SEC_DATA | SEC_LOAD }, | 130 |
129 { ".bss", "__bss", SEC_NO_FLAGS }, | 131 /* __DATA Segment. */ |
130 { NULL, NULL, 0} | 132 static const mach_o_section_name_xlat data_section_names_xlat[] = |
131 }; | 133 { |
132 | 134 {» ".data",» » » "__data", |
133 struct mach_o_segment_name_xlat | 135 » SEC_DATA | SEC_LOAD,» » BFD_MACH_O_S_REGULAR, |
134 { | 136 » BFD_MACH_O_S_ATTR_NONE,»» 0}, |
135 /* Segment name. */ | 137 {» ".bss",»» » » "__bss", |
136 const char *segname; | 138 » SEC_NO_FLAGS,» » » BFD_MACH_O_S_ZEROFILL, |
137 | 139 » BFD_MACH_O_S_ATTR_NONE,»» 0}, |
138 /* List of known sections for the segment. */ | 140 {» ".const_data",» » » "__const", |
139 const struct mach_o_section_name_xlat *sections; | 141 » SEC_DATA | SEC_LOAD,» » BFD_MACH_O_S_REGULAR, |
140 }; | 142 » BFD_MACH_O_S_ATTR_NONE,»» 0}, |
141 | 143 {» ".static_data",»» » "__static_data", |
142 /* List of known segment names. */ | 144 » SEC_DATA | SEC_LOAD,» » BFD_MACH_O_S_REGULAR, |
143 | 145 » BFD_MACH_O_S_ATTR_NONE,»» 0}, |
144 static const struct mach_o_segment_name_xlat segsec_names_xlat[] = | 146 {» ".mod_init_func",» » "__mod_init_func", |
| 147 » SEC_DATA | SEC_LOAD,» » BFD_MACH_O_S_MOD_INIT_FUNC_POINTERS, |
| 148 » BFD_MACH_O_S_ATTR_NONE,»» 2}, |
| 149 {» ".mod_term_func",» » "__mod_term_func", |
| 150 » SEC_DATA | SEC_LOAD,» » BFD_MACH_O_S_MOD_FINI_FUNC_POINTERS, |
| 151 » BFD_MACH_O_S_ATTR_NONE,»» 2}, |
| 152 {» ".dyld",» » » "__dyld", |
| 153 » SEC_DATA | SEC_LOAD,» » BFD_MACH_O_S_REGULAR, |
| 154 » BFD_MACH_O_S_ATTR_NONE,»» 0}, |
| 155 {» ".cfstring",» » » "__cfstring", |
| 156 » SEC_DATA | SEC_LOAD,» » BFD_MACH_O_S_REGULAR, |
| 157 » BFD_MACH_O_S_ATTR_NONE,»» 2}, |
| 158 { NULL, NULL, 0, 0, 0, 0} |
| 159 }; |
| 160 |
| 161 /* __DWARF Segment. */ |
| 162 static const mach_o_section_name_xlat dwarf_section_names_xlat[] = |
| 163 { |
| 164 {» ".debug_frame",»» » "__debug_frame", |
| 165 » SEC_DEBUGGING,» » » BFD_MACH_O_S_REGULAR, |
| 166 » BFD_MACH_O_S_ATTR_DEBUG,» 0}, |
| 167 {» ".debug_info",» » » "__debug_info", |
| 168 » SEC_DEBUGGING,» » » BFD_MACH_O_S_REGULAR, |
| 169 » BFD_MACH_O_S_ATTR_DEBUG,» 0}, |
| 170 {» ".debug_abbrev",» » "__debug_abbrev", |
| 171 » SEC_DEBUGGING,» » » BFD_MACH_O_S_REGULAR, |
| 172 » BFD_MACH_O_S_ATTR_DEBUG,» 0}, |
| 173 {» ".debug_aranges",» » "__debug_aranges", |
| 174 » SEC_DEBUGGING,» » » BFD_MACH_O_S_REGULAR, |
| 175 » BFD_MACH_O_S_ATTR_DEBUG,» 0}, |
| 176 {» ".debug_macinfo",» » "__debug_macinfo", |
| 177 » SEC_DEBUGGING,» » » BFD_MACH_O_S_REGULAR, |
| 178 » BFD_MACH_O_S_ATTR_DEBUG,» 0}, |
| 179 {» ".debug_line",» » » "__debug_line", |
| 180 » SEC_DEBUGGING,» » » BFD_MACH_O_S_REGULAR, |
| 181 » BFD_MACH_O_S_ATTR_DEBUG,» 0}, |
| 182 {» ".debug_loc",» » » "__debug_loc", |
| 183 » SEC_DEBUGGING,» » » BFD_MACH_O_S_REGULAR, |
| 184 » BFD_MACH_O_S_ATTR_DEBUG,» 0}, |
| 185 {» ".debug_pubnames",» » "__debug_pubnames", |
| 186 » SEC_DEBUGGING,» » » BFD_MACH_O_S_REGULAR, |
| 187 » BFD_MACH_O_S_ATTR_DEBUG,» 0}, |
| 188 {» ".debug_pubtypes",» » "__debug_pubtypes", |
| 189 » SEC_DEBUGGING,» » » BFD_MACH_O_S_REGULAR, |
| 190 » BFD_MACH_O_S_ATTR_DEBUG,» 0}, |
| 191 {» ".debug_str",» » » "__debug_str", |
| 192 » SEC_DEBUGGING,» » » BFD_MACH_O_S_REGULAR, |
| 193 » BFD_MACH_O_S_ATTR_DEBUG,» 0}, |
| 194 {» ".debug_ranges",» » "__debug_ranges", |
| 195 » SEC_DEBUGGING,» » » BFD_MACH_O_S_REGULAR, |
| 196 » BFD_MACH_O_S_ATTR_DEBUG,» 0}, |
| 197 {» ".debug_macro",»» » "__debug_macro", |
| 198 » SEC_DEBUGGING,» » » BFD_MACH_O_S_REGULAR, |
| 199 » BFD_MACH_O_S_ATTR_DEBUG,» 0}, |
| 200 { NULL, NULL, 0, 0, 0, 0} |
| 201 }; |
| 202 |
| 203 /* __OBJC Segment. */ |
| 204 static const mach_o_section_name_xlat objc_section_names_xlat[] = |
| 205 { |
| 206 {» ".objc_class",» » » "__class", |
| 207 » SEC_DATA | SEC_LOAD,» » BFD_MACH_O_S_REGULAR, |
| 208 » BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0}, |
| 209 {» ".objc_meta_class",» » "__meta_class", |
| 210 » SEC_DATA | SEC_LOAD,» » BFD_MACH_O_S_REGULAR, |
| 211 » BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0}, |
| 212 {» ".objc_cat_cls_meth",» » "__cat_cls_meth", |
| 213 » SEC_DATA | SEC_LOAD,» » BFD_MACH_O_S_REGULAR, |
| 214 » BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0}, |
| 215 {» ".objc_cat_inst_meth",» » "__cat_inst_meth", |
| 216 » SEC_DATA | SEC_LOAD,» » BFD_MACH_O_S_REGULAR, |
| 217 » BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0}, |
| 218 {» ".objc_protocol",» » "__protocol", |
| 219 » SEC_DATA | SEC_LOAD,» » BFD_MACH_O_S_REGULAR, |
| 220 » BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0}, |
| 221 {» ".objc_string_object",» » "__string_object", |
| 222 » SEC_DATA | SEC_LOAD,» » BFD_MACH_O_S_REGULAR, |
| 223 » BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0}, |
| 224 {» ".objc_cls_meth",» » "__cls_meth", |
| 225 » SEC_DATA | SEC_LOAD,» » BFD_MACH_O_S_REGULAR, |
| 226 » BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0}, |
| 227 {» ".objc_inst_meth",» » "__inst_meth", |
| 228 » SEC_DATA | SEC_LOAD,» » BFD_MACH_O_S_REGULAR, |
| 229 » BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0}, |
| 230 {» ".objc_cls_refs",» » "__cls_refs", |
| 231 » SEC_DATA | SEC_LOAD,» » BFD_MACH_O_S_LITERAL_POINTERS, |
| 232 » BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0}, |
| 233 {» ".objc_message_refs",» » "__message_refs", |
| 234 » SEC_DATA | SEC_LOAD,» » BFD_MACH_O_S_LITERAL_POINTERS, |
| 235 » BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0}, |
| 236 {» ".objc_symbols",» » "__symbols", |
| 237 » SEC_DATA | SEC_LOAD,» » BFD_MACH_O_S_REGULAR, |
| 238 » BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0}, |
| 239 {» ".objc_category",» » "__category", |
| 240 » SEC_DATA | SEC_LOAD,» » BFD_MACH_O_S_REGULAR, |
| 241 » BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0}, |
| 242 {» ".objc_class_vars",» » "__class_vars", |
| 243 » SEC_DATA | SEC_LOAD,» » BFD_MACH_O_S_REGULAR, |
| 244 » BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0}, |
| 245 {» ".objc_instance_vars",» » "__instance_vars", |
| 246 » SEC_DATA | SEC_LOAD,» » BFD_MACH_O_S_REGULAR, |
| 247 » BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0}, |
| 248 {» ".objc_module_info",» » "__module_info", |
| 249 » SEC_DATA | SEC_LOAD,» » BFD_MACH_O_S_REGULAR, |
| 250 » BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0}, |
| 251 {» ".objc_selector_strs",» » "__selector_strs", |
| 252 » SEC_DATA | SEC_LOAD,» » BFD_MACH_O_S_CSTRING_LITERALS, |
| 253 » BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0}, |
| 254 {» ".objc_image_info",» » "__image_info", |
| 255 » SEC_DATA | SEC_LOAD,» » BFD_MACH_O_S_REGULAR, |
| 256 » BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0}, |
| 257 {» ".objc_selector_fixup",»» "__sel_fixup", |
| 258 » SEC_DATA | SEC_LOAD,» » BFD_MACH_O_S_REGULAR, |
| 259 » BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0}, |
| 260 /* Objc V1 */ |
| 261 {» ".objc1_class_ext",» » "__class_ext", |
| 262 » SEC_DATA | SEC_LOAD,» » BFD_MACH_O_S_REGULAR, |
| 263 » BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0}, |
| 264 {» ".objc1_property_list",»» "__property", |
| 265 » SEC_DATA | SEC_LOAD,» » BFD_MACH_O_S_REGULAR, |
| 266 » BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0}, |
| 267 {» ".objc1_protocol_ext",» » "__protocol_ext", |
| 268 » SEC_DATA | SEC_LOAD,» » BFD_MACH_O_S_REGULAR, |
| 269 » BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0}, |
| 270 { NULL, NULL, 0, 0, 0, 0} |
| 271 }; |
| 272 |
| 273 static const mach_o_segment_name_xlat segsec_names_xlat[] = |
145 { | 274 { |
146 { "__TEXT", text_section_names_xlat }, | 275 { "__TEXT", text_section_names_xlat }, |
147 { "__DATA", data_section_names_xlat }, | 276 { "__DATA", data_section_names_xlat }, |
148 { "__DWARF", dwarf_section_names_xlat }, | 277 { "__DWARF", dwarf_section_names_xlat }, |
| 278 { "__OBJC", objc_section_names_xlat }, |
149 { NULL, NULL } | 279 { NULL, NULL } |
150 }; | 280 }; |
151 | 281 |
152 /* Mach-O to bfd names. */ | 282 static const char dsym_subdir[] = ".dSYM/Contents/Resources/DWARF"; |
153 | 283 |
154 void | 284 /* For both cases bfd-name => mach-o name and vice versa, the specific target |
155 bfd_mach_o_normalize_section_name (const char *segname, const char *sectname, | 285 is checked before the generic. This allows a target (e.g. ppc for cstring) |
156 const char **name, flagword *flags) | 286 to override the generic definition with a more specific one. */ |
| 287 |
| 288 /* Fetch the translation from a Mach-O section designation (segment, section) |
| 289 as a bfd short name, if one exists. Otherwise return NULL. |
| 290 |
| 291 Allow the segment and section names to be unterminated 16 byte arrays. */ |
| 292 |
| 293 const mach_o_section_name_xlat * |
| 294 bfd_mach_o_section_data_for_mach_sect (bfd *abfd, const char *segname, |
| 295 » » » » const char *sectname) |
157 { | 296 { |
158 const struct mach_o_segment_name_xlat *seg; | 297 const struct mach_o_segment_name_xlat *seg; |
159 | 298 const mach_o_section_name_xlat *sec; |
160 *name = NULL; | 299 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd); |
161 *flags = SEC_NO_FLAGS; | 300 |
162 | 301 /* First try any target-specific translations defined... */ |
| 302 if (bed->segsec_names_xlat) |
| 303 for (seg = bed->segsec_names_xlat; seg->segname; seg++) |
| 304 if (strncmp (seg->segname, segname, BFD_MACH_O_SEGNAME_SIZE) == 0) |
| 305 » for (sec = seg->sections; sec->mach_o_name; sec++) |
| 306 » if (strncmp (sec->mach_o_name, sectname, |
| 307 » » BFD_MACH_O_SECTNAME_SIZE) == 0) |
| 308 » return sec; |
| 309 |
| 310 /* ... and then the Mach-O generic ones. */ |
163 for (seg = segsec_names_xlat; seg->segname; seg++) | 311 for (seg = segsec_names_xlat; seg->segname; seg++) |
164 { | 312 if (strncmp (seg->segname, segname, BFD_MACH_O_SEGNAME_SIZE) == 0) |
165 if (strncmp (seg->segname, segname, BFD_MACH_O_SEGNAME_SIZE) == 0) | 313 for (sec = seg->sections; sec->mach_o_name; sec++) |
166 { | 314 if (strncmp (sec->mach_o_name, sectname, |
167 const struct mach_o_section_name_xlat *sec; | 315 » » BFD_MACH_O_SECTNAME_SIZE) == 0) |
168 | 316 return sec; |
169 for (sec = seg->sections; sec->mach_o_name; sec++) | 317 |
170 { | 318 return NULL; |
171 if (strncmp (sec->mach_o_name, sectname, | |
172 BFD_MACH_O_SECTNAME_SIZE) == 0) | |
173 { | |
174 *name = sec->bfd_name; | |
175 *flags = sec->flags; | |
176 return; | |
177 } | |
178 } | |
179 return; | |
180 } | |
181 } | |
182 } | 319 } |
183 | 320 |
184 /* Convert Mach-O section name to BFD. Try to use standard names, otherwise | 321 /* If the bfd_name for this section is a 'canonical' form for which we |
185 forge a new name. SEGNAME and SECTNAME are 16 bytes strings. */ | 322 know the Mach-O data, return the segment name and the data for the |
186 | 323 Mach-O equivalent. Otherwise return NULL. */ |
187 static void | 324 |
188 bfd_mach_o_convert_section_name_to_bfd | 325 const mach_o_section_name_xlat * |
189 (bfd *abfd, const char *segname, const char *sectname, | 326 bfd_mach_o_section_data_for_bfd_name (bfd *abfd, const char *bfd_name, |
190 const char **name, flagword *flags) | 327 » » » » const char **segname) |
191 { | 328 { |
| 329 const struct mach_o_segment_name_xlat *seg; |
| 330 const mach_o_section_name_xlat *sec; |
| 331 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd); |
| 332 *segname = NULL; |
| 333 |
| 334 if (bfd_name[0] != '.') |
| 335 return NULL; |
| 336 |
| 337 /* First try any target-specific translations defined... */ |
| 338 if (bed->segsec_names_xlat) |
| 339 for (seg = bed->segsec_names_xlat; seg->segname; seg++) |
| 340 for (sec = seg->sections; sec->bfd_name; sec++) |
| 341 if (strcmp (bfd_name, sec->bfd_name) == 0) |
| 342 { |
| 343 *segname = seg->segname; |
| 344 return sec; |
| 345 } |
| 346 |
| 347 /* ... and then the Mach-O generic ones. */ |
| 348 for (seg = segsec_names_xlat; seg->segname; seg++) |
| 349 for (sec = seg->sections; sec->bfd_name; sec++) |
| 350 if (strcmp (bfd_name, sec->bfd_name) == 0) |
| 351 { |
| 352 *segname = seg->segname; |
| 353 return sec; |
| 354 } |
| 355 |
| 356 return NULL; |
| 357 } |
| 358 |
| 359 /* Convert Mach-O section name to BFD. |
| 360 |
| 361 Try to use standard/canonical names, for which we have tables including |
| 362 default flag settings - which are returned. Otherwise forge a new name |
| 363 in the form "<segmentname>.<sectionname>" this will be prefixed with |
| 364 LC_SEGMENT. if the segment name does not begin with an underscore. |
| 365 |
| 366 SEGNAME and SECTNAME are 16 byte arrays (they do not need to be NUL- |
| 367 terminated if the name length is exactly 16 bytes - but must be if the name |
| 368 length is less than 16 characters). */ |
| 369 |
| 370 void |
| 371 bfd_mach_o_convert_section_name_to_bfd (bfd *abfd, const char *segname, |
| 372 const char *secname, const char **name, |
| 373 flagword *flags) |
| 374 { |
| 375 const mach_o_section_name_xlat *xlat; |
192 char *res; | 376 char *res; |
193 unsigned int len; | 377 unsigned int len; |
194 const char *pfx = ""; | 378 const char *pfx = ""; |
195 | 379 |
196 /* First search for a canonical name. */ | 380 *name = NULL; |
197 bfd_mach_o_normalize_section_name (segname, sectname, name, flags); | 381 *flags = SEC_NO_FLAGS; |
198 | 382 |
199 /* Return now if found. */ | 383 /* First search for a canonical name... |
200 if (*name) | 384 xlat will be non-null if there is an entry for segname, secname. */ |
201 return; | 385 xlat = bfd_mach_o_section_data_for_mach_sect (abfd, segname, secname); |
| 386 if (xlat) |
| 387 { |
| 388 len = strlen (xlat->bfd_name); |
| 389 res = bfd_alloc (abfd, len+1); |
| 390 if (res == NULL) |
| 391 » return; |
| 392 memcpy (res, xlat->bfd_name, len+1); |
| 393 *name = res; |
| 394 *flags = xlat->bfd_flags; |
| 395 return; |
| 396 } |
| 397 |
| 398 /* ... else we make up a bfd name from the segment concatenated with the |
| 399 section. */ |
202 | 400 |
203 len = 16 + 1 + 16 + 1; | 401 len = 16 + 1 + 16 + 1; |
204 | 402 |
205 /* Put "LC_SEGMENT." prefix if the segment name is weird (ie doesn't start | 403 /* Put "LC_SEGMENT." prefix if the segment name is weird (ie doesn't start |
206 with an underscore. */ | 404 with an underscore. */ |
207 if (segname[0] != '_') | 405 if (segname[0] != '_') |
208 { | 406 { |
209 static const char seg_pfx[] = "LC_SEGMENT."; | 407 static const char seg_pfx[] = "LC_SEGMENT."; |
210 | 408 |
211 pfx = seg_pfx; | 409 pfx = seg_pfx; |
212 len += sizeof (seg_pfx) - 1; | 410 len += sizeof (seg_pfx) - 1; |
213 } | 411 } |
214 | 412 |
215 res = bfd_alloc (abfd, len); | 413 res = bfd_alloc (abfd, len); |
216 if (res == NULL) | 414 if (res == NULL) |
217 return; | 415 return; |
218 snprintf (res, len, "%s%.16s.%.16s", pfx, segname, sectname); | 416 snprintf (res, len, "%s%.16s.%.16s", pfx, segname, secname); |
219 *name = res; | 417 *name = res; |
220 *flags = SEC_NO_FLAGS; | |
221 } | 418 } |
222 | 419 |
223 /* Convert a bfd section name to a Mach-O segment + section name. */ | 420 /* Convert a bfd section name to a Mach-O segment + section name. |
224 | 421 |
225 static void | 422 If the name is a canonical one for which we have a Darwin match |
| 423 return the translation table - which contains defaults for flags, |
| 424 type, attribute and default alignment data. |
| 425 |
| 426 Otherwise, expand the bfd_name (assumed to be in the form |
| 427 "[LC_SEGMENT.]<segmentname>.<sectionname>") and return NULL. */ |
| 428 |
| 429 static const mach_o_section_name_xlat * |
226 bfd_mach_o_convert_section_name_to_mach_o (bfd *abfd ATTRIBUTE_UNUSED, | 430 bfd_mach_o_convert_section_name_to_mach_o (bfd *abfd ATTRIBUTE_UNUSED, |
227 asection *sect, | 431 asection *sect, |
228 bfd_mach_o_section *section) | 432 bfd_mach_o_section *section) |
229 { | 433 { |
230 const struct mach_o_segment_name_xlat *seg; | 434 const mach_o_section_name_xlat *xlat; |
231 const char *name = bfd_get_section_name (abfd, sect); | 435 const char *name = bfd_get_section_name (abfd, sect); |
| 436 const char *segname; |
232 const char *dot; | 437 const char *dot; |
233 unsigned int len; | 438 unsigned int len; |
234 unsigned int seglen; | 439 unsigned int seglen; |
235 unsigned int seclen; | 440 unsigned int seclen; |
236 | 441 |
237 /* List of well known names. They all start with a dot. */ | 442 memset (section->segname, 0, BFD_MACH_O_SEGNAME_SIZE + 1); |
238 if (name[0] == '.') | 443 memset (section->sectname, 0, BFD_MACH_O_SECTNAME_SIZE + 1); |
239 for (seg = segsec_names_xlat; seg->segname; seg++) | |
240 { | |
241 const struct mach_o_section_name_xlat *sec; | |
242 | 444 |
243 for (sec = seg->sections; sec->mach_o_name; sec++) | 445 /* See if is a canonical name ... */ |
244 { | 446 xlat = bfd_mach_o_section_data_for_bfd_name (abfd, name, &segname); |
245 if (strcmp (sec->bfd_name, name) == 0) | 447 if (xlat) |
246 { | 448 { |
247 strcpy (section->segname, seg->segname); | 449 strcpy (section->segname, segname); |
248 strcpy (section->sectname, sec->mach_o_name); | 450 strcpy (section->sectname, xlat->mach_o_name); |
249 return; | 451 return xlat; |
250 } | 452 } |
251 } | |
252 } | |
253 | 453 |
254 /* Strip LC_SEGMENT. prefix. */ | 454 /* .. else we convert our constructed one back to Mach-O. |
| 455 Strip LC_SEGMENT. prefix, if present. */ |
255 if (strncmp (name, "LC_SEGMENT.", 11) == 0) | 456 if (strncmp (name, "LC_SEGMENT.", 11) == 0) |
256 name += 11; | 457 name += 11; |
257 | 458 |
258 /* Find a dot. */ | 459 /* Find a dot. */ |
259 dot = strchr (name, '.'); | 460 dot = strchr (name, '.'); |
260 len = strlen (name); | 461 len = strlen (name); |
261 | 462 |
262 /* Try to split name into segment and section names. */ | 463 /* Try to split name into segment and section names. */ |
263 if (dot && dot != name) | 464 if (dot && dot != name) |
264 { | 465 { |
265 seglen = dot - name; | 466 seglen = dot - name; |
266 seclen = len - (dot + 1 - name); | 467 seclen = len - (dot + 1 - name); |
267 | 468 |
268 if (seglen < 16 && seclen < 16) | 469 if (seglen < 16 && seclen < 16) |
269 { | 470 { |
270 memcpy (section->segname, name, seglen); | 471 memcpy (section->segname, name, seglen); |
271 section->segname[seglen] = 0; | 472 section->segname[seglen] = 0; |
272 memcpy (section->sectname, dot + 1, seclen); | 473 memcpy (section->sectname, dot + 1, seclen); |
273 section->sectname[seclen] = 0; | 474 section->sectname[seclen] = 0; |
274 return; | 475 return NULL; |
275 } | 476 } |
276 } | 477 } |
277 | 478 |
| 479 /* The segment and section names are both missing - don't make them |
| 480 into dots. */ |
| 481 if (dot && dot == name) |
| 482 return NULL; |
| 483 |
| 484 /* Just duplicate the name into both segment and section. */ |
278 if (len > 16) | 485 if (len > 16) |
279 len = 16; | 486 len = 16; |
280 memcpy (section->segname, name, len); | 487 memcpy (section->segname, name, len); |
281 section->segname[len] = 0; | 488 section->segname[len] = 0; |
282 memcpy (section->sectname, name, len); | 489 memcpy (section->sectname, name, len); |
283 section->sectname[len] = 0; | 490 section->sectname[len] = 0; |
| 491 return NULL; |
284 } | 492 } |
285 | 493 |
286 /* Return the size of an entry for section SEC. | 494 /* Return the size of an entry for section SEC. |
287 Must be called only for symbol pointer section and symbol stubs | 495 Must be called only for symbol pointer section and symbol stubs |
288 sections. */ | 496 sections. */ |
289 | 497 |
290 unsigned int | 498 unsigned int |
291 bfd_mach_o_section_get_entry_size (bfd *abfd, bfd_mach_o_section *sec) | 499 bfd_mach_o_section_get_entry_size (bfd *abfd, bfd_mach_o_section *sec) |
292 { | 500 { |
293 switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK) | 501 switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK) |
(...skipping 24 matching lines...) Expand all Loading... |
318 else | 526 else |
319 return sec->size / elsz; | 527 return sec->size / elsz; |
320 } | 528 } |
321 | 529 |
322 | 530 |
323 /* Copy any private info we understand from the input symbol | 531 /* Copy any private info we understand from the input symbol |
324 to the output symbol. */ | 532 to the output symbol. */ |
325 | 533 |
326 bfd_boolean | 534 bfd_boolean |
327 bfd_mach_o_bfd_copy_private_symbol_data (bfd *ibfd ATTRIBUTE_UNUSED, | 535 bfd_mach_o_bfd_copy_private_symbol_data (bfd *ibfd ATTRIBUTE_UNUSED, |
328 » » » » » asymbol *isymbol ATTRIBUTE_UNUSED, | 536 » » » » » asymbol *isymbol, |
329 bfd *obfd ATTRIBUTE_UNUSED, | 537 bfd *obfd ATTRIBUTE_UNUSED, |
330 » » » » » asymbol *osymbol ATTRIBUTE_UNUSED) | 538 » » » » » asymbol *osymbol) |
331 { | 539 { |
| 540 bfd_mach_o_asymbol *os, *is; |
| 541 os = (bfd_mach_o_asymbol *)osymbol; |
| 542 is = (bfd_mach_o_asymbol *)isymbol; |
| 543 os->n_type = is->n_type; |
| 544 os->n_sect = is->n_sect; |
| 545 os->n_desc = is->n_desc; |
| 546 os->symbol.udata.i = is->symbol.udata.i; |
332 return TRUE; | 547 return TRUE; |
333 } | 548 } |
334 | 549 |
335 /* Copy any private info we understand from the input section | 550 /* Copy any private info we understand from the input section |
336 to the output section. */ | 551 to the output section. */ |
337 | 552 |
338 bfd_boolean | 553 bfd_boolean |
339 bfd_mach_o_bfd_copy_private_section_data (bfd *ibfd ATTRIBUTE_UNUSED, | 554 bfd_mach_o_bfd_copy_private_section_data (bfd *ibfd ATTRIBUTE_UNUSED, |
340 » » » » » asection *isection ATTRIBUTE_UNUSED, | 555 » » » » » asection *isection, |
341 bfd *obfd ATTRIBUTE_UNUSED, | 556 bfd *obfd ATTRIBUTE_UNUSED, |
342 » » » » » asection *osection ATTRIBUTE_UNUSED) | 557 » » » » » asection *osection) |
343 { | 558 { |
| 559 if (osection->used_by_bfd == NULL) |
| 560 osection->used_by_bfd = isection->used_by_bfd; |
| 561 else |
| 562 if (isection->used_by_bfd != NULL) |
| 563 memcpy (osection->used_by_bfd, isection->used_by_bfd, |
| 564 sizeof (bfd_mach_o_section)); |
| 565 |
| 566 if (osection->used_by_bfd != NULL) |
| 567 ((bfd_mach_o_section *)osection->used_by_bfd)->bfdsection = osection; |
| 568 |
344 return TRUE; | 569 return TRUE; |
345 } | 570 } |
346 | 571 |
347 /* Copy any private info we understand from the input bfd | 572 /* Copy any private info we understand from the input bfd |
348 to the output bfd. */ | 573 to the output bfd. */ |
349 | 574 |
350 bfd_boolean | 575 bfd_boolean |
351 bfd_mach_o_bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd) | 576 bfd_mach_o_bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd) |
352 { | 577 { |
353 if (bfd_get_flavour (ibfd) != bfd_target_mach_o_flavour | 578 if (bfd_get_flavour (ibfd) != bfd_target_mach_o_flavour |
354 || bfd_get_flavour (obfd) != bfd_target_mach_o_flavour) | 579 || bfd_get_flavour (obfd) != bfd_target_mach_o_flavour) |
355 return TRUE; | 580 return TRUE; |
356 | 581 |
357 BFD_ASSERT (bfd_mach_o_valid (ibfd)); | 582 BFD_ASSERT (bfd_mach_o_valid (ibfd)); |
358 BFD_ASSERT (bfd_mach_o_valid (obfd)); | 583 BFD_ASSERT (bfd_mach_o_valid (obfd)); |
359 | 584 |
360 /* FIXME: copy commands. */ | 585 /* FIXME: copy commands. */ |
361 | 586 |
362 return TRUE; | 587 return TRUE; |
363 } | 588 } |
364 | 589 |
| 590 /* This allows us to set up to 32 bits of flags (unless we invent some |
| 591 fiendish scheme to subdivide). For now, we'll just set the file flags |
| 592 without error checking - just overwrite. */ |
| 593 |
| 594 bfd_boolean |
| 595 bfd_mach_o_bfd_set_private_flags (bfd *abfd, flagword flags) |
| 596 { |
| 597 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd); |
| 598 |
| 599 if (!mdata) |
| 600 return FALSE; |
| 601 |
| 602 mdata->header.flags = flags; |
| 603 return TRUE; |
| 604 } |
| 605 |
365 /* Count the total number of symbols. */ | 606 /* Count the total number of symbols. */ |
366 | 607 |
367 static long | 608 static long |
368 bfd_mach_o_count_symbols (bfd *abfd) | 609 bfd_mach_o_count_symbols (bfd *abfd) |
369 { | 610 { |
370 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd); | 611 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd); |
371 | 612 |
372 if (mdata->symtab == NULL) | 613 if (mdata->symtab == NULL) |
373 return 0; | 614 return 0; |
374 return mdata->symtab->nsyms; | 615 return mdata->symtab->nsyms; |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
410 BFD_ASSERT (sym->symbols != NULL); | 651 BFD_ASSERT (sym->symbols != NULL); |
411 | 652 |
412 for (j = 0; j < sym->nsyms; j++) | 653 for (j = 0; j < sym->nsyms; j++) |
413 alocation[j] = &sym->symbols[j].symbol; | 654 alocation[j] = &sym->symbols[j].symbol; |
414 | 655 |
415 alocation[j] = NULL; | 656 alocation[j] = NULL; |
416 | 657 |
417 return nsyms; | 658 return nsyms; |
418 } | 659 } |
419 | 660 |
| 661 /* Create synthetic symbols for indirect symbols. */ |
| 662 |
420 long | 663 long |
421 bfd_mach_o_get_synthetic_symtab (bfd *abfd, | 664 bfd_mach_o_get_synthetic_symtab (bfd *abfd, |
422 long symcount ATTRIBUTE_UNUSED, | 665 long symcount ATTRIBUTE_UNUSED, |
423 asymbol **syms ATTRIBUTE_UNUSED, | 666 asymbol **syms ATTRIBUTE_UNUSED, |
424 long dynsymcount ATTRIBUTE_UNUSED, | 667 long dynsymcount ATTRIBUTE_UNUSED, |
425 asymbol **dynsyms ATTRIBUTE_UNUSED, | 668 asymbol **dynsyms ATTRIBUTE_UNUSED, |
426 asymbol **ret) | 669 asymbol **ret) |
427 { | 670 { |
428 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd); | 671 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd); |
429 bfd_mach_o_dysymtab_command *dysymtab = mdata->dysymtab; | 672 bfd_mach_o_dysymtab_command *dysymtab = mdata->dysymtab; |
430 bfd_mach_o_symtab_command *symtab = mdata->symtab; | 673 bfd_mach_o_symtab_command *symtab = mdata->symtab; |
431 asymbol *s; | 674 asymbol *s; |
432 unsigned long count, i, j, n; | 675 unsigned long count, i, j, n; |
433 size_t size; | 676 size_t size; |
434 char *names; | 677 char *names; |
435 char *nul_name; | 678 char *nul_name; |
436 | 679 |
437 *ret = NULL; | 680 *ret = NULL; |
438 | 681 |
| 682 /* Stop now if no symbols or no indirect symbols. */ |
439 if (dysymtab == NULL || symtab == NULL || symtab->symbols == NULL) | 683 if (dysymtab == NULL || symtab == NULL || symtab->symbols == NULL) |
440 return 0; | 684 return 0; |
441 | 685 |
442 if (dysymtab->nindirectsyms == 0) | 686 if (dysymtab->nindirectsyms == 0) |
443 return 0; | 687 return 0; |
444 | 688 |
| 689 /* We need to allocate a bfd symbol for every indirect symbol and to |
| 690 allocate the memory for its name. */ |
445 count = dysymtab->nindirectsyms; | 691 count = dysymtab->nindirectsyms; |
446 size = count * sizeof (asymbol) + 1; | 692 size = count * sizeof (asymbol) + 1; |
447 | 693 |
448 for (j = 0; j < count; j++) | 694 for (j = 0; j < count; j++) |
449 { | 695 { |
450 unsigned int isym = dysymtab->indirect_syms[j]; | 696 unsigned int isym = dysymtab->indirect_syms[j]; |
451 | 697 |
| 698 /* Some indirect symbols are anonymous. */ |
452 if (isym < symtab->nsyms && symtab->symbols[isym].symbol.name) | 699 if (isym < symtab->nsyms && symtab->symbols[isym].symbol.name) |
453 size += strlen (symtab->symbols[isym].symbol.name) + sizeof ("$stub"); | 700 size += strlen (symtab->symbols[isym].symbol.name) + sizeof ("$stub"); |
454 } | 701 } |
455 | 702 |
456 s = *ret = (asymbol *) bfd_malloc (size); | 703 s = *ret = (asymbol *) bfd_malloc (size); |
457 if (s == NULL) | 704 if (s == NULL) |
458 return -1; | 705 return -1; |
459 names = (char *) (s + count); | 706 names = (char *) (s + count); |
460 nul_name = names; | 707 nul_name = names; |
461 *names++ = 0; | 708 *names++ = 0; |
462 | 709 |
463 n = 0; | 710 n = 0; |
464 for (i = 0; i < mdata->nsects; i++) | 711 for (i = 0; i < mdata->nsects; i++) |
465 { | 712 { |
466 bfd_mach_o_section *sec = mdata->sections[i]; | 713 bfd_mach_o_section *sec = mdata->sections[i]; |
467 unsigned int first, last; | 714 unsigned int first, last; |
468 bfd_vma addr; | 715 bfd_vma addr; |
469 bfd_vma entry_size; | 716 bfd_vma entry_size; |
470 | 717 |
471 switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK) | 718 switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK) |
472 { | 719 { |
473 case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS: | 720 case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS: |
474 case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS: | 721 case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS: |
475 case BFD_MACH_O_S_SYMBOL_STUBS: | 722 case BFD_MACH_O_S_SYMBOL_STUBS: |
| 723 /* Only these sections have indirect symbols. */ |
476 first = sec->reserved1; | 724 first = sec->reserved1; |
477 last = first + bfd_mach_o_section_get_nbr_indirect (abfd, sec); | 725 last = first + bfd_mach_o_section_get_nbr_indirect (abfd, sec); |
478 addr = sec->addr; | 726 addr = sec->addr; |
479 entry_size = bfd_mach_o_section_get_entry_size (abfd, sec); | 727 entry_size = bfd_mach_o_section_get_entry_size (abfd, sec); |
480 for (j = first; j < last; j++) | 728 for (j = first; j < last; j++) |
481 { | 729 { |
482 unsigned int isym = dysymtab->indirect_syms[j]; | 730 unsigned int isym = dysymtab->indirect_syms[j]; |
483 | 731 |
484 s->flags = BSF_GLOBAL | BSF_SYNTHETIC; | 732 s->flags = BSF_GLOBAL | BSF_SYNTHETIC; |
485 s->section = sec->bfdsection; | 733 s->section = sec->bfdsection; |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
573 asym->n_type, name, asym->n_sect, asym->n_desc); | 821 asym->n_type, name, asym->n_sect, asym->n_desc); |
574 if ((asym->n_type & BFD_MACH_O_N_STAB) == 0 | 822 if ((asym->n_type & BFD_MACH_O_N_STAB) == 0 |
575 && (asym->n_type & BFD_MACH_O_N_TYPE) == BFD_MACH_O_N_SECT) | 823 && (asym->n_type & BFD_MACH_O_N_TYPE) == BFD_MACH_O_N_SECT) |
576 fprintf (file, " [%s]", symbol->section->name); | 824 fprintf (file, " [%s]", symbol->section->name); |
577 fprintf (file, " %s", symbol->name); | 825 fprintf (file, " %s", symbol->name); |
578 } | 826 } |
579 } | 827 } |
580 | 828 |
581 static void | 829 static void |
582 bfd_mach_o_convert_architecture (bfd_mach_o_cpu_type mtype, | 830 bfd_mach_o_convert_architecture (bfd_mach_o_cpu_type mtype, |
583 » » » » bfd_mach_o_cpu_subtype msubtype ATTRIBUTE_UNUSE
D, | 831 » » » » bfd_mach_o_cpu_subtype msubtype, |
584 enum bfd_architecture *type, | 832 enum bfd_architecture *type, |
585 unsigned long *subtype) | 833 unsigned long *subtype) |
586 { | 834 { |
587 *subtype = bfd_arch_unknown; | 835 *subtype = bfd_arch_unknown; |
588 | 836 |
589 switch (mtype) | 837 switch (mtype) |
590 { | 838 { |
591 case BFD_MACH_O_CPU_TYPE_VAX: *type = bfd_arch_vax; break; | 839 case BFD_MACH_O_CPU_TYPE_VAX: |
592 case BFD_MACH_O_CPU_TYPE_MC680x0: *type = bfd_arch_m68k; break; | 840 *type = bfd_arch_vax; |
| 841 break; |
| 842 case BFD_MACH_O_CPU_TYPE_MC680x0: |
| 843 *type = bfd_arch_m68k; |
| 844 break; |
593 case BFD_MACH_O_CPU_TYPE_I386: | 845 case BFD_MACH_O_CPU_TYPE_I386: |
594 *type = bfd_arch_i386; | 846 *type = bfd_arch_i386; |
595 *subtype = bfd_mach_i386_i386; | 847 *subtype = bfd_mach_i386_i386; |
596 break; | 848 break; |
597 case BFD_MACH_O_CPU_TYPE_X86_64: | 849 case BFD_MACH_O_CPU_TYPE_X86_64: |
598 *type = bfd_arch_i386; | 850 *type = bfd_arch_i386; |
599 *subtype = bfd_mach_x86_64; | 851 *subtype = bfd_mach_x86_64; |
600 break; | 852 break; |
601 case BFD_MACH_O_CPU_TYPE_MIPS: *type = bfd_arch_mips; break; | 853 case BFD_MACH_O_CPU_TYPE_MIPS: |
602 case BFD_MACH_O_CPU_TYPE_MC98000: *type = bfd_arch_m98k; break; | 854 *type = bfd_arch_mips; |
603 case BFD_MACH_O_CPU_TYPE_HPPA: *type = bfd_arch_hppa; break; | 855 break; |
604 case BFD_MACH_O_CPU_TYPE_ARM: *type = bfd_arch_arm; break; | 856 case BFD_MACH_O_CPU_TYPE_MC98000: |
605 case BFD_MACH_O_CPU_TYPE_MC88000: *type = bfd_arch_m88k; break; | 857 *type = bfd_arch_m98k; |
| 858 break; |
| 859 case BFD_MACH_O_CPU_TYPE_HPPA: |
| 860 *type = bfd_arch_hppa; |
| 861 break; |
| 862 case BFD_MACH_O_CPU_TYPE_ARM: |
| 863 *type = bfd_arch_arm; |
| 864 switch (msubtype) |
| 865 { |
| 866 case BFD_MACH_O_CPU_SUBTYPE_ARM_V4T: |
| 867 *subtype = bfd_mach_arm_4T; |
| 868 break; |
| 869 case BFD_MACH_O_CPU_SUBTYPE_ARM_V6: |
| 870 *subtype = bfd_mach_arm_4T;» /* Best fit ? */ |
| 871 break; |
| 872 case BFD_MACH_O_CPU_SUBTYPE_ARM_V5TEJ: |
| 873 *subtype = bfd_mach_arm_5TE; |
| 874 break; |
| 875 case BFD_MACH_O_CPU_SUBTYPE_ARM_XSCALE: |
| 876 *subtype = bfd_mach_arm_XScale; |
| 877 break; |
| 878 case BFD_MACH_O_CPU_SUBTYPE_ARM_V7: |
| 879 *subtype = bfd_mach_arm_5TE;» /* Best fit ? */ |
| 880 break; |
| 881 case BFD_MACH_O_CPU_SUBTYPE_ARM_ALL: |
| 882 default: |
| 883 break; |
| 884 } |
| 885 break; |
| 886 case BFD_MACH_O_CPU_TYPE_MC88000: |
| 887 *type = bfd_arch_m88k; |
| 888 break; |
606 case BFD_MACH_O_CPU_TYPE_SPARC: | 889 case BFD_MACH_O_CPU_TYPE_SPARC: |
607 *type = bfd_arch_sparc; | 890 *type = bfd_arch_sparc; |
608 *subtype = bfd_mach_sparc; | 891 *subtype = bfd_mach_sparc; |
609 break; | 892 break; |
610 case BFD_MACH_O_CPU_TYPE_I860: *type = bfd_arch_i860; break; | 893 case BFD_MACH_O_CPU_TYPE_I860: |
611 case BFD_MACH_O_CPU_TYPE_ALPHA: *type = bfd_arch_alpha; break; | 894 *type = bfd_arch_i860; |
| 895 break; |
| 896 case BFD_MACH_O_CPU_TYPE_ALPHA: |
| 897 *type = bfd_arch_alpha; |
| 898 break; |
612 case BFD_MACH_O_CPU_TYPE_POWERPC: | 899 case BFD_MACH_O_CPU_TYPE_POWERPC: |
613 *type = bfd_arch_powerpc; | 900 *type = bfd_arch_powerpc; |
614 *subtype = bfd_mach_ppc; | 901 *subtype = bfd_mach_ppc; |
615 break; | 902 break; |
616 case BFD_MACH_O_CPU_TYPE_POWERPC_64: | 903 case BFD_MACH_O_CPU_TYPE_POWERPC_64: |
617 *type = bfd_arch_powerpc; | 904 *type = bfd_arch_powerpc; |
618 *subtype = bfd_mach_ppc64; | 905 *subtype = bfd_mach_ppc64; |
619 break; | 906 break; |
620 default: | 907 default: |
621 *type = bfd_arch_unknown; | 908 *type = bfd_arch_unknown; |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
681 return 0; | 968 return 0; |
682 } | 969 } |
683 | 970 |
684 long | 971 long |
685 bfd_mach_o_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED, | 972 bfd_mach_o_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED, |
686 asection *asect) | 973 asection *asect) |
687 { | 974 { |
688 return (asect->reloc_count + 1) * sizeof (arelent *); | 975 return (asect->reloc_count + 1) * sizeof (arelent *); |
689 } | 976 } |
690 | 977 |
| 978 /* In addition to the need to byte-swap the symbol number, the bit positions |
| 979 of the fields in the relocation information vary per target endian-ness. */ |
| 980 |
| 981 static void |
| 982 bfd_mach_o_swap_in_non_scattered_reloc (bfd *abfd, bfd_mach_o_reloc_info *rel, |
| 983 unsigned char *fields) |
| 984 { |
| 985 unsigned char info = fields[3]; |
| 986 |
| 987 if (bfd_big_endian (abfd)) |
| 988 { |
| 989 rel->r_value = (fields[0] << 16) | (fields[1] << 8) | fields[2]; |
| 990 rel->r_type = (info >> BFD_MACH_O_BE_TYPE_SHIFT) & BFD_MACH_O_TYPE_MASK; |
| 991 rel->r_pcrel = (info & BFD_MACH_O_BE_PCREL) ? 1 : 0; |
| 992 rel->r_length = (info >> BFD_MACH_O_BE_LENGTH_SHIFT) |
| 993 & BFD_MACH_O_LENGTH_MASK; |
| 994 rel->r_extern = (info & BFD_MACH_O_BE_EXTERN) ? 1 : 0; |
| 995 } |
| 996 else |
| 997 { |
| 998 rel->r_value = (fields[2] << 16) | (fields[1] << 8) | fields[0]; |
| 999 rel->r_type = (info >> BFD_MACH_O_LE_TYPE_SHIFT) & BFD_MACH_O_TYPE_MASK; |
| 1000 rel->r_pcrel = (info & BFD_MACH_O_LE_PCREL) ? 1 : 0; |
| 1001 rel->r_length = (info >> BFD_MACH_O_LE_LENGTH_SHIFT) |
| 1002 & BFD_MACH_O_LENGTH_MASK; |
| 1003 rel->r_extern = (info & BFD_MACH_O_LE_EXTERN) ? 1 : 0; |
| 1004 } |
| 1005 } |
| 1006 |
691 static int | 1007 static int |
692 bfd_mach_o_canonicalize_one_reloc (bfd *abfd, | 1008 bfd_mach_o_canonicalize_one_reloc (bfd *abfd, |
693 struct mach_o_reloc_info_external *raw, | 1009 struct mach_o_reloc_info_external *raw, |
694 arelent *res, asymbol **syms) | 1010 arelent *res, asymbol **syms) |
695 { | 1011 { |
696 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd); | 1012 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd); |
697 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd); | 1013 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd); |
698 bfd_mach_o_reloc_info reloc; | 1014 bfd_mach_o_reloc_info reloc; |
699 bfd_vma addr; | 1015 bfd_vma addr; |
700 bfd_vma symnum; | |
701 asymbol **sym; | 1016 asymbol **sym; |
702 | 1017 |
703 addr = bfd_get_32 (abfd, raw->r_address); | 1018 addr = bfd_get_32 (abfd, raw->r_address); |
704 symnum = bfd_get_32 (abfd, raw->r_symbolnum); | 1019 res->sym_ptr_ptr = NULL; |
| 1020 res->addend = 0; |
705 | 1021 |
706 if (addr & BFD_MACH_O_SR_SCATTERED) | 1022 if (addr & BFD_MACH_O_SR_SCATTERED) |
707 { | 1023 { |
708 unsigned int j; | 1024 unsigned int j; |
| 1025 bfd_vma symnum = bfd_get_32 (abfd, raw->r_symbolnum); |
709 | 1026 |
710 /* Scattered relocation. | 1027 /* Scattered relocation, can't be extern. */ |
711 Extract section and offset from r_value. */ | 1028 reloc.r_scattered = 1; |
712 res->sym_ptr_ptr = NULL; | 1029 reloc.r_extern = 0; |
713 res->addend = 0; | 1030 |
| 1031 /* Extract section and offset from r_value (symnum). */ |
| 1032 reloc.r_value = symnum; |
| 1033 /* FIXME: This breaks when a symbol in a reloc exactly follows the |
| 1034 » end of the data for the section (e.g. in a calculation of section |
| 1035 » data length). At present, the symbol will end up associated with |
| 1036 » the following section or, if it falls within alignment padding, as |
| 1037 » null - which will assert later. */ |
714 for (j = 0; j < mdata->nsects; j++) | 1038 for (j = 0; j < mdata->nsects; j++) |
715 { | 1039 { |
716 bfd_mach_o_section *sect = mdata->sections[j]; | 1040 bfd_mach_o_section *sect = mdata->sections[j]; |
717 if (symnum >= sect->addr && symnum < sect->addr + sect->size) | 1041 if (symnum >= sect->addr && symnum < sect->addr + sect->size) |
718 { | 1042 { |
719 res->sym_ptr_ptr = sect->bfdsection->symbol_ptr_ptr; | 1043 res->sym_ptr_ptr = sect->bfdsection->symbol_ptr_ptr; |
720 res->addend = symnum - sect->addr; | 1044 res->addend = symnum - sect->addr; |
721 break; | 1045 break; |
722 } | 1046 } |
723 } | 1047 } |
724 res->address = BFD_MACH_O_GET_SR_ADDRESS (addr); | 1048 |
| 1049 /* Extract the info and address fields from r_address. */ |
725 reloc.r_type = BFD_MACH_O_GET_SR_TYPE (addr); | 1050 reloc.r_type = BFD_MACH_O_GET_SR_TYPE (addr); |
726 reloc.r_length = BFD_MACH_O_GET_SR_LENGTH (addr); | 1051 reloc.r_length = BFD_MACH_O_GET_SR_LENGTH (addr); |
727 reloc.r_pcrel = addr & BFD_MACH_O_SR_PCREL; | 1052 reloc.r_pcrel = addr & BFD_MACH_O_SR_PCREL; |
728 reloc.r_scattered = 1; | 1053 reloc.r_address = BFD_MACH_O_GET_SR_TYPE (addr); |
| 1054 res->address = BFD_MACH_O_GET_SR_ADDRESS (addr); |
729 } | 1055 } |
730 else | 1056 else |
731 { | 1057 { |
732 unsigned int num = BFD_MACH_O_GET_R_SYMBOLNUM (symnum); | 1058 unsigned int num; |
733 res->addend = 0; | 1059 |
734 res->address = addr; | 1060 /* Non-scattered relocation. */ |
735 if (symnum & BFD_MACH_O_R_EXTERN) | 1061 reloc.r_scattered = 0; |
736 { | 1062 |
| 1063 /* The value and info fields have to be extracted dependent on target |
| 1064 endian-ness. */ |
| 1065 bfd_mach_o_swap_in_non_scattered_reloc (abfd, &reloc, raw->r_symbolnum); |
| 1066 num = reloc.r_value; |
| 1067 |
| 1068 if (reloc.r_extern) |
737 sym = syms + num; | 1069 sym = syms + num; |
738 reloc.r_extern = 1; | 1070 else if (reloc.r_scattered |
739 } | 1071 » || (reloc.r_type != BFD_MACH_O_GENERIC_RELOC_PAIR)) |
740 else | |
741 { | 1072 { |
742 BFD_ASSERT (num != 0); | 1073 BFD_ASSERT (num != 0); |
743 BFD_ASSERT (num <= mdata->nsects); | 1074 BFD_ASSERT (num <= mdata->nsects); |
744 sym = mdata->sections[num - 1]->bfdsection->symbol_ptr_ptr; | 1075 sym = mdata->sections[num - 1]->bfdsection->symbol_ptr_ptr; |
745 /* For a symbol defined in section S, the addend (stored in the | 1076 /* For a symbol defined in section S, the addend (stored in the |
746 binary) contains the address of the section. To comply with | 1077 binary) contains the address of the section. To comply with |
747 bfd conventio, substract the section address. | 1078 bfd convention, subtract the section address. |
748 Use the address from the header, so that the user can modify | 1079 Use the address from the header, so that the user can modify |
749 the vma of the section. */ | 1080 the vma of the section. */ |
750 res->addend = -mdata->sections[num - 1]->addr; | 1081 res->addend = -mdata->sections[num - 1]->addr; |
751 reloc.r_extern = 0; | 1082 } |
| 1083 else /* ... The 'symnum' in a non-scattered PAIR will be 0x00ffffff. */ |
| 1084 { |
| 1085 /* Pairs for PPC LO/HI/HA are not scattered, but contain the offset |
| 1086 in the lower 16bits of the address value. So we have to find the |
| 1087 'symbol' from the preceding reloc. We do this even thoough the |
| 1088 section symbol is probably not needed here, because NULL symbol |
| 1089 values cause an assert in generic BFD code. */ |
| 1090 sym = (res - 1)->sym_ptr_ptr; |
752 } | 1091 } |
753 res->sym_ptr_ptr = sym; | 1092 res->sym_ptr_ptr = sym; |
754 reloc.r_type = BFD_MACH_O_GET_R_TYPE (symnum); | 1093 |
755 reloc.r_length = BFD_MACH_O_GET_R_LENGTH (symnum); | 1094 /* The 'address' is just r_address. |
756 reloc.r_pcrel = (symnum & BFD_MACH_O_R_PCREL) ? 1 : 0; | 1095 ??? maybe this should be masked with 0xffffff for safety. */ |
757 reloc.r_scattered = 0; | 1096 res->address = addr; |
| 1097 reloc.r_address = addr; |
758 } | 1098 } |
759 | 1099 |
| 1100 /* We have set up a reloc with all the information present, so the swapper can |
| 1101 modify address, value and addend fields, if necessary, to convey informatio
n |
| 1102 in the generic BFD reloc that is mach-o specific. */ |
| 1103 |
760 if (!(*bed->_bfd_mach_o_swap_reloc_in)(res, &reloc)) | 1104 if (!(*bed->_bfd_mach_o_swap_reloc_in)(res, &reloc)) |
761 return -1; | 1105 return -1; |
762 return 0; | 1106 return 0; |
763 } | 1107 } |
764 | 1108 |
765 static int | 1109 static int |
766 bfd_mach_o_canonicalize_relocs (bfd *abfd, unsigned long filepos, | 1110 bfd_mach_o_canonicalize_relocs (bfd *abfd, unsigned long filepos, |
767 unsigned long count, | 1111 unsigned long count, |
768 arelent *res, asymbol **syms) | 1112 arelent *res, asymbol **syms) |
769 { | 1113 { |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
803 unsigned long i; | 1147 unsigned long i; |
804 arelent *res; | 1148 arelent *res; |
805 | 1149 |
806 if (asect->reloc_count == 0) | 1150 if (asect->reloc_count == 0) |
807 return 0; | 1151 return 0; |
808 | 1152 |
809 /* No need to go further if we don't know how to read relocs. */ | 1153 /* No need to go further if we don't know how to read relocs. */ |
810 if (bed->_bfd_mach_o_swap_reloc_in == NULL) | 1154 if (bed->_bfd_mach_o_swap_reloc_in == NULL) |
811 return 0; | 1155 return 0; |
812 | 1156 |
813 res = bfd_malloc (asect->reloc_count * sizeof (arelent)); | 1157 if (asect->relocation == NULL) |
814 if (res == NULL) | 1158 { |
815 return -1; | 1159 res = bfd_malloc (asect->reloc_count * sizeof (arelent)); |
| 1160 if (res == NULL) |
| 1161 return -1; |
816 | 1162 |
817 if (bfd_mach_o_canonicalize_relocs (abfd, asect->rel_filepos, | 1163 if (bfd_mach_o_canonicalize_relocs (abfd, asect->rel_filepos, |
818 asect->reloc_count, res, syms) < 0) | 1164 asect->reloc_count, res, syms) < 0) |
819 { | 1165 { |
820 free (res); | 1166 free (res); |
821 return -1; | 1167 return -1; |
| 1168 } |
| 1169 asect->relocation = res; |
822 } | 1170 } |
823 | 1171 |
| 1172 res = asect->relocation; |
824 for (i = 0; i < asect->reloc_count; i++) | 1173 for (i = 0; i < asect->reloc_count; i++) |
825 rels[i] = &res[i]; | 1174 rels[i] = &res[i]; |
826 rels[i] = NULL; | 1175 rels[i] = NULL; |
827 asect->relocation = res; | |
828 | 1176 |
829 return i; | 1177 return i; |
830 } | 1178 } |
831 | 1179 |
832 long | 1180 long |
833 bfd_mach_o_get_dynamic_reloc_upper_bound (bfd *abfd) | 1181 bfd_mach_o_get_dynamic_reloc_upper_bound (bfd *abfd) |
834 { | 1182 { |
835 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd); | 1183 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd); |
836 | 1184 |
837 if (mdata->dysymtab == NULL) | 1185 if (mdata->dysymtab == NULL) |
838 return 1; | 1186 return 1; |
839 return (mdata->dysymtab->nextrel + mdata->dysymtab->nlocrel) | 1187 return (mdata->dysymtab->nextrel + mdata->dysymtab->nlocrel + 1) |
840 * sizeof (arelent *); | 1188 * sizeof (arelent *); |
841 } | 1189 } |
842 | 1190 |
843 long | 1191 long |
844 bfd_mach_o_canonicalize_dynamic_reloc (bfd *abfd, arelent **rels, | 1192 bfd_mach_o_canonicalize_dynamic_reloc (bfd *abfd, arelent **rels, |
845 struct bfd_symbol **syms) | 1193 struct bfd_symbol **syms) |
846 { | 1194 { |
847 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd); | 1195 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd); |
848 bfd_mach_o_dysymtab_command *dysymtab = mdata->dysymtab; | 1196 bfd_mach_o_dysymtab_command *dysymtab = mdata->dysymtab; |
849 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd); | 1197 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd); |
850 unsigned long i; | 1198 unsigned long i; |
851 arelent *res; | 1199 arelent *res; |
852 | 1200 |
853 if (dysymtab == NULL) | 1201 if (dysymtab == NULL) |
854 return 0; | 1202 return 0; |
855 if (dysymtab->nextrel == 0 && dysymtab->nlocrel == 0) | 1203 if (dysymtab->nextrel == 0 && dysymtab->nlocrel == 0) |
856 return 0; | 1204 return 0; |
857 | 1205 |
858 /* No need to go further if we don't know how to read relocs. */ | 1206 /* No need to go further if we don't know how to read relocs. */ |
859 if (bed->_bfd_mach_o_swap_reloc_in == NULL) | 1207 if (bed->_bfd_mach_o_swap_reloc_in == NULL) |
860 return 0; | 1208 return 0; |
861 | 1209 |
862 res = bfd_malloc ((dysymtab->nextrel + dysymtab->nlocrel) * sizeof (arelent)); | 1210 if (mdata->dyn_reloc_cache == NULL) |
863 if (res == NULL) | 1211 { |
864 return -1; | 1212 res = bfd_malloc ((dysymtab->nextrel + dysymtab->nlocrel) |
| 1213 * sizeof (arelent)); |
| 1214 if (res == NULL) |
| 1215 return -1; |
865 | 1216 |
866 if (bfd_mach_o_canonicalize_relocs (abfd, dysymtab->extreloff, | 1217 if (bfd_mach_o_canonicalize_relocs (abfd, dysymtab->extreloff, |
867 dysymtab->nextrel, res, syms) < 0) | 1218 dysymtab->nextrel, res, syms) < 0) |
868 { | 1219 { |
869 free (res); | 1220 free (res); |
870 return -1; | 1221 return -1; |
| 1222 } |
| 1223 |
| 1224 if (bfd_mach_o_canonicalize_relocs (abfd, dysymtab->locreloff, |
| 1225 dysymtab->nlocrel, |
| 1226 res + dysymtab->nextrel, syms) < 0) |
| 1227 { |
| 1228 free (res); |
| 1229 return -1; |
| 1230 } |
| 1231 |
| 1232 mdata->dyn_reloc_cache = res; |
871 } | 1233 } |
872 | 1234 |
873 if (bfd_mach_o_canonicalize_relocs (abfd, dysymtab->locreloff, | 1235 res = mdata->dyn_reloc_cache; |
874 dysymtab->nlocrel, | |
875 res + dysymtab->nextrel, syms) < 0) | |
876 { | |
877 free (res); | |
878 return -1; | |
879 } | |
880 | |
881 for (i = 0; i < dysymtab->nextrel + dysymtab->nlocrel; i++) | 1236 for (i = 0; i < dysymtab->nextrel + dysymtab->nlocrel; i++) |
882 rels[i] = &res[i]; | 1237 rels[i] = &res[i]; |
883 rels[i] = NULL; | 1238 rels[i] = NULL; |
884 return i; | 1239 return i; |
885 } | 1240 } |
886 | 1241 |
| 1242 /* In addition to the need to byte-swap the symbol number, the bit positions |
| 1243 of the fields in the relocation information vary per target endian-ness. */ |
| 1244 |
| 1245 static void |
| 1246 bfd_mach_o_swap_out_non_scattered_reloc (bfd *abfd, unsigned char *fields, |
| 1247 bfd_mach_o_reloc_info *rel) |
| 1248 { |
| 1249 unsigned char info = 0; |
| 1250 |
| 1251 BFD_ASSERT (rel->r_type <= 15); |
| 1252 BFD_ASSERT (rel->r_length <= 3); |
| 1253 |
| 1254 if (bfd_big_endian (abfd)) |
| 1255 { |
| 1256 fields[0] = (rel->r_value >> 16) & 0xff; |
| 1257 fields[1] = (rel->r_value >> 8) & 0xff; |
| 1258 fields[2] = rel->r_value & 0xff; |
| 1259 info |= rel->r_type << BFD_MACH_O_BE_TYPE_SHIFT; |
| 1260 info |= rel->r_pcrel ? BFD_MACH_O_BE_PCREL : 0; |
| 1261 info |= rel->r_length << BFD_MACH_O_BE_LENGTH_SHIFT; |
| 1262 info |= rel->r_extern ? BFD_MACH_O_BE_EXTERN : 0; |
| 1263 } |
| 1264 else |
| 1265 { |
| 1266 fields[2] = (rel->r_value >> 16) & 0xff; |
| 1267 fields[1] = (rel->r_value >> 8) & 0xff; |
| 1268 fields[0] = rel->r_value & 0xff; |
| 1269 info |= rel->r_type << BFD_MACH_O_LE_TYPE_SHIFT; |
| 1270 info |= rel->r_pcrel ? BFD_MACH_O_LE_PCREL : 0; |
| 1271 info |= rel->r_length << BFD_MACH_O_LE_LENGTH_SHIFT; |
| 1272 info |= rel->r_extern ? BFD_MACH_O_LE_EXTERN : 0; |
| 1273 } |
| 1274 fields[3] = info; |
| 1275 } |
| 1276 |
887 static bfd_boolean | 1277 static bfd_boolean |
888 bfd_mach_o_write_relocs (bfd *abfd, bfd_mach_o_section *section) | 1278 bfd_mach_o_write_relocs (bfd *abfd, bfd_mach_o_section *section) |
889 { | 1279 { |
890 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd); | |
891 unsigned int i; | 1280 unsigned int i; |
892 arelent **entries; | 1281 arelent **entries; |
893 asection *sec; | 1282 asection *sec; |
894 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd); | 1283 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd); |
895 | 1284 |
896 sec = section->bfdsection; | 1285 sec = section->bfdsection; |
897 if (sec->reloc_count == 0) | 1286 if (sec->reloc_count == 0) |
898 return TRUE; | 1287 return TRUE; |
899 | 1288 |
900 if (bed->_bfd_mach_o_swap_reloc_out == NULL) | 1289 if (bed->_bfd_mach_o_swap_reloc_out == NULL) |
901 return TRUE; | 1290 return TRUE; |
902 | 1291 |
903 /* Allocate relocation room. */ | |
904 mdata->filelen = FILE_ALIGN(mdata->filelen, 2); | |
905 section->nreloc = sec->reloc_count; | |
906 sec->rel_filepos = mdata->filelen; | |
907 section->reloff = sec->rel_filepos; | |
908 mdata->filelen += sec->reloc_count * BFD_MACH_O_RELENT_SIZE; | |
909 | |
910 if (bfd_seek (abfd, section->reloff, SEEK_SET) != 0) | 1292 if (bfd_seek (abfd, section->reloff, SEEK_SET) != 0) |
911 return FALSE; | 1293 return FALSE; |
912 | 1294 |
913 /* Convert and write. */ | 1295 /* Convert and write. */ |
914 entries = section->bfdsection->orelocation; | 1296 entries = section->bfdsection->orelocation; |
915 for (i = 0; i < section->nreloc; i++) | 1297 for (i = 0; i < section->nreloc; i++) |
916 { | 1298 { |
917 arelent *rel = entries[i]; | 1299 arelent *rel = entries[i]; |
918 struct mach_o_reloc_info_external raw; | 1300 struct mach_o_reloc_info_external raw; |
919 bfd_mach_o_reloc_info info, *pinfo = &info; | 1301 bfd_mach_o_reloc_info info, *pinfo = &info; |
(...skipping 11 matching lines...) Expand all Loading... |
931 | (pinfo->r_pcrel ? BFD_MACH_O_SR_PCREL : 0) | 1313 | (pinfo->r_pcrel ? BFD_MACH_O_SR_PCREL : 0) |
932 | BFD_MACH_O_SET_SR_LENGTH(pinfo->r_length) | 1314 | BFD_MACH_O_SET_SR_LENGTH(pinfo->r_length) |
933 | BFD_MACH_O_SET_SR_TYPE(pinfo->r_type) | 1315 | BFD_MACH_O_SET_SR_TYPE(pinfo->r_type) |
934 | BFD_MACH_O_SET_SR_ADDRESS(pinfo->r_address); | 1316 | BFD_MACH_O_SET_SR_ADDRESS(pinfo->r_address); |
935 /* Note: scattered relocs have field in reverse order... */ | 1317 /* Note: scattered relocs have field in reverse order... */ |
936 bfd_put_32 (abfd, v, raw.r_address); | 1318 bfd_put_32 (abfd, v, raw.r_address); |
937 bfd_put_32 (abfd, pinfo->r_value, raw.r_symbolnum); | 1319 bfd_put_32 (abfd, pinfo->r_value, raw.r_symbolnum); |
938 } | 1320 } |
939 else | 1321 else |
940 { | 1322 { |
941 unsigned long v; | |
942 | |
943 bfd_put_32 (abfd, pinfo->r_address, raw.r_address); | 1323 bfd_put_32 (abfd, pinfo->r_address, raw.r_address); |
944 v = BFD_MACH_O_SET_R_SYMBOLNUM (pinfo->r_value) | 1324 bfd_mach_o_swap_out_non_scattered_reloc (abfd, raw.r_symbolnum, |
945 | (pinfo->r_pcrel ? BFD_MACH_O_R_PCREL : 0) | 1325 » » » » » » pinfo); |
946 | BFD_MACH_O_SET_R_LENGTH (pinfo->r_length) | |
947 | (pinfo->r_extern ? BFD_MACH_O_R_EXTERN : 0) | |
948 | BFD_MACH_O_SET_R_TYPE (pinfo->r_type); | |
949 bfd_put_32 (abfd, v, raw.r_symbolnum); | |
950 } | 1326 } |
951 | 1327 |
952 if (bfd_bwrite (&raw, BFD_MACH_O_RELENT_SIZE, abfd) | 1328 if (bfd_bwrite (&raw, BFD_MACH_O_RELENT_SIZE, abfd) |
953 != BFD_MACH_O_RELENT_SIZE) | 1329 != BFD_MACH_O_RELENT_SIZE) |
954 return FALSE; | 1330 return FALSE; |
955 } | 1331 } |
956 return TRUE; | 1332 return TRUE; |
957 } | 1333 } |
958 | 1334 |
959 static int | 1335 static int |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1092 if (bfd_seek (abfd, sym->symoff, SEEK_SET) != 0) | 1468 if (bfd_seek (abfd, sym->symoff, SEEK_SET) != 0) |
1093 return FALSE; | 1469 return FALSE; |
1094 | 1470 |
1095 sym->nsyms = bfd_get_symcount (abfd); | 1471 sym->nsyms = bfd_get_symcount (abfd); |
1096 mdata->filelen += sym->nsyms * symlen; | 1472 mdata->filelen += sym->nsyms * symlen; |
1097 | 1473 |
1098 strtab = _bfd_stringtab_init (); | 1474 strtab = _bfd_stringtab_init (); |
1099 if (strtab == NULL) | 1475 if (strtab == NULL) |
1100 return FALSE; | 1476 return FALSE; |
1101 | 1477 |
| 1478 if (sym->nsyms > 0) |
| 1479 /* Although we don't strictly need to do this, for compatibility with |
| 1480 Darwin system tools, actually output an empty string for the index |
| 1481 0 entry. */ |
| 1482 _bfd_stringtab_add (strtab, "", TRUE, FALSE); |
| 1483 |
1102 for (i = 0; i < sym->nsyms; i++) | 1484 for (i = 0; i < sym->nsyms; i++) |
1103 { | 1485 { |
1104 bfd_size_type str_index; | 1486 bfd_size_type str_index; |
1105 bfd_mach_o_asymbol *s = (bfd_mach_o_asymbol *)symbols[i]; | 1487 bfd_mach_o_asymbol *s = (bfd_mach_o_asymbol *)symbols[i]; |
1106 | 1488 |
1107 /* Compute name index. */ | |
1108 /* An index of 0 always means the empty string. */ | |
1109 if (s->symbol.name == 0 || s->symbol.name[0] == '\0') | 1489 if (s->symbol.name == 0 || s->symbol.name[0] == '\0') |
| 1490 /* An index of 0 always means the empty string. */ |
1110 str_index = 0; | 1491 str_index = 0; |
1111 else | 1492 else |
1112 { | 1493 { |
1113 str_index = _bfd_stringtab_add (strtab, s->symbol.name, TRUE, FALSE); | 1494 str_index = _bfd_stringtab_add (strtab, s->symbol.name, TRUE, FALSE); |
| 1495 |
1114 if (str_index == (bfd_size_type) -1) | 1496 if (str_index == (bfd_size_type) -1) |
1115 goto err; | 1497 goto err; |
1116 } | 1498 } |
1117 | 1499 |
1118 if (wide) | 1500 if (wide) |
1119 { | 1501 { |
1120 struct mach_o_nlist_64_external raw; | 1502 struct mach_o_nlist_64_external raw; |
1121 | 1503 |
1122 bfd_h_put_32 (abfd, str_index, raw.n_strx); | 1504 bfd_h_put_32 (abfd, str_index, raw.n_strx); |
1123 bfd_h_put_8 (abfd, s->n_type, raw.n_type); | 1505 bfd_h_put_8 (abfd, s->n_type, raw.n_type); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1166 return FALSE; | 1548 return FALSE; |
1167 } | 1549 } |
1168 | 1550 |
1169 return TRUE; | 1551 return TRUE; |
1170 | 1552 |
1171 err: | 1553 err: |
1172 _bfd_stringtab_free (strtab); | 1554 _bfd_stringtab_free (strtab); |
1173 return FALSE; | 1555 return FALSE; |
1174 } | 1556 } |
1175 | 1557 |
1176 /* Process the symbols and generate Mach-O specific fields. | 1558 /* Write a dysymtab command. |
1177 Number them. */ | 1559 TODO: Possibly coalesce writes of smaller objects. */ |
| 1560 |
| 1561 static bfd_boolean |
| 1562 bfd_mach_o_write_dysymtab (bfd *abfd, bfd_mach_o_load_command *command) |
| 1563 { |
| 1564 bfd_mach_o_dysymtab_command *cmd = &command->command.dysymtab; |
| 1565 |
| 1566 BFD_ASSERT (command->type == BFD_MACH_O_LC_DYSYMTAB); |
| 1567 |
| 1568 if (cmd->nmodtab != 0) |
| 1569 { |
| 1570 unsigned int i; |
| 1571 |
| 1572 if (bfd_seek (abfd, cmd->modtaboff, SEEK_SET) != 0) |
| 1573 » return FALSE; |
| 1574 |
| 1575 for (i = 0; i < cmd->nmodtab; i++) |
| 1576 » { |
| 1577 » bfd_mach_o_dylib_module *module = &cmd->dylib_module[i]; |
| 1578 » unsigned int iinit; |
| 1579 » unsigned int ninit; |
| 1580 |
| 1581 » iinit = module->iinit & 0xffff; |
| 1582 » iinit |= ((module->iterm & 0xffff) << 16); |
| 1583 |
| 1584 » ninit = module->ninit & 0xffff; |
| 1585 » ninit |= ((module->nterm & 0xffff) << 16); |
| 1586 |
| 1587 » if (bfd_mach_o_wide_p (abfd)) |
| 1588 » { |
| 1589 » struct mach_o_dylib_module_64_external w; |
| 1590 |
| 1591 » bfd_h_put_32 (abfd, module->module_name_idx, &w.module_name); |
| 1592 » bfd_h_put_32 (abfd, module->iextdefsym, &w.iextdefsym); |
| 1593 » bfd_h_put_32 (abfd, module->nextdefsym, &w.nextdefsym); |
| 1594 » bfd_h_put_32 (abfd, module->irefsym, &w.irefsym); |
| 1595 » bfd_h_put_32 (abfd, module->nrefsym, &w.nrefsym); |
| 1596 » bfd_h_put_32 (abfd, module->ilocalsym, &w.ilocalsym); |
| 1597 » bfd_h_put_32 (abfd, module->nlocalsym, &w.nlocalsym); |
| 1598 » bfd_h_put_32 (abfd, module->iextrel, &w.iextrel); |
| 1599 » bfd_h_put_32 (abfd, module->nextrel, &w.nextrel); |
| 1600 » bfd_h_put_32 (abfd, iinit, &w.iinit_iterm); |
| 1601 » bfd_h_put_32 (abfd, ninit, &w.ninit_nterm); |
| 1602 » bfd_h_put_64 (abfd, module->objc_module_info_addr, |
| 1603 » » » &w.objc_module_info_addr); |
| 1604 » bfd_h_put_32 (abfd, module->objc_module_info_size, |
| 1605 » » » &w.objc_module_info_size); |
| 1606 |
| 1607 » if (bfd_bwrite ((void *) &w, sizeof (w), abfd) != sizeof (w)) |
| 1608 » » return FALSE; |
| 1609 » } |
| 1610 » else |
| 1611 » { |
| 1612 » struct mach_o_dylib_module_external n; |
| 1613 |
| 1614 » bfd_h_put_32 (abfd, module->module_name_idx, &n.module_name); |
| 1615 » bfd_h_put_32 (abfd, module->iextdefsym, &n.iextdefsym); |
| 1616 » bfd_h_put_32 (abfd, module->nextdefsym, &n.nextdefsym); |
| 1617 » bfd_h_put_32 (abfd, module->irefsym, &n.irefsym); |
| 1618 » bfd_h_put_32 (abfd, module->nrefsym, &n.nrefsym); |
| 1619 » bfd_h_put_32 (abfd, module->ilocalsym, &n.ilocalsym); |
| 1620 » bfd_h_put_32 (abfd, module->nlocalsym, &n.nlocalsym); |
| 1621 » bfd_h_put_32 (abfd, module->iextrel, &n.iextrel); |
| 1622 » bfd_h_put_32 (abfd, module->nextrel, &n.nextrel); |
| 1623 » bfd_h_put_32 (abfd, iinit, &n.iinit_iterm); |
| 1624 » bfd_h_put_32 (abfd, ninit, &n.ninit_nterm); |
| 1625 » bfd_h_put_32 (abfd, module->objc_module_info_addr, |
| 1626 » » » &n.objc_module_info_addr); |
| 1627 » bfd_h_put_32 (abfd, module->objc_module_info_size, |
| 1628 » » » &n.objc_module_info_size); |
| 1629 |
| 1630 » if (bfd_bwrite ((void *) &n, sizeof (n), abfd) != sizeof (n)) |
| 1631 » » return FALSE; |
| 1632 » } |
| 1633 » } |
| 1634 } |
| 1635 |
| 1636 if (cmd->ntoc != 0) |
| 1637 { |
| 1638 unsigned int i; |
| 1639 |
| 1640 if (bfd_seek (abfd, cmd->tocoff, SEEK_SET) != 0) |
| 1641 » return FALSE; |
| 1642 |
| 1643 for (i = 0; i < cmd->ntoc; i++) |
| 1644 » { |
| 1645 » struct mach_o_dylib_table_of_contents_external raw; |
| 1646 » bfd_mach_o_dylib_table_of_content *toc = &cmd->dylib_toc[i]; |
| 1647 |
| 1648 » bfd_h_put_32 (abfd, toc->symbol_index, &raw.symbol_index); |
| 1649 » bfd_h_put_32 (abfd, toc->module_index, &raw.module_index); |
| 1650 |
| 1651 » if (bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw)) |
| 1652 » return FALSE; |
| 1653 » } |
| 1654 } |
| 1655 |
| 1656 if (cmd->nindirectsyms > 0) |
| 1657 { |
| 1658 unsigned int i; |
| 1659 |
| 1660 if (bfd_seek (abfd, cmd->indirectsymoff, SEEK_SET) != 0) |
| 1661 » return FALSE; |
| 1662 |
| 1663 for (i = 0; i < cmd->nindirectsyms; ++i) |
| 1664 » { |
| 1665 » unsigned char raw[4]; |
| 1666 |
| 1667 » bfd_h_put_32 (abfd, cmd->indirect_syms[i], &raw); |
| 1668 » if (bfd_bwrite (raw, sizeof (raw), abfd) != sizeof (raw)) |
| 1669 » return FALSE; |
| 1670 » } |
| 1671 } |
| 1672 |
| 1673 if (cmd->nextrefsyms != 0) |
| 1674 { |
| 1675 unsigned int i; |
| 1676 |
| 1677 if (bfd_seek (abfd, cmd->extrefsymoff, SEEK_SET) != 0) |
| 1678 » return FALSE; |
| 1679 |
| 1680 for (i = 0; i < cmd->nextrefsyms; i++) |
| 1681 » { |
| 1682 » unsigned long v; |
| 1683 » unsigned char raw[4]; |
| 1684 » bfd_mach_o_dylib_reference *ref = &cmd->ext_refs[i]; |
| 1685 |
| 1686 » /* Fields isym and flags are written as bit-fields, thus we need |
| 1687 » a specific processing for endianness. */ |
| 1688 |
| 1689 » if (bfd_big_endian (abfd)) |
| 1690 » { |
| 1691 » v = ((ref->isym & 0xffffff) << 8); |
| 1692 » v |= ref->flags & 0xff; |
| 1693 » } |
| 1694 » else |
| 1695 » { |
| 1696 » v = ref->isym & 0xffffff; |
| 1697 » v |= ((ref->flags & 0xff) << 24); |
| 1698 » } |
| 1699 |
| 1700 » bfd_h_put_32 (abfd, v, raw); |
| 1701 » if (bfd_bwrite (raw, sizeof (raw), abfd) != sizeof (raw)) |
| 1702 » return FALSE; |
| 1703 » } |
| 1704 } |
| 1705 |
| 1706 /* The command. */ |
| 1707 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0) |
| 1708 return FALSE; |
| 1709 else |
| 1710 { |
| 1711 struct mach_o_dysymtab_command_external raw; |
| 1712 |
| 1713 bfd_h_put_32 (abfd, cmd->ilocalsym, &raw.ilocalsym); |
| 1714 bfd_h_put_32 (abfd, cmd->nlocalsym, &raw.nlocalsym); |
| 1715 bfd_h_put_32 (abfd, cmd->iextdefsym, &raw.iextdefsym); |
| 1716 bfd_h_put_32 (abfd, cmd->nextdefsym, &raw.nextdefsym); |
| 1717 bfd_h_put_32 (abfd, cmd->iundefsym, &raw.iundefsym); |
| 1718 bfd_h_put_32 (abfd, cmd->nundefsym, &raw.nundefsym); |
| 1719 bfd_h_put_32 (abfd, cmd->tocoff, &raw.tocoff); |
| 1720 bfd_h_put_32 (abfd, cmd->ntoc, &raw.ntoc); |
| 1721 bfd_h_put_32 (abfd, cmd->modtaboff, &raw.modtaboff); |
| 1722 bfd_h_put_32 (abfd, cmd->nmodtab, &raw.nmodtab); |
| 1723 bfd_h_put_32 (abfd, cmd->extrefsymoff, &raw.extrefsymoff); |
| 1724 bfd_h_put_32 (abfd, cmd->nextrefsyms, &raw.nextrefsyms); |
| 1725 bfd_h_put_32 (abfd, cmd->indirectsymoff, &raw.indirectsymoff); |
| 1726 bfd_h_put_32 (abfd, cmd->nindirectsyms, &raw.nindirectsyms); |
| 1727 bfd_h_put_32 (abfd, cmd->extreloff, &raw.extreloff); |
| 1728 bfd_h_put_32 (abfd, cmd->nextrel, &raw.nextrel); |
| 1729 bfd_h_put_32 (abfd, cmd->locreloff, &raw.locreloff); |
| 1730 bfd_h_put_32 (abfd, cmd->nlocrel, &raw.nlocrel); |
| 1731 |
| 1732 if (bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw)) |
| 1733 » return FALSE; |
| 1734 } |
| 1735 |
| 1736 return TRUE; |
| 1737 } |
| 1738 |
| 1739 static unsigned |
| 1740 bfd_mach_o_primary_symbol_sort_key (bfd_mach_o_asymbol *s) |
| 1741 { |
| 1742 unsigned mtyp = s->n_type & BFD_MACH_O_N_TYPE; |
| 1743 |
| 1744 /* Just leave debug symbols where they are (pretend they are local, and |
| 1745 then they will just be sorted on position). */ |
| 1746 if (s->n_type & BFD_MACH_O_N_STAB) |
| 1747 return 0; |
| 1748 |
| 1749 /* Local (we should never see an undefined local AFAICT). */ |
| 1750 if (! (s->n_type & (BFD_MACH_O_N_EXT | BFD_MACH_O_N_PEXT))) |
| 1751 return 0; |
| 1752 |
| 1753 /* Common symbols look like undefined externs. */ |
| 1754 if (mtyp == BFD_MACH_O_N_UNDF) |
| 1755 return 2; |
| 1756 |
| 1757 /* A defined non-local, non-debug symbol. */ |
| 1758 return 1; |
| 1759 } |
| 1760 |
| 1761 static int |
| 1762 bfd_mach_o_cf_symbols (const void *a, const void *b) |
| 1763 { |
| 1764 bfd_mach_o_asymbol *sa = *(bfd_mach_o_asymbol **) a; |
| 1765 bfd_mach_o_asymbol *sb = *(bfd_mach_o_asymbol **) b; |
| 1766 unsigned int soa, sob; |
| 1767 |
| 1768 soa = bfd_mach_o_primary_symbol_sort_key (sa); |
| 1769 sob = bfd_mach_o_primary_symbol_sort_key (sb); |
| 1770 if (soa < sob) |
| 1771 return -1; |
| 1772 |
| 1773 if (soa > sob) |
| 1774 return 1; |
| 1775 |
| 1776 /* If it's local or stab, just preserve the input order. */ |
| 1777 if (soa == 0) |
| 1778 { |
| 1779 if (sa->symbol.udata.i < sb->symbol.udata.i) |
| 1780 return -1; |
| 1781 if (sa->symbol.udata.i > sb->symbol.udata.i) |
| 1782 return 1; |
| 1783 |
| 1784 /* This is probably an error. */ |
| 1785 return 0; |
| 1786 } |
| 1787 |
| 1788 /* The second sort key is name. */ |
| 1789 return strcmp (sa->symbol.name, sb->symbol.name); |
| 1790 } |
| 1791 |
| 1792 /* Process the symbols. |
| 1793 |
| 1794 This should be OK for single-module files - but it is not likely to work |
| 1795 for multi-module shared libraries. |
| 1796 |
| 1797 (a) If the application has not filled in the relevant mach-o fields, make |
| 1798 an estimate. |
| 1799 |
| 1800 (b) Order them, like this: |
| 1801 » ( i) local. |
| 1802 » » (unsorted) |
| 1803 » ( ii) external defined |
| 1804 » » (by name) |
| 1805 » (iii) external undefined/common |
| 1806 » » (by name) |
| 1807 » ( iv) common |
| 1808 » » (by name) |
| 1809 */ |
1178 | 1810 |
1179 static bfd_boolean | 1811 static bfd_boolean |
1180 bfd_mach_o_mangle_symbols (bfd *abfd) | 1812 bfd_mach_o_mangle_symbols (bfd *abfd) |
1181 { | 1813 { |
1182 unsigned long i; | 1814 unsigned long i; |
1183 asymbol **symbols = bfd_get_outsymbols (abfd); | 1815 asymbol **symbols = bfd_get_outsymbols (abfd); |
1184 | 1816 |
| 1817 if (symbols == NULL || bfd_get_symcount (abfd) == 0) |
| 1818 return TRUE; |
| 1819 |
1185 for (i = 0; i < bfd_get_symcount (abfd); i++) | 1820 for (i = 0; i < bfd_get_symcount (abfd); i++) |
1186 { | 1821 { |
1187 bfd_mach_o_asymbol *s = (bfd_mach_o_asymbol *)symbols[i]; | 1822 bfd_mach_o_asymbol *s = (bfd_mach_o_asymbol *)symbols[i]; |
1188 | 1823 |
1189 if (s->n_type == BFD_MACH_O_N_UNDF && !(s->symbol.flags & BSF_DEBUGGING)) | 1824 /* We use this value, which is out-of-range as a symbol index, to signal |
| 1825 » that the mach-o-specific data are not filled in and need to be created |
| 1826 » from the bfd values. It is much preferable for the application to do |
| 1827 » this, since more meaningful diagnostics can be made that way. */ |
| 1828 |
| 1829 if (s->symbol.udata.i == SYM_MACHO_FIELDS_UNSET) |
1190 { | 1830 { |
1191 /* As genuine Mach-O symbols type shouldn't be N_UNDF (undefined | 1831 /* No symbol information has been set - therefore determine |
1192 symbols should be N_UNDEF | N_EXT), we suppose the back-end | 1832 it from the bfd symbol flags/info. */ |
1193 values haven't been set. */ | |
1194 if (s->symbol.section == bfd_abs_section_ptr) | 1833 if (s->symbol.section == bfd_abs_section_ptr) |
1195 s->n_type = BFD_MACH_O_N_ABS; | 1834 s->n_type = BFD_MACH_O_N_ABS; |
1196 else if (s->symbol.section == bfd_und_section_ptr) | 1835 else if (s->symbol.section == bfd_und_section_ptr) |
1197 { | 1836 { |
1198 s->n_type = BFD_MACH_O_N_UNDF; | 1837 s->n_type = BFD_MACH_O_N_UNDF; |
1199 if (s->symbol.flags & BSF_WEAK) | 1838 if (s->symbol.flags & BSF_WEAK) |
1200 s->n_desc |= BFD_MACH_O_N_WEAK_REF; | 1839 s->n_desc |= BFD_MACH_O_N_WEAK_REF; |
| 1840 /* mach-o automatically makes undefined symbols extern. */ |
| 1841 s->n_type |= BFD_MACH_O_N_EXT; |
| 1842 s->symbol.flags |= BSF_GLOBAL; |
1201 } | 1843 } |
1202 else if (s->symbol.section == bfd_com_section_ptr) | 1844 else if (s->symbol.section == bfd_com_section_ptr) |
1203 s->n_type = BFD_MACH_O_N_UNDF | BFD_MACH_O_N_EXT; | 1845 » { |
| 1846 s->n_type = BFD_MACH_O_N_UNDF | BFD_MACH_O_N_EXT; |
| 1847 s->symbol.flags |= BSF_GLOBAL; |
| 1848 } |
1204 else | 1849 else |
1205 s->n_type = BFD_MACH_O_N_SECT; | 1850 s->n_type = BFD_MACH_O_N_SECT; |
1206 | 1851 |
1207 if (s->symbol.flags & BSF_GLOBAL) | 1852 if (s->symbol.flags & BSF_GLOBAL) |
1208 s->n_type |= BFD_MACH_O_N_EXT; | 1853 s->n_type |= BFD_MACH_O_N_EXT; |
1209 } | 1854 } |
1210 | 1855 |
1211 /* Compute section index. */ | 1856 /* Put the section index in, where required. */ |
1212 if (s->symbol.section != bfd_abs_section_ptr | 1857 if ((s->symbol.section != bfd_abs_section_ptr |
1213 && s->symbol.section != bfd_und_section_ptr | 1858 && s->symbol.section != bfd_und_section_ptr |
1214 && s->symbol.section != bfd_com_section_ptr) | 1859 && s->symbol.section != bfd_com_section_ptr) |
1215 s->n_sect = s->symbol.section->target_index; | 1860 || ((s->n_type & BFD_MACH_O_N_STAB) != 0 |
| 1861 && s->symbol.name == NULL)) |
| 1862 » s->n_sect = s->symbol.section->target_index; |
1216 | 1863 |
1217 /* Number symbols. */ | 1864 /* Number to preserve order for local and debug syms. */ |
1218 s->symbol.udata.i = i; | 1865 s->symbol.udata.i = i; |
1219 } | 1866 } |
| 1867 |
| 1868 /* Sort the symbols. */ |
| 1869 qsort ((void *) symbols, (size_t) bfd_get_symcount (abfd), |
| 1870 sizeof (asymbol *), bfd_mach_o_cf_symbols); |
| 1871 |
| 1872 for (i = 0; i < bfd_get_symcount (abfd); ++i) |
| 1873 { |
| 1874 bfd_mach_o_asymbol *s = (bfd_mach_o_asymbol *)symbols[i]; |
| 1875 s->symbol.udata.i = i; /* renumber. */ |
| 1876 } |
| 1877 |
1220 return TRUE; | 1878 return TRUE; |
1221 } | 1879 } |
1222 | 1880 |
| 1881 /* We build a flat table of sections, which can be re-ordered if necessary. |
| 1882 Fill in the section number and other mach-o-specific data. */ |
| 1883 |
| 1884 static bfd_boolean |
| 1885 bfd_mach_o_mangle_sections (bfd *abfd, bfd_mach_o_data_struct *mdata) |
| 1886 { |
| 1887 asection *sec; |
| 1888 unsigned target_index; |
| 1889 unsigned nsect; |
| 1890 |
| 1891 nsect = bfd_count_sections (abfd); |
| 1892 |
| 1893 /* Don't do it if it's already set - assume the application knows what it's |
| 1894 doing. */ |
| 1895 if (mdata->nsects == nsect |
| 1896 && (mdata->nsects == 0 || mdata->sections != NULL)) |
| 1897 return TRUE; |
| 1898 |
| 1899 mdata->nsects = nsect; |
| 1900 mdata->sections = bfd_alloc (abfd, |
| 1901 mdata->nsects * sizeof (bfd_mach_o_section *)); |
| 1902 if (mdata->sections == NULL) |
| 1903 return FALSE; |
| 1904 |
| 1905 /* We need to check that this can be done... */ |
| 1906 if (nsect > 255) |
| 1907 (*_bfd_error_handler) (_("mach-o: there are too many sections (%d)" |
| 1908 " maximum is 255,\n"), nsect); |
| 1909 |
| 1910 /* Create Mach-O sections. |
| 1911 Section type, attribute and align should have been set when the |
| 1912 section was created - either read in or specified. */ |
| 1913 target_index = 0; |
| 1914 for (sec = abfd->sections; sec; sec = sec->next) |
| 1915 { |
| 1916 unsigned bfd_align = bfd_get_section_alignment (abfd, sec); |
| 1917 bfd_mach_o_section *msect = bfd_mach_o_get_mach_o_section (sec); |
| 1918 |
| 1919 mdata->sections[target_index] = msect; |
| 1920 |
| 1921 msect->addr = bfd_get_section_vma (abfd, sec); |
| 1922 msect->size = bfd_get_section_size (sec); |
| 1923 |
| 1924 /* Use the largest alignment set, in case it was bumped after the |
| 1925 section was created. */ |
| 1926 msect->align = msect->align > bfd_align ? msect->align : bfd_align; |
| 1927 |
| 1928 msect->offset = 0; |
| 1929 sec->target_index = ++target_index; |
| 1930 } |
| 1931 |
| 1932 return TRUE; |
| 1933 } |
| 1934 |
1223 bfd_boolean | 1935 bfd_boolean |
1224 bfd_mach_o_write_contents (bfd *abfd) | 1936 bfd_mach_o_write_contents (bfd *abfd) |
1225 { | 1937 { |
1226 unsigned int i; | 1938 unsigned int i; |
1227 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd); | 1939 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd); |
1228 | 1940 |
| 1941 /* Make the commands, if not already present. */ |
1229 if (mdata->header.ncmds == 0) | 1942 if (mdata->header.ncmds == 0) |
1230 if (!bfd_mach_o_build_commands (abfd)) | 1943 if (!bfd_mach_o_build_commands (abfd)) |
1231 return FALSE; | 1944 return FALSE; |
1232 | 1945 |
1233 /* Now write header information. */ | |
1234 if (mdata->header.filetype == 0) | |
1235 { | |
1236 if (abfd->flags & EXEC_P) | |
1237 mdata->header.filetype = BFD_MACH_O_MH_EXECUTE; | |
1238 else if (abfd->flags & DYNAMIC) | |
1239 mdata->header.filetype = BFD_MACH_O_MH_DYLIB; | |
1240 else | |
1241 mdata->header.filetype = BFD_MACH_O_MH_OBJECT; | |
1242 } | |
1243 if (!bfd_mach_o_write_header (abfd, &mdata->header)) | 1946 if (!bfd_mach_o_write_header (abfd, &mdata->header)) |
1244 return FALSE; | 1947 return FALSE; |
1245 | 1948 |
1246 /* Assign a number to each symbols. */ | |
1247 if (!bfd_mach_o_mangle_symbols (abfd)) | |
1248 return FALSE; | |
1249 | |
1250 for (i = 0; i < mdata->header.ncmds; i++) | 1949 for (i = 0; i < mdata->header.ncmds; i++) |
1251 { | 1950 { |
1252 struct mach_o_load_command_external raw; | 1951 struct mach_o_load_command_external raw; |
1253 bfd_mach_o_load_command *cur = &mdata->commands[i]; | 1952 bfd_mach_o_load_command *cur = &mdata->commands[i]; |
1254 unsigned long typeflag; | 1953 unsigned long typeflag; |
1255 | 1954 |
1256 typeflag = cur->type | (cur->type_required ? BFD_MACH_O_LC_REQ_DYLD : 0); | 1955 typeflag = cur->type | (cur->type_required ? BFD_MACH_O_LC_REQ_DYLD : 0); |
1257 | 1956 |
1258 bfd_h_put_32 (abfd, typeflag, raw.cmd); | 1957 bfd_h_put_32 (abfd, typeflag, raw.cmd); |
1259 bfd_h_put_32 (abfd, cur->len, raw.cmdsize); | 1958 bfd_h_put_32 (abfd, cur->len, raw.cmdsize); |
1260 | 1959 |
1261 if (bfd_seek (abfd, cur->offset, SEEK_SET) != 0 | 1960 if (bfd_seek (abfd, cur->offset, SEEK_SET) != 0 |
1262 || bfd_bwrite (&raw, BFD_MACH_O_LC_SIZE, abfd) != 8) | 1961 || bfd_bwrite (&raw, BFD_MACH_O_LC_SIZE, abfd) != 8) |
1263 return FALSE; | 1962 return FALSE; |
1264 | 1963 |
1265 switch (cur->type) | 1964 switch (cur->type) |
1266 { | 1965 { |
1267 case BFD_MACH_O_LC_SEGMENT: | 1966 case BFD_MACH_O_LC_SEGMENT: |
1268 if (bfd_mach_o_write_segment_32 (abfd, cur) != 0) | 1967 if (bfd_mach_o_write_segment_32 (abfd, cur) != 0) |
1269 return FALSE; | 1968 return FALSE; |
1270 break; | 1969 break; |
1271 case BFD_MACH_O_LC_SEGMENT_64: | 1970 case BFD_MACH_O_LC_SEGMENT_64: |
1272 if (bfd_mach_o_write_segment_64 (abfd, cur) != 0) | 1971 if (bfd_mach_o_write_segment_64 (abfd, cur) != 0) |
1273 return FALSE; | 1972 return FALSE; |
1274 break; | 1973 break; |
1275 case BFD_MACH_O_LC_SYMTAB: | 1974 case BFD_MACH_O_LC_SYMTAB: |
1276 if (!bfd_mach_o_write_symtab (abfd, cur)) | 1975 if (!bfd_mach_o_write_symtab (abfd, cur)) |
1277 return FALSE; | 1976 return FALSE; |
1278 break; | 1977 break; |
| 1978 case BFD_MACH_O_LC_DYSYMTAB: |
| 1979 if (!bfd_mach_o_write_dysymtab (abfd, cur)) |
| 1980 return FALSE; |
| 1981 break; |
1279 case BFD_MACH_O_LC_SYMSEG: | 1982 case BFD_MACH_O_LC_SYMSEG: |
1280 break; | 1983 break; |
1281 case BFD_MACH_O_LC_THREAD: | 1984 case BFD_MACH_O_LC_THREAD: |
1282 case BFD_MACH_O_LC_UNIXTHREAD: | 1985 case BFD_MACH_O_LC_UNIXTHREAD: |
1283 if (bfd_mach_o_write_thread (abfd, cur) != 0) | 1986 if (bfd_mach_o_write_thread (abfd, cur) != 0) |
1284 return FALSE; | 1987 return FALSE; |
1285 break; | 1988 break; |
1286 case BFD_MACH_O_LC_LOADFVMLIB: | 1989 case BFD_MACH_O_LC_LOADFVMLIB: |
1287 case BFD_MACH_O_LC_IDFVMLIB: | 1990 case BFD_MACH_O_LC_IDFVMLIB: |
1288 case BFD_MACH_O_LC_IDENT: | 1991 case BFD_MACH_O_LC_IDENT: |
1289 case BFD_MACH_O_LC_FVMFILE: | 1992 case BFD_MACH_O_LC_FVMFILE: |
1290 case BFD_MACH_O_LC_PREPAGE: | 1993 case BFD_MACH_O_LC_PREPAGE: |
1291 case BFD_MACH_O_LC_DYSYMTAB: | |
1292 case BFD_MACH_O_LC_LOAD_DYLIB: | 1994 case BFD_MACH_O_LC_LOAD_DYLIB: |
1293 case BFD_MACH_O_LC_LOAD_WEAK_DYLIB: | 1995 case BFD_MACH_O_LC_LOAD_WEAK_DYLIB: |
1294 case BFD_MACH_O_LC_ID_DYLIB: | 1996 case BFD_MACH_O_LC_ID_DYLIB: |
1295 case BFD_MACH_O_LC_REEXPORT_DYLIB: | 1997 case BFD_MACH_O_LC_REEXPORT_DYLIB: |
1296 case BFD_MACH_O_LC_LOAD_UPWARD_DYLIB: | 1998 case BFD_MACH_O_LC_LOAD_UPWARD_DYLIB: |
1297 case BFD_MACH_O_LC_LOAD_DYLINKER: | 1999 case BFD_MACH_O_LC_LOAD_DYLINKER: |
1298 case BFD_MACH_O_LC_ID_DYLINKER: | 2000 case BFD_MACH_O_LC_ID_DYLINKER: |
1299 case BFD_MACH_O_LC_PREBOUND_DYLIB: | 2001 case BFD_MACH_O_LC_PREBOUND_DYLIB: |
1300 case BFD_MACH_O_LC_ROUTINES: | 2002 case BFD_MACH_O_LC_ROUTINES: |
1301 case BFD_MACH_O_LC_SUB_FRAMEWORK: | 2003 case BFD_MACH_O_LC_SUB_FRAMEWORK: |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1337 | BFD_MACH_O_S_ATTR_SOME_INSTRUCTIONS | 2039 | BFD_MACH_O_S_ATTR_SOME_INSTRUCTIONS |
1338 | BFD_MACH_O_S_REGULAR; | 2040 | BFD_MACH_O_S_REGULAR; |
1339 else if ((bfd_flags & (SEC_ALLOC | SEC_LOAD)) == SEC_ALLOC) | 2041 else if ((bfd_flags & (SEC_ALLOC | SEC_LOAD)) == SEC_ALLOC) |
1340 s->flags = BFD_MACH_O_S_ZEROFILL; | 2042 s->flags = BFD_MACH_O_S_ZEROFILL; |
1341 else if (bfd_flags & SEC_DEBUGGING) | 2043 else if (bfd_flags & SEC_DEBUGGING) |
1342 s->flags = BFD_MACH_O_S_REGULAR | BFD_MACH_O_S_ATTR_DEBUG; | 2044 s->flags = BFD_MACH_O_S_REGULAR | BFD_MACH_O_S_ATTR_DEBUG; |
1343 else | 2045 else |
1344 s->flags = BFD_MACH_O_S_REGULAR; | 2046 s->flags = BFD_MACH_O_S_REGULAR; |
1345 } | 2047 } |
1346 | 2048 |
1347 /* Build Mach-O load commands from the sections. */ | 2049 /* Count the number of sections in the list for the segment named. |
| 2050 |
| 2051 The special case of NULL or "" for the segment name is valid for |
| 2052 an MH_OBJECT file and means 'all sections available'. |
| 2053 |
| 2054 Requires that the sections table in mdata be filled in. |
| 2055 |
| 2056 Returns the number of sections (0 is valid). |
| 2057 Any number > 255 signals an invalid section count, although we will, |
| 2058 perhaps, allow the file to be written (in line with Darwin tools up |
| 2059 to XCode 4). |
| 2060 |
| 2061 A section count of (unsigned long) -1 signals a definite error. */ |
| 2062 |
| 2063 static unsigned long |
| 2064 bfd_mach_o_count_sections_for_seg (const char *segment, |
| 2065 » » » » bfd_mach_o_data_struct *mdata) |
| 2066 { |
| 2067 unsigned i,j; |
| 2068 if (mdata == NULL || mdata->sections == NULL) |
| 2069 return (unsigned long) -1; |
| 2070 |
| 2071 /* The MH_OBJECT case, all sections are considered; Although nsects is |
| 2072 is an unsigned long, the maximum valid section count is 255 and this |
| 2073 will have been checked already by mangle_sections. */ |
| 2074 if (segment == NULL || segment[0] == '\0') |
| 2075 return mdata->nsects; |
| 2076 |
| 2077 /* Count the number of sections we see in this segment. */ |
| 2078 j = 0; |
| 2079 for (i = 0; i < mdata->nsects; ++i) |
| 2080 { |
| 2081 bfd_mach_o_section *s = mdata->sections[i]; |
| 2082 if (strncmp (segment, s->segname, BFD_MACH_O_SEGNAME_SIZE) == 0) |
| 2083 j++; |
| 2084 } |
| 2085 return j; |
| 2086 } |
| 2087 |
| 2088 static bfd_boolean |
| 2089 bfd_mach_o_build_seg_command (const char *segment, |
| 2090 » » » bfd_mach_o_data_struct *mdata, |
| 2091 » » » bfd_mach_o_segment_command *seg) |
| 2092 { |
| 2093 unsigned i; |
| 2094 int is_mho = (segment == NULL || segment[0] == '\0'); |
| 2095 |
| 2096 /* Fill segment command. */ |
| 2097 if (is_mho) |
| 2098 memset (seg->segname, 0, sizeof (seg->segname)); |
| 2099 else |
| 2100 strncpy (seg->segname, segment, sizeof (seg->segname)); |
| 2101 |
| 2102 /* TODO: fix this up for non-MH_OBJECT cases. */ |
| 2103 seg->vmaddr = 0; |
| 2104 seg->vmsize = 0; |
| 2105 |
| 2106 seg->fileoff = mdata->filelen; |
| 2107 seg->filesize = 0; |
| 2108 seg->maxprot = BFD_MACH_O_PROT_READ | BFD_MACH_O_PROT_WRITE |
| 2109 » » | BFD_MACH_O_PROT_EXECUTE; |
| 2110 seg->initprot = seg->maxprot; |
| 2111 seg->flags = 0; |
| 2112 seg->sect_head = NULL; |
| 2113 seg->sect_tail = NULL; |
| 2114 |
| 2115 /* Append sections to the segment. |
| 2116 |
| 2117 This is a little tedious, we have to honor the need to account zerofill |
| 2118 sections after all the rest. This forces us to do the calculation of |
| 2119 total vmsize in three passes so that any alignment increments are |
| 2120 properly accounted. */ |
| 2121 |
| 2122 for (i = 0; i < mdata->nsects; ++i) |
| 2123 { |
| 2124 bfd_mach_o_section *s = mdata->sections[i]; |
| 2125 asection *sec = s->bfdsection; |
| 2126 |
| 2127 /* If we're not making an MH_OBJECT, check whether this section is from |
| 2128 » our segment, and skip if not. Otherwise, just add all sections. */ |
| 2129 if (! is_mho |
| 2130 » && strncmp (segment, s->segname, BFD_MACH_O_SEGNAME_SIZE) != 0) |
| 2131 » continue; |
| 2132 |
| 2133 /* Although we account for zerofill section sizes in vm order, they are |
| 2134 » placed in the file in source sequence. */ |
| 2135 bfd_mach_o_append_section_to_segment (seg, sec); |
| 2136 s->offset = 0; |
| 2137 |
| 2138 /* Zerofill sections have zero file size & offset, |
| 2139 » and are not written. */ |
| 2140 if ((s->flags & BFD_MACH_O_SECTION_TYPE_MASK) == BFD_MACH_O_S_ZEROFILL |
| 2141 || (s->flags & BFD_MACH_O_SECTION_TYPE_MASK) |
| 2142 » == BFD_MACH_O_S_GB_ZEROFILL) |
| 2143 continue; |
| 2144 |
| 2145 if (s->size > 0) |
| 2146 { |
| 2147 » seg->vmsize = FILE_ALIGN (seg->vmsize, s->align); |
| 2148 » seg->vmsize += s->size; |
| 2149 |
| 2150 » seg->filesize = FILE_ALIGN (seg->filesize, s->align); |
| 2151 » seg->filesize += s->size; |
| 2152 |
| 2153 mdata->filelen = FILE_ALIGN (mdata->filelen, s->align); |
| 2154 s->offset = mdata->filelen; |
| 2155 } |
| 2156 |
| 2157 sec->filepos = s->offset; |
| 2158 mdata->filelen += s->size; |
| 2159 } |
| 2160 |
| 2161 /* Now pass through again, for zerofill, only now we just update the vmsize.
*/ |
| 2162 for (i = 0; i < mdata->nsects; ++i) |
| 2163 { |
| 2164 bfd_mach_o_section *s = mdata->sections[i]; |
| 2165 |
| 2166 if ((s->flags & BFD_MACH_O_SECTION_TYPE_MASK) != BFD_MACH_O_S_ZEROFILL) |
| 2167 continue; |
| 2168 |
| 2169 if (! is_mho |
| 2170 » && strncmp (segment, s->segname, BFD_MACH_O_SEGNAME_SIZE) != 0) |
| 2171 » continue; |
| 2172 |
| 2173 if (s->size > 0) |
| 2174 » { |
| 2175 » seg->vmsize = FILE_ALIGN (seg->vmsize, s->align); |
| 2176 » seg->vmsize += s->size; |
| 2177 » } |
| 2178 } |
| 2179 |
| 2180 /* Now pass through again, for zerofill_GB. */ |
| 2181 for (i = 0; i < mdata->nsects; ++i) |
| 2182 { |
| 2183 bfd_mach_o_section *s = mdata->sections[i]; |
| 2184 |
| 2185 if ((s->flags & BFD_MACH_O_SECTION_TYPE_MASK) != BFD_MACH_O_S_GB_ZEROFILL) |
| 2186 continue; |
| 2187 |
| 2188 if (! is_mho |
| 2189 » && strncmp (segment, s->segname, BFD_MACH_O_SEGNAME_SIZE) != 0) |
| 2190 » continue; |
| 2191 |
| 2192 if (s->size > 0) |
| 2193 » { |
| 2194 » seg->vmsize = FILE_ALIGN (seg->vmsize, s->align); |
| 2195 » seg->vmsize += s->size; |
| 2196 » } |
| 2197 } |
| 2198 |
| 2199 /* Allocate space for the relocations. */ |
| 2200 mdata->filelen = FILE_ALIGN(mdata->filelen, 2); |
| 2201 |
| 2202 for (i = 0; i < mdata->nsects; ++i) |
| 2203 { |
| 2204 bfd_mach_o_section *ms = mdata->sections[i]; |
| 2205 asection *sec = ms->bfdsection; |
| 2206 |
| 2207 if ((ms->nreloc = sec->reloc_count) == 0) |
| 2208 { |
| 2209 » ms->reloff = 0; |
| 2210 » continue; |
| 2211 } |
| 2212 sec->rel_filepos = mdata->filelen; |
| 2213 ms->reloff = sec->rel_filepos; |
| 2214 mdata->filelen += sec->reloc_count * BFD_MACH_O_RELENT_SIZE; |
| 2215 } |
| 2216 |
| 2217 return TRUE; |
| 2218 } |
| 2219 |
| 2220 /* Count the number of indirect symbols in the image. |
| 2221 Requires that the sections are in their final order. */ |
| 2222 |
| 2223 static unsigned int |
| 2224 bfd_mach_o_count_indirect_symbols (bfd *abfd, bfd_mach_o_data_struct *mdata) |
| 2225 { |
| 2226 unsigned int i; |
| 2227 unsigned int nisyms = 0; |
| 2228 |
| 2229 for (i = 0; i < mdata->nsects; ++i) |
| 2230 { |
| 2231 bfd_mach_o_section *sec = mdata->sections[i]; |
| 2232 |
| 2233 switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK) |
| 2234 » { |
| 2235 » case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS: |
| 2236 » case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS: |
| 2237 » case BFD_MACH_O_S_SYMBOL_STUBS: |
| 2238 » nisyms += bfd_mach_o_section_get_nbr_indirect (abfd, sec); |
| 2239 » break; |
| 2240 » default: |
| 2241 » break; |
| 2242 » } |
| 2243 } |
| 2244 return nisyms; |
| 2245 } |
| 2246 |
| 2247 static bfd_boolean |
| 2248 bfd_mach_o_build_dysymtab_command (bfd *abfd, |
| 2249 » » » » bfd_mach_o_data_struct *mdata, |
| 2250 » » » » bfd_mach_o_load_command *cmd) |
| 2251 { |
| 2252 bfd_mach_o_dysymtab_command *dsym = &cmd->command.dysymtab; |
| 2253 |
| 2254 /* TODO: |
| 2255 We are not going to try and fill these in yet and, moreover, we are |
| 2256 going to bail if they are already set. */ |
| 2257 if (dsym->nmodtab != 0 |
| 2258 || dsym->ntoc != 0 |
| 2259 || dsym->nextrefsyms != 0) |
| 2260 { |
| 2261 (*_bfd_error_handler) (_("sorry: modtab, toc and extrefsyms are not yet" |
| 2262 » » » » " implemented for dysymtab commands.")); |
| 2263 return FALSE; |
| 2264 } |
| 2265 |
| 2266 dsym->ilocalsym = 0; |
| 2267 |
| 2268 if (bfd_get_symcount (abfd) > 0) |
| 2269 { |
| 2270 asymbol **symbols = bfd_get_outsymbols (abfd); |
| 2271 unsigned long i; |
| 2272 |
| 2273 /* Count the number of each kind of symbol. */ |
| 2274 for (i = 0; i < bfd_get_symcount (abfd); ++i) |
| 2275 » { |
| 2276 » bfd_mach_o_asymbol *s = (bfd_mach_o_asymbol *)symbols[i]; |
| 2277 » if (s->n_type & (BFD_MACH_O_N_EXT | BFD_MACH_O_N_PEXT)) |
| 2278 » break; |
| 2279 » } |
| 2280 dsym->nlocalsym = i; |
| 2281 dsym->iextdefsym = i; |
| 2282 for (; i < bfd_get_symcount (abfd); ++i) |
| 2283 » { |
| 2284 » bfd_mach_o_asymbol *s = (bfd_mach_o_asymbol *)symbols[i]; |
| 2285 » if ((s->n_type & BFD_MACH_O_N_TYPE) == BFD_MACH_O_N_UNDF) |
| 2286 » break; |
| 2287 » } |
| 2288 dsym->nextdefsym = i - dsym->nlocalsym; |
| 2289 dsym->iundefsym = dsym->nextdefsym + dsym->iextdefsym; |
| 2290 dsym->nundefsym = bfd_get_symcount (abfd) |
| 2291 » » » - dsym->nlocalsym |
| 2292 » » » - dsym->nextdefsym; |
| 2293 } |
| 2294 else |
| 2295 { |
| 2296 dsym->nlocalsym = 0; |
| 2297 dsym->iextdefsym = 0; |
| 2298 dsym->nextdefsym = 0; |
| 2299 dsym->iundefsym = 0; |
| 2300 dsym->nundefsym = 0; |
| 2301 } |
| 2302 |
| 2303 dsym->nindirectsyms = bfd_mach_o_count_indirect_symbols (abfd, mdata); |
| 2304 if (dsym->nindirectsyms > 0) |
| 2305 { |
| 2306 unsigned i; |
| 2307 unsigned n; |
| 2308 |
| 2309 mdata->filelen = FILE_ALIGN (mdata->filelen, 2); |
| 2310 dsym->indirectsymoff = mdata->filelen; |
| 2311 mdata->filelen += dsym->nindirectsyms * 4; |
| 2312 |
| 2313 dsym->indirect_syms = bfd_zalloc (abfd, dsym->nindirectsyms * 4); |
| 2314 if (dsym->indirect_syms == NULL) |
| 2315 return FALSE; |
| 2316 » » |
| 2317 n = 0; |
| 2318 for (i = 0; i < mdata->nsects; ++i) |
| 2319 » { |
| 2320 » bfd_mach_o_section *sec = mdata->sections[i]; |
| 2321 |
| 2322 » switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK) |
| 2323 » { |
| 2324 » case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS: |
| 2325 » case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS: |
| 2326 » case BFD_MACH_O_S_SYMBOL_STUBS: |
| 2327 » » { |
| 2328 » » unsigned j, num; |
| 2329 » » bfd_mach_o_asymbol **isyms = sec->indirect_syms; |
| 2330 » » |
| 2331 » » num = bfd_mach_o_section_get_nbr_indirect (abfd, sec); |
| 2332 » » if (isyms == NULL || num == 0) |
| 2333 » » break; |
| 2334 » » /* Record the starting index in the reserved1 field. */ |
| 2335 » » sec->reserved1 = n; |
| 2336 » » for (j = 0; j < num; j++, n++) |
| 2337 » » { |
| 2338 » » if (isyms[j] == NULL) |
| 2339 » » dsym->indirect_syms[n] = BFD_MACH_O_INDIRECT_SYM_LOCAL; |
| 2340 » » else if (isyms[j]->symbol.section == bfd_abs_section_ptr |
| 2341 » » » && ! (isyms[j]->n_type & BFD_MACH_O_N_EXT)) |
| 2342 » » dsym->indirect_syms[n] = BFD_MACH_O_INDIRECT_SYM_LOCAL |
| 2343 » » » » » » | BFD_MACH_O_INDIRECT_SYM_ABS; |
| 2344 » » else |
| 2345 » » dsym->indirect_syms[n] = isyms[j]->symbol.udata.i; |
| 2346 » » } |
| 2347 » » } |
| 2348 » » break; |
| 2349 » default: |
| 2350 » » break; |
| 2351 » } |
| 2352 » } |
| 2353 } |
| 2354 |
| 2355 return TRUE; |
| 2356 } |
| 2357 |
| 2358 /* Build Mach-O load commands (currently assuming an MH_OBJECT file). |
| 2359 TODO: Other file formats, rebuilding symtab/dysymtab commands for strip |
| 2360 and copy functionality. */ |
1348 | 2361 |
1349 bfd_boolean | 2362 bfd_boolean |
1350 bfd_mach_o_build_commands (bfd *abfd) | 2363 bfd_mach_o_build_commands (bfd *abfd) |
1351 { | 2364 { |
1352 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd); | 2365 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd); |
1353 unsigned int wide = mach_o_wide_p (&mdata->header); | 2366 unsigned wide = mach_o_wide_p (&mdata->header); |
1354 bfd_mach_o_segment_command *seg; | 2367 int segcmd_idx = -1; |
1355 asection *sec; | 2368 int symtab_idx = -1; |
1356 bfd_mach_o_load_command *cmd; | 2369 int dysymtab_idx = -1; |
1357 bfd_mach_o_load_command *symtab_cmd; | 2370 unsigned long base_offset = 0; |
1358 int target_index; | 2371 |
1359 | 2372 /* Return now if commands are already present. */ |
1360 /* Return now if commands are already built. */ | |
1361 if (mdata->header.ncmds) | 2373 if (mdata->header.ncmds) |
1362 return FALSE; | 2374 return FALSE; |
1363 | 2375 |
1364 /* Very simple version: a command (segment) to contain all the sections and | 2376 /* Fill in the file type, if not already set. */ |
1365 a command for the symbol table. */ | 2377 |
1366 mdata->header.ncmds = 2; | 2378 if (mdata->header.filetype == 0) |
1367 mdata->commands = bfd_alloc (abfd, mdata->header.ncmds | 2379 { |
1368 * sizeof (bfd_mach_o_load_command)); | 2380 if (abfd->flags & EXEC_P) |
| 2381 mdata->header.filetype = BFD_MACH_O_MH_EXECUTE; |
| 2382 else if (abfd->flags & DYNAMIC) |
| 2383 mdata->header.filetype = BFD_MACH_O_MH_DYLIB; |
| 2384 else |
| 2385 mdata->header.filetype = BFD_MACH_O_MH_OBJECT; |
| 2386 } |
| 2387 |
| 2388 /* If hasn't already been done, flatten sections list, and sort |
| 2389 if/when required. Must be done before the symbol table is adjusted, |
| 2390 since that depends on properly numbered sections. */ |
| 2391 if (mdata->nsects == 0 || mdata->sections == NULL) |
| 2392 if (! bfd_mach_o_mangle_sections (abfd, mdata)) |
| 2393 return FALSE; |
| 2394 |
| 2395 /* Order the symbol table, fill-in/check mach-o specific fields and |
| 2396 partition out any indirect symbols. */ |
| 2397 if (!bfd_mach_o_mangle_symbols (abfd)) |
| 2398 return FALSE; |
| 2399 |
| 2400 /* Very simple command set (only really applicable to MH_OBJECTs): |
| 2401 All the commands are optional - present only when there is suitable data. |
| 2402 (i.e. it is valid to have an empty file) |
| 2403 |
| 2404 » a command (segment) to contain all the sections, |
| 2405 » command for the symbol table, |
| 2406 » a command for the dysymtab. |
| 2407 |
| 2408 ??? maybe we should assert that this is an MH_OBJECT? */ |
| 2409 |
| 2410 if (mdata->nsects > 0) |
| 2411 { |
| 2412 segcmd_idx = 0; |
| 2413 mdata->header.ncmds = 1; |
| 2414 } |
| 2415 |
| 2416 if (bfd_get_symcount (abfd) > 0) |
| 2417 { |
| 2418 mdata->header.ncmds++; |
| 2419 symtab_idx = segcmd_idx + 1; /* 0 if the seg command is absent. */ |
| 2420 } |
| 2421 |
| 2422 /* FIXME: |
| 2423 This is a rather crude test for whether we should build a dysymtab. */ |
| 2424 if (bfd_mach_o_should_emit_dysymtab () |
| 2425 && bfd_get_symcount (abfd)) |
| 2426 { |
| 2427 mdata->header.ncmds++; |
| 2428 /* If there should be a case where a dysymtab could be emitted without |
| 2429 » a symtab (seems improbable), this would need amending. */ |
| 2430 dysymtab_idx = symtab_idx + 1; |
| 2431 } |
| 2432 |
| 2433 if (wide) |
| 2434 base_offset = BFD_MACH_O_HEADER_64_SIZE; |
| 2435 else |
| 2436 base_offset = BFD_MACH_O_HEADER_SIZE; |
| 2437 |
| 2438 /* Well, we must have a header, at least. */ |
| 2439 mdata->filelen = base_offset; |
| 2440 |
| 2441 /* A bit unusual, but no content is valid; |
| 2442 as -n empty.s -o empty.o */ |
| 2443 if (mdata->header.ncmds == 0) |
| 2444 return TRUE; |
| 2445 |
| 2446 mdata->commands = bfd_zalloc (abfd, mdata->header.ncmds |
| 2447 * sizeof (bfd_mach_o_load_command)); |
1369 if (mdata->commands == NULL) | 2448 if (mdata->commands == NULL) |
1370 return FALSE; | 2449 return FALSE; |
1371 cmd = &mdata->commands[0]; | 2450 |
1372 seg = &cmd->command.segment; | 2451 if (segcmd_idx >= 0) |
1373 | 2452 { |
1374 seg->nsects = bfd_count_sections (abfd); | 2453 bfd_mach_o_load_command *cmd = &mdata->commands[segcmd_idx]; |
1375 | 2454 bfd_mach_o_segment_command *seg = &cmd->command.segment; |
1376 /* Set segment command. */ | 2455 |
1377 if (wide) | 2456 /* Count the segctions in the special blank segment used for MH_OBJECT. *
/ |
1378 { | 2457 seg->nsects = bfd_mach_o_count_sections_for_seg (NULL, mdata); |
1379 cmd->type = BFD_MACH_O_LC_SEGMENT_64; | 2458 if (seg->nsects == (unsigned long) -1) |
1380 cmd->offset = BFD_MACH_O_HEADER_64_SIZE; | 2459 » return FALSE; |
1381 cmd->len = BFD_MACH_O_LC_SEGMENT_64_SIZE | 2460 |
1382 + BFD_MACH_O_SECTION_64_SIZE * seg->nsects; | 2461 /* Init segment command. */ |
1383 } | 2462 cmd->offset = base_offset; |
1384 else | 2463 if (wide) |
1385 { | 2464 » { |
1386 cmd->type = BFD_MACH_O_LC_SEGMENT; | 2465 » cmd->type = BFD_MACH_O_LC_SEGMENT_64; |
1387 cmd->offset = BFD_MACH_O_HEADER_SIZE; | 2466 » cmd->len = BFD_MACH_O_LC_SEGMENT_64_SIZE |
1388 cmd->len = BFD_MACH_O_LC_SEGMENT_SIZE | 2467 » » » + BFD_MACH_O_SECTION_64_SIZE * seg->nsects; |
1389 + BFD_MACH_O_SECTION_SIZE * seg->nsects; | 2468 » } |
1390 } | 2469 else |
1391 cmd->type_required = FALSE; | 2470 » { |
1392 mdata->header.sizeofcmds = cmd->len; | 2471 » cmd->type = BFD_MACH_O_LC_SEGMENT; |
1393 mdata->filelen = cmd->offset + cmd->len; | 2472 » cmd->len = BFD_MACH_O_LC_SEGMENT_SIZE |
1394 | 2473 » » » + BFD_MACH_O_SECTION_SIZE * seg->nsects; |
1395 /* Set symtab command. */ | 2474 » } |
1396 symtab_cmd = &mdata->commands[1]; | 2475 |
| 2476 cmd->type_required = FALSE; |
| 2477 mdata->header.sizeofcmds = cmd->len; |
| 2478 mdata->filelen += cmd->len; |
| 2479 } |
| 2480 |
| 2481 if (symtab_idx >= 0) |
| 2482 { |
| 2483 /* Init symtab command. */ |
| 2484 bfd_mach_o_load_command *cmd = &mdata->commands[symtab_idx]; |
1397 | 2485 |
1398 symtab_cmd->type = BFD_MACH_O_LC_SYMTAB; | 2486 cmd->type = BFD_MACH_O_LC_SYMTAB; |
1399 symtab_cmd->offset = cmd->offset + cmd->len; | 2487 cmd->offset = base_offset; |
1400 symtab_cmd->len = 6 * 4; | 2488 if (segcmd_idx >= 0) |
1401 symtab_cmd->type_required = FALSE; | 2489 cmd->offset += mdata->commands[segcmd_idx].len; |
1402 | 2490 |
1403 mdata->header.sizeofcmds += symtab_cmd->len; | 2491 cmd->len = sizeof (struct mach_o_symtab_command_external) |
1404 mdata->filelen += symtab_cmd->len; | 2492 » » + BFD_MACH_O_LC_SIZE; |
1405 | 2493 cmd->type_required = FALSE; |
1406 /* Fill segment command. */ | 2494 mdata->header.sizeofcmds += cmd->len; |
1407 memset (seg->segname, 0, sizeof (seg->segname)); | 2495 mdata->filelen += cmd->len; |
1408 seg->vmaddr = 0; | 2496 } |
1409 seg->fileoff = mdata->filelen; | 2497 |
1410 seg->filesize = 0; | 2498 /* If required, setup symtab command, see comment above about the quality |
1411 seg->maxprot = BFD_MACH_O_PROT_READ | BFD_MACH_O_PROT_WRITE | 2499 of this test. */ |
1412 | BFD_MACH_O_PROT_EXECUTE; | 2500 if (dysymtab_idx >= 0) |
1413 seg->initprot = seg->maxprot; | 2501 { |
1414 seg->flags = 0; | 2502 bfd_mach_o_load_command *cmd = &mdata->commands[dysymtab_idx]; |
1415 seg->sect_head = NULL; | 2503 |
1416 seg->sect_tail = NULL; | 2504 cmd->type = BFD_MACH_O_LC_DYSYMTAB; |
1417 | 2505 if (symtab_idx >= 0) |
1418 /* Create Mach-O sections. */ | 2506 cmd->offset = mdata->commands[symtab_idx].offset |
1419 target_index = 0; | 2507 » » + mdata->commands[symtab_idx].len; |
1420 for (sec = abfd->sections; sec; sec = sec->next) | 2508 else if (segcmd_idx >= 0) |
1421 { | 2509 cmd->offset = mdata->commands[segcmd_idx].offset |
1422 bfd_mach_o_section *msect = bfd_mach_o_get_mach_o_section (sec); | 2510 » » + mdata->commands[segcmd_idx].len; |
1423 | |
1424 bfd_mach_o_append_section_to_segment (seg, sec); | |
1425 | |
1426 if (msect->flags == 0) | |
1427 { | |
1428 /* We suppose it hasn't been set. Convert from BFD flags. */ | |
1429 bfd_mach_o_set_section_flags_from_bfd (abfd, sec); | |
1430 } | |
1431 msect->addr = bfd_get_section_vma (abfd, sec); | |
1432 msect->size = bfd_get_section_size (sec); | |
1433 msect->align = bfd_get_section_alignment (abfd, sec); | |
1434 | |
1435 if (msect->size != 0) | |
1436 { | |
1437 mdata->filelen = FILE_ALIGN (mdata->filelen, msect->align); | |
1438 msect->offset = mdata->filelen; | |
1439 } | |
1440 else | 2511 else |
1441 msect->offset = 0; | 2512 » cmd->offset = base_offset; |
1442 | 2513 |
1443 sec->filepos = msect->offset; | 2514 cmd->type_required = FALSE; |
1444 sec->target_index = ++target_index; | 2515 cmd->len = sizeof (struct mach_o_dysymtab_command_external) |
1445 | 2516 » » + BFD_MACH_O_LC_SIZE; |
1446 mdata->filelen += msect->size; | 2517 |
1447 } | 2518 mdata->header.sizeofcmds += cmd->len; |
1448 seg->filesize = mdata->filelen - seg->fileoff; | 2519 mdata->filelen += cmd->len; |
1449 seg->vmsize = seg->filesize; | 2520 } |
1450 | 2521 |
| 2522 /* So, now we have sized the commands and the filelen set to that. |
| 2523 Now we can build the segment command and set the section file offsets. */ |
| 2524 if (segcmd_idx >= 0 |
| 2525 && ! bfd_mach_o_build_seg_command |
| 2526 » » (NULL, mdata, &mdata->commands[segcmd_idx].command.segment)) |
| 2527 return FALSE; |
| 2528 |
| 2529 /* If we're doing a dysymtab, cmd points to its load command. */ |
| 2530 if (dysymtab_idx >= 0 |
| 2531 && ! bfd_mach_o_build_dysymtab_command (abfd, mdata, |
| 2532 » » » » » &mdata->commands[dysymtab_idx])) |
| 2533 return FALSE; |
| 2534 |
| 2535 /* The symtab command is filled in when the symtab is written. */ |
1451 return TRUE; | 2536 return TRUE; |
1452 } | 2537 } |
1453 | 2538 |
1454 /* Set the contents of a section. */ | 2539 /* Set the contents of a section. */ |
1455 | 2540 |
1456 bfd_boolean | 2541 bfd_boolean |
1457 bfd_mach_o_set_section_contents (bfd *abfd, | 2542 bfd_mach_o_set_section_contents (bfd *abfd, |
1458 asection *section, | 2543 asection *section, |
1459 const void * location, | 2544 const void * location, |
1460 file_ptr offset, | 2545 file_ptr offset, |
1461 bfd_size_type count) | 2546 bfd_size_type count) |
1462 { | 2547 { |
1463 file_ptr pos; | 2548 file_ptr pos; |
1464 | 2549 |
1465 /* This must be done first, because bfd_set_section_contents is | 2550 /* Trying to write the first section contents will trigger the creation of |
1466 going to set output_has_begun to TRUE. */ | 2551 the load commands if they are not already present. */ |
1467 if (! abfd->output_has_begun && ! bfd_mach_o_build_commands (abfd)) | 2552 if (! abfd->output_has_begun && ! bfd_mach_o_build_commands (abfd)) |
1468 return FALSE; | 2553 return FALSE; |
1469 | 2554 |
1470 if (count == 0) | 2555 if (count == 0) |
1471 return TRUE; | 2556 return TRUE; |
1472 | 2557 |
1473 pos = section->filepos + offset; | 2558 pos = section->filepos + offset; |
1474 if (bfd_seek (abfd, pos, SEEK_SET) != 0 | 2559 if (bfd_seek (abfd, pos, SEEK_SET) != 0 |
1475 || bfd_bwrite (location, count, abfd) != count) | 2560 || bfd_bwrite (location, count, abfd) != count) |
1476 return FALSE; | 2561 return FALSE; |
(...skipping 13 matching lines...) Expand all Loading... |
1490 | 2575 |
1491 asymbol * | 2576 asymbol * |
1492 bfd_mach_o_make_empty_symbol (bfd *abfd) | 2577 bfd_mach_o_make_empty_symbol (bfd *abfd) |
1493 { | 2578 { |
1494 asymbol *new_symbol; | 2579 asymbol *new_symbol; |
1495 | 2580 |
1496 new_symbol = bfd_zalloc (abfd, sizeof (bfd_mach_o_asymbol)); | 2581 new_symbol = bfd_zalloc (abfd, sizeof (bfd_mach_o_asymbol)); |
1497 if (new_symbol == NULL) | 2582 if (new_symbol == NULL) |
1498 return new_symbol; | 2583 return new_symbol; |
1499 new_symbol->the_bfd = abfd; | 2584 new_symbol->the_bfd = abfd; |
1500 new_symbol->udata.i = 0; | 2585 new_symbol->udata.i = SYM_MACHO_FIELDS_UNSET; |
1501 return new_symbol; | 2586 return new_symbol; |
1502 } | 2587 } |
1503 | 2588 |
1504 static bfd_boolean | 2589 static bfd_boolean |
1505 bfd_mach_o_read_header (bfd *abfd, bfd_mach_o_header *header) | 2590 bfd_mach_o_read_header (bfd *abfd, bfd_mach_o_header *header) |
1506 { | 2591 { |
1507 struct mach_o_header_external raw; | 2592 struct mach_o_header_external raw; |
1508 unsigned int size; | 2593 unsigned int size; |
1509 bfd_vma (*get32) (const void *) = NULL; | 2594 bfd_vma (*get32) (const void *) = NULL; |
1510 | 2595 |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1557 | 2642 |
1558 header->cputype = (*get32) (raw.cputype); | 2643 header->cputype = (*get32) (raw.cputype); |
1559 header->cpusubtype = (*get32) (raw.cpusubtype); | 2644 header->cpusubtype = (*get32) (raw.cpusubtype); |
1560 header->filetype = (*get32) (raw.filetype); | 2645 header->filetype = (*get32) (raw.filetype); |
1561 header->ncmds = (*get32) (raw.ncmds); | 2646 header->ncmds = (*get32) (raw.ncmds); |
1562 header->sizeofcmds = (*get32) (raw.sizeofcmds); | 2647 header->sizeofcmds = (*get32) (raw.sizeofcmds); |
1563 header->flags = (*get32) (raw.flags); | 2648 header->flags = (*get32) (raw.flags); |
1564 | 2649 |
1565 if (mach_o_wide_p (header)) | 2650 if (mach_o_wide_p (header)) |
1566 header->reserved = (*get32) (raw.reserved); | 2651 header->reserved = (*get32) (raw.reserved); |
| 2652 else |
| 2653 header->reserved = 0; |
1567 | 2654 |
1568 return TRUE; | 2655 return TRUE; |
1569 } | 2656 } |
1570 | 2657 |
1571 bfd_boolean | 2658 bfd_boolean |
1572 bfd_mach_o_new_section_hook (bfd *abfd, asection *sec) | 2659 bfd_mach_o_new_section_hook (bfd *abfd, asection *sec) |
1573 { | 2660 { |
1574 bfd_mach_o_section *s; | 2661 bfd_mach_o_section *s; |
| 2662 unsigned bfdalign = bfd_get_section_alignment (abfd, sec); |
1575 | 2663 |
1576 s = bfd_mach_o_get_mach_o_section (sec); | 2664 s = bfd_mach_o_get_mach_o_section (sec); |
1577 if (s == NULL) | 2665 if (s == NULL) |
1578 { | 2666 { |
1579 flagword bfd_flags; | 2667 flagword bfd_flags; |
| 2668 static const mach_o_section_name_xlat * xlat; |
1580 | 2669 |
1581 s = (bfd_mach_o_section *) bfd_zalloc (abfd, sizeof (*s)); | 2670 s = (bfd_mach_o_section *) bfd_zalloc (abfd, sizeof (*s)); |
1582 if (s == NULL) | 2671 if (s == NULL) |
1583 return FALSE; | 2672 return FALSE; |
1584 sec->used_by_bfd = s; | 2673 sec->used_by_bfd = s; |
1585 s->bfdsection = sec; | 2674 s->bfdsection = sec; |
1586 | 2675 |
1587 /* Create default name. */ | 2676 /* Create the Darwin seg/sect name pair from the bfd name. |
1588 bfd_mach_o_convert_section_name_to_mach_o (abfd, sec, s); | 2677 » If this is a canonical name for which a specific paiting exists |
1589 | 2678 » there will also be defined flags, type, attribute and alignment |
1590 /* Create default flags. */ | 2679 » values. */ |
1591 bfd_flags = bfd_get_section_flags (abfd, sec); | 2680 xlat = bfd_mach_o_convert_section_name_to_mach_o (abfd, sec, s); |
1592 if ((bfd_flags & SEC_CODE) == SEC_CODE) | 2681 if (xlat != NULL) |
1593 s->flags = BFD_MACH_O_S_ATTR_PURE_INSTRUCTIONS | 2682 » { |
1594 | BFD_MACH_O_S_ATTR_SOME_INSTRUCTIONS | 2683 » s->flags = xlat->macho_sectype | xlat->macho_secattr; |
1595 | BFD_MACH_O_S_REGULAR; | 2684 » s->align = xlat->sectalign > bfdalign ? xlat->sectalign |
1596 else if ((bfd_flags & (SEC_ALLOC | SEC_LOAD)) == SEC_ALLOC) | 2685 » » » » » » : bfdalign; |
1597 s->flags = BFD_MACH_O_S_ZEROFILL; | 2686 » bfd_set_section_alignment (abfd, sec, s->align); |
1598 else if (bfd_flags & SEC_DEBUGGING) | 2687 » bfd_flags = bfd_get_section_flags (abfd, sec); |
1599 s->flags = BFD_MACH_O_S_REGULAR | BFD_MACH_O_S_ATTR_DEBUG; | 2688 » if (bfd_flags == SEC_NO_FLAGS) |
| 2689 » bfd_set_section_flags (abfd, sec, xlat->bfd_flags); |
| 2690 » } |
1600 else | 2691 else |
1601 s->flags = BFD_MACH_O_S_REGULAR; | 2692 » /* Create default flags. */ |
| 2693 » bfd_mach_o_set_section_flags_from_bfd (abfd, sec); |
1602 } | 2694 } |
1603 | 2695 |
1604 return _bfd_generic_new_section_hook (abfd, sec); | 2696 return _bfd_generic_new_section_hook (abfd, sec); |
1605 } | 2697 } |
1606 | 2698 |
1607 static void | 2699 static void |
1608 bfd_mach_o_init_section_from_mach_o (bfd *abfd, asection *sec, | 2700 bfd_mach_o_init_section_from_mach_o (bfd *abfd, asection *sec, |
1609 unsigned long prot) | 2701 unsigned long prot) |
1610 { | 2702 { |
1611 flagword flags; | 2703 flagword flags; |
1612 bfd_mach_o_section *section; | 2704 bfd_mach_o_section *section; |
1613 | 2705 |
1614 flags = bfd_get_section_flags (abfd, sec); | 2706 flags = bfd_get_section_flags (abfd, sec); |
1615 section = bfd_mach_o_get_mach_o_section (sec); | 2707 section = bfd_mach_o_get_mach_o_section (sec); |
1616 | 2708 |
| 2709 /* TODO: see if we should use the xlat system for doing this by |
| 2710 preference and fall back to this for unknown sections. */ |
| 2711 |
1617 if (flags == SEC_NO_FLAGS) | 2712 if (flags == SEC_NO_FLAGS) |
1618 { | 2713 { |
1619 /* Try to guess flags. */ | 2714 /* Try to guess flags. */ |
1620 if (section->flags & BFD_MACH_O_S_ATTR_DEBUG) | 2715 if (section->flags & BFD_MACH_O_S_ATTR_DEBUG) |
1621 flags = SEC_DEBUGGING; | 2716 flags = SEC_DEBUGGING; |
1622 else | 2717 else |
1623 { | 2718 { |
1624 flags = SEC_ALLOC; | 2719 flags = SEC_ALLOC; |
1625 if ((section->flags & BFD_MACH_O_SECTION_TYPE_MASK) | 2720 if ((section->flags & BFD_MACH_O_SECTION_TYPE_MASK) |
1626 != BFD_MACH_O_S_ZEROFILL) | 2721 != BFD_MACH_O_S_ZEROFILL) |
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1810 (_("bfd_mach_o_read_symtab_symbol: name out of range (%lu >= %lu)"), | 2905 (_("bfd_mach_o_read_symtab_symbol: name out of range (%lu >= %lu)"), |
1811 (unsigned long) stroff, | 2906 (unsigned long) stroff, |
1812 (unsigned long) sym->strsize); | 2907 (unsigned long) sym->strsize); |
1813 return FALSE; | 2908 return FALSE; |
1814 } | 2909 } |
1815 | 2910 |
1816 s->symbol.the_bfd = abfd; | 2911 s->symbol.the_bfd = abfd; |
1817 s->symbol.name = sym->strtab + stroff; | 2912 s->symbol.name = sym->strtab + stroff; |
1818 s->symbol.value = value; | 2913 s->symbol.value = value; |
1819 s->symbol.flags = 0x0; | 2914 s->symbol.flags = 0x0; |
1820 s->symbol.udata.i = 0; | 2915 s->symbol.udata.i = i; |
1821 s->n_type = type; | 2916 s->n_type = type; |
1822 s->n_sect = section; | 2917 s->n_sect = section; |
1823 s->n_desc = desc; | 2918 s->n_desc = desc; |
1824 | 2919 |
1825 if (type & BFD_MACH_O_N_STAB) | 2920 if (type & BFD_MACH_O_N_STAB) |
1826 { | 2921 { |
1827 s->symbol.flags |= BSF_DEBUGGING; | 2922 s->symbol.flags |= BSF_DEBUGGING; |
1828 s->symbol.section = bfd_und_section_ptr; | 2923 s->symbol.section = bfd_und_section_ptr; |
1829 switch (type) | 2924 switch (type) |
1830 { | 2925 { |
(...skipping 10 matching lines...) Expand all Loading... |
1841 { | 2936 { |
1842 s->symbol.section = mdata->sections[section - 1]->bfdsection; | 2937 s->symbol.section = mdata->sections[section - 1]->bfdsection; |
1843 s->symbol.value = | 2938 s->symbol.value = |
1844 s->symbol.value - mdata->sections[section - 1]->addr; | 2939 s->symbol.value - mdata->sections[section - 1]->addr; |
1845 } | 2940 } |
1846 break; | 2941 break; |
1847 } | 2942 } |
1848 } | 2943 } |
1849 else | 2944 else |
1850 { | 2945 { |
1851 if (type & BFD_MACH_O_N_PEXT) | 2946 if (type & (BFD_MACH_O_N_PEXT | BFD_MACH_O_N_EXT)) |
1852 s->symbol.flags |= BSF_GLOBAL; | 2947 s->symbol.flags |= BSF_GLOBAL; |
1853 | 2948 else |
1854 if (type & BFD_MACH_O_N_EXT) | |
1855 » s->symbol.flags |= BSF_GLOBAL; | |
1856 | |
1857 if (!(type & (BFD_MACH_O_N_PEXT | BFD_MACH_O_N_EXT))) | |
1858 s->symbol.flags |= BSF_LOCAL; | 2949 s->symbol.flags |= BSF_LOCAL; |
1859 | 2950 |
1860 switch (symtype) | 2951 switch (symtype) |
1861 { | 2952 { |
1862 case BFD_MACH_O_N_UNDF: | 2953 case BFD_MACH_O_N_UNDF: |
1863 if (type == (BFD_MACH_O_N_UNDF | BFD_MACH_O_N_EXT) | 2954 if (type == (BFD_MACH_O_N_UNDF | BFD_MACH_O_N_EXT) |
1864 && s->symbol.value != 0) | 2955 && s->symbol.value != 0) |
1865 { | 2956 { |
1866 /* A common symbol. */ | 2957 /* A common symbol. */ |
1867 s->symbol.section = bfd_com_section_ptr; | 2958 s->symbol.section = bfd_com_section_ptr; |
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2104 bfd_mach_o_read_prebound_dylib (bfd *abfd ATTRIBUTE_UNUSED, | 3195 bfd_mach_o_read_prebound_dylib (bfd *abfd ATTRIBUTE_UNUSED, |
2105 bfd_mach_o_load_command *command ATTRIBUTE_UNUSE
D) | 3196 bfd_mach_o_load_command *command ATTRIBUTE_UNUSE
D) |
2106 { | 3197 { |
2107 /* bfd_mach_o_prebound_dylib_command *cmd = &command->command.prebound_dylib;
*/ | 3198 /* bfd_mach_o_prebound_dylib_command *cmd = &command->command.prebound_dylib;
*/ |
2108 | 3199 |
2109 BFD_ASSERT (command->type == BFD_MACH_O_LC_PREBOUND_DYLIB); | 3200 BFD_ASSERT (command->type == BFD_MACH_O_LC_PREBOUND_DYLIB); |
2110 return 0; | 3201 return 0; |
2111 } | 3202 } |
2112 | 3203 |
2113 static int | 3204 static int |
| 3205 bfd_mach_o_read_fvmlib (bfd *abfd, bfd_mach_o_load_command *command) |
| 3206 { |
| 3207 bfd_mach_o_fvmlib_command *fvm = &command->command.fvmlib; |
| 3208 struct mach_o_fvmlib_command_external raw; |
| 3209 unsigned int nameoff; |
| 3210 |
| 3211 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0 |
| 3212 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw)) |
| 3213 return -1; |
| 3214 |
| 3215 nameoff = bfd_h_get_32 (abfd, raw.name); |
| 3216 fvm->minor_version = bfd_h_get_32 (abfd, raw.minor_version); |
| 3217 fvm->header_addr = bfd_h_get_32 (abfd, raw.header_addr); |
| 3218 |
| 3219 fvm->name_offset = command->offset + nameoff; |
| 3220 fvm->name_len = command->len - nameoff; |
| 3221 fvm->name_str = bfd_alloc (abfd, fvm->name_len); |
| 3222 if (fvm->name_str == NULL) |
| 3223 return -1; |
| 3224 if (bfd_seek (abfd, fvm->name_offset, SEEK_SET) != 0 |
| 3225 || bfd_bread (fvm->name_str, fvm->name_len, abfd) != fvm->name_len) |
| 3226 return -1; |
| 3227 return 0; |
| 3228 } |
| 3229 |
| 3230 static int |
2114 bfd_mach_o_read_thread (bfd *abfd, bfd_mach_o_load_command *command) | 3231 bfd_mach_o_read_thread (bfd *abfd, bfd_mach_o_load_command *command) |
2115 { | 3232 { |
2116 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd); | 3233 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd); |
2117 bfd_mach_o_thread_command *cmd = &command->command.thread; | 3234 bfd_mach_o_thread_command *cmd = &command->command.thread; |
2118 unsigned int offset; | 3235 unsigned int offset; |
2119 unsigned int nflavours; | 3236 unsigned int nflavours; |
2120 unsigned int i; | 3237 unsigned int i; |
2121 | 3238 |
2122 BFD_ASSERT ((command->type == BFD_MACH_O_LC_THREAD) | 3239 BFD_ASSERT ((command->type == BFD_MACH_O_LC_THREAD) |
2123 || (command->type == BFD_MACH_O_LC_UNIXTHREAD)); | 3240 || (command->type == BFD_MACH_O_LC_UNIXTHREAD)); |
(...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2516 return FALSE; | 3633 return FALSE; |
2517 | 3634 |
2518 ver = bfd_get_32 (abfd, raw.version); | 3635 ver = bfd_get_32 (abfd, raw.version); |
2519 cmd->rel = ver >> 16; | 3636 cmd->rel = ver >> 16; |
2520 cmd->maj = ver >> 8; | 3637 cmd->maj = ver >> 8; |
2521 cmd->min = ver; | 3638 cmd->min = ver; |
2522 cmd->reserved = bfd_get_32 (abfd, raw.reserved); | 3639 cmd->reserved = bfd_get_32 (abfd, raw.reserved); |
2523 return TRUE; | 3640 return TRUE; |
2524 } | 3641 } |
2525 | 3642 |
| 3643 static bfd_boolean |
| 3644 bfd_mach_o_read_encryption_info (bfd *abfd, bfd_mach_o_load_command *command) |
| 3645 { |
| 3646 bfd_mach_o_encryption_info_command *cmd = &command->command.encryption_info; |
| 3647 struct mach_o_encryption_info_command_external raw; |
| 3648 |
| 3649 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0 |
| 3650 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw)) |
| 3651 return FALSE; |
| 3652 |
| 3653 cmd->cryptoff = bfd_get_32 (abfd, raw.cryptoff); |
| 3654 cmd->cryptsize = bfd_get_32 (abfd, raw.cryptsize); |
| 3655 cmd->cryptid = bfd_get_32 (abfd, raw.cryptid); |
| 3656 return TRUE; |
| 3657 } |
| 3658 |
2526 static int | 3659 static int |
2527 bfd_mach_o_read_segment (bfd *abfd, | 3660 bfd_mach_o_read_segment (bfd *abfd, |
2528 bfd_mach_o_load_command *command, | 3661 bfd_mach_o_load_command *command, |
2529 unsigned int wide) | 3662 unsigned int wide) |
2530 { | 3663 { |
2531 bfd_mach_o_segment_command *seg = &command->command.segment; | 3664 bfd_mach_o_segment_command *seg = &command->command.segment; |
2532 unsigned long i; | 3665 unsigned long i; |
2533 | 3666 |
2534 if (wide) | 3667 if (wide) |
2535 { | 3668 { |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2661 case BFD_MACH_O_LC_LOAD_UPWARD_DYLIB: | 3794 case BFD_MACH_O_LC_LOAD_UPWARD_DYLIB: |
2662 if (bfd_mach_o_read_dylib (abfd, command) != 0) | 3795 if (bfd_mach_o_read_dylib (abfd, command) != 0) |
2663 return -1; | 3796 return -1; |
2664 break; | 3797 break; |
2665 case BFD_MACH_O_LC_PREBOUND_DYLIB: | 3798 case BFD_MACH_O_LC_PREBOUND_DYLIB: |
2666 if (bfd_mach_o_read_prebound_dylib (abfd, command) != 0) | 3799 if (bfd_mach_o_read_prebound_dylib (abfd, command) != 0) |
2667 return -1; | 3800 return -1; |
2668 break; | 3801 break; |
2669 case BFD_MACH_O_LC_LOADFVMLIB: | 3802 case BFD_MACH_O_LC_LOADFVMLIB: |
2670 case BFD_MACH_O_LC_IDFVMLIB: | 3803 case BFD_MACH_O_LC_IDFVMLIB: |
| 3804 if (bfd_mach_o_read_fvmlib (abfd, command) != 0) |
| 3805 return -1; |
| 3806 break; |
2671 case BFD_MACH_O_LC_IDENT: | 3807 case BFD_MACH_O_LC_IDENT: |
2672 case BFD_MACH_O_LC_FVMFILE: | 3808 case BFD_MACH_O_LC_FVMFILE: |
2673 case BFD_MACH_O_LC_PREPAGE: | 3809 case BFD_MACH_O_LC_PREPAGE: |
2674 case BFD_MACH_O_LC_ROUTINES: | 3810 case BFD_MACH_O_LC_ROUTINES: |
2675 case BFD_MACH_O_LC_ROUTINES_64: | 3811 case BFD_MACH_O_LC_ROUTINES_64: |
2676 break; | 3812 break; |
2677 case BFD_MACH_O_LC_SUB_FRAMEWORK: | 3813 case BFD_MACH_O_LC_SUB_FRAMEWORK: |
2678 case BFD_MACH_O_LC_SUB_UMBRELLA: | 3814 case BFD_MACH_O_LC_SUB_UMBRELLA: |
2679 case BFD_MACH_O_LC_SUB_LIBRARY: | 3815 case BFD_MACH_O_LC_SUB_LIBRARY: |
2680 case BFD_MACH_O_LC_SUB_CLIENT: | 3816 case BFD_MACH_O_LC_SUB_CLIENT: |
(...skipping 11 matching lines...) Expand all Loading... |
2692 case BFD_MACH_O_LC_UUID: | 3828 case BFD_MACH_O_LC_UUID: |
2693 if (bfd_mach_o_read_uuid (abfd, command) != 0) | 3829 if (bfd_mach_o_read_uuid (abfd, command) != 0) |
2694 return -1; | 3830 return -1; |
2695 break; | 3831 break; |
2696 case BFD_MACH_O_LC_CODE_SIGNATURE: | 3832 case BFD_MACH_O_LC_CODE_SIGNATURE: |
2697 case BFD_MACH_O_LC_SEGMENT_SPLIT_INFO: | 3833 case BFD_MACH_O_LC_SEGMENT_SPLIT_INFO: |
2698 case BFD_MACH_O_LC_FUNCTION_STARTS: | 3834 case BFD_MACH_O_LC_FUNCTION_STARTS: |
2699 if (bfd_mach_o_read_linkedit (abfd, command) != 0) | 3835 if (bfd_mach_o_read_linkedit (abfd, command) != 0) |
2700 return -1; | 3836 return -1; |
2701 break; | 3837 break; |
| 3838 case BFD_MACH_O_LC_ENCRYPTION_INFO: |
| 3839 if (!bfd_mach_o_read_encryption_info (abfd, command)) |
| 3840 return -1; |
| 3841 break; |
2702 case BFD_MACH_O_LC_DYLD_INFO: | 3842 case BFD_MACH_O_LC_DYLD_INFO: |
2703 if (bfd_mach_o_read_dyld_info (abfd, command) != 0) | 3843 if (bfd_mach_o_read_dyld_info (abfd, command) != 0) |
2704 return -1; | 3844 return -1; |
2705 break; | 3845 break; |
2706 case BFD_MACH_O_LC_VERSION_MIN_MACOSX: | 3846 case BFD_MACH_O_LC_VERSION_MIN_MACOSX: |
2707 case BFD_MACH_O_LC_VERSION_MIN_IPHONEOS: | 3847 case BFD_MACH_O_LC_VERSION_MIN_IPHONEOS: |
2708 if (!bfd_mach_o_read_version_min (abfd, command)) | 3848 if (!bfd_mach_o_read_version_min (abfd, command)) |
2709 return -1; | 3849 return -1; |
2710 break; | 3850 break; |
2711 default: | 3851 default: |
2712 (*_bfd_error_handler)(_("%B: unable to read unknown load command 0x%lx"), | 3852 (*_bfd_error_handler)(_("%B: unknown load command 0x%lx"), |
2713 abfd, (unsigned long) command->type); | 3853 abfd, (unsigned long) command->type); |
2714 break; | 3854 break; |
2715 } | 3855 } |
2716 | 3856 |
2717 return 0; | 3857 return 0; |
2718 } | 3858 } |
2719 | 3859 |
2720 static void | 3860 static void |
2721 bfd_mach_o_flatten_sections (bfd *abfd) | 3861 bfd_mach_o_flatten_sections (bfd *abfd) |
2722 { | 3862 { |
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2940 mdata->header.cputype = 0; | 4080 mdata->header.cputype = 0; |
2941 mdata->header.cpusubtype = 0; | 4081 mdata->header.cpusubtype = 0; |
2942 mdata->header.filetype = 0; | 4082 mdata->header.filetype = 0; |
2943 mdata->header.ncmds = 0; | 4083 mdata->header.ncmds = 0; |
2944 mdata->header.sizeofcmds = 0; | 4084 mdata->header.sizeofcmds = 0; |
2945 mdata->header.flags = 0; | 4085 mdata->header.flags = 0; |
2946 mdata->header.byteorder = BFD_ENDIAN_UNKNOWN; | 4086 mdata->header.byteorder = BFD_ENDIAN_UNKNOWN; |
2947 mdata->commands = NULL; | 4087 mdata->commands = NULL; |
2948 mdata->nsects = 0; | 4088 mdata->nsects = 0; |
2949 mdata->sections = NULL; | 4089 mdata->sections = NULL; |
| 4090 mdata->dyn_reloc_cache = NULL; |
2950 | 4091 |
2951 return TRUE; | 4092 return TRUE; |
2952 } | 4093 } |
2953 | 4094 |
2954 static bfd_boolean | 4095 static bfd_boolean |
2955 bfd_mach_o_gen_mkobject (bfd *abfd) | 4096 bfd_mach_o_gen_mkobject (bfd *abfd) |
2956 { | 4097 { |
2957 bfd_mach_o_data_struct *mdata; | 4098 bfd_mach_o_data_struct *mdata; |
2958 | 4099 |
2959 if (!bfd_mach_o_mkobject_init (abfd)) | 4100 if (!bfd_mach_o_mkobject_init (abfd)) |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2998 goto wrong; | 4139 goto wrong; |
2999 | 4140 |
3000 /* Check cputype and filetype. | 4141 /* Check cputype and filetype. |
3001 In case of wildcard, do not accept magics that are handled by existing | 4142 In case of wildcard, do not accept magics that are handled by existing |
3002 targets. */ | 4143 targets. */ |
3003 if (cputype) | 4144 if (cputype) |
3004 { | 4145 { |
3005 if (header.cputype != cputype) | 4146 if (header.cputype != cputype) |
3006 goto wrong; | 4147 goto wrong; |
3007 } | 4148 } |
3008 else | 4149 |
3009 { | |
3010 switch (header.cputype) | |
3011 { | |
3012 case BFD_MACH_O_CPU_TYPE_I386: | |
3013 /* Handled by mach-o-i386 */ | |
3014 goto wrong; | |
3015 default: | |
3016 break; | |
3017 } | |
3018 } | |
3019 if (filetype) | 4150 if (filetype) |
3020 { | 4151 { |
3021 if (header.filetype != filetype) | 4152 if (header.filetype != filetype) |
3022 goto wrong; | 4153 goto wrong; |
3023 } | 4154 } |
3024 else | 4155 else |
3025 { | 4156 { |
3026 switch (header.filetype) | 4157 switch (header.filetype) |
3027 { | 4158 { |
3028 case BFD_MACH_O_MH_CORE: | 4159 case BFD_MACH_O_MH_CORE: |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3127 abfd->tdata.mach_o_fat_data = adata; | 4258 abfd->tdata.mach_o_fat_data = adata; |
3128 return abfd->xvec; | 4259 return abfd->xvec; |
3129 | 4260 |
3130 error: | 4261 error: |
3131 if (adata != NULL) | 4262 if (adata != NULL) |
3132 bfd_release (abfd, adata); | 4263 bfd_release (abfd, adata); |
3133 bfd_set_error (bfd_error_wrong_format); | 4264 bfd_set_error (bfd_error_wrong_format); |
3134 return NULL; | 4265 return NULL; |
3135 } | 4266 } |
3136 | 4267 |
| 4268 /* Set the filename for a fat binary member ABFD, whose bfd architecture is |
| 4269 ARCH_TYPE/ARCH_SUBTYPE and corresponding entry in header is ENTRY. |
| 4270 Set arelt_data and origin fields too. */ |
| 4271 |
| 4272 static void |
| 4273 bfd_mach_o_fat_member_init (bfd *abfd, |
| 4274 enum bfd_architecture arch_type, |
| 4275 unsigned long arch_subtype, |
| 4276 mach_o_fat_archentry *entry) |
| 4277 { |
| 4278 struct areltdata *areltdata; |
| 4279 /* Create the member filename. Use ARCH_NAME. */ |
| 4280 const bfd_arch_info_type *ap = bfd_lookup_arch (arch_type, arch_subtype); |
| 4281 |
| 4282 if (ap) |
| 4283 { |
| 4284 /* Use the architecture name if known. */ |
| 4285 abfd->filename = ap->printable_name; |
| 4286 } |
| 4287 else |
| 4288 { |
| 4289 /* Forge a uniq id. */ |
| 4290 const size_t namelen = 2 + 8 + 1 + 2 + 8 + 1; |
| 4291 char *name = bfd_alloc (abfd, namelen); |
| 4292 snprintf (name, namelen, "0x%lx-0x%lx", |
| 4293 entry->cputype, entry->cpusubtype); |
| 4294 abfd->filename = name; |
| 4295 } |
| 4296 |
| 4297 areltdata = bfd_zalloc (abfd, sizeof (struct areltdata)); |
| 4298 areltdata->parsed_size = entry->size; |
| 4299 abfd->arelt_data = areltdata; |
| 4300 abfd->iostream = NULL; |
| 4301 abfd->origin = entry->offset; |
| 4302 } |
| 4303 |
3137 bfd * | 4304 bfd * |
3138 bfd_mach_o_openr_next_archived_file (bfd *archive, bfd *prev) | 4305 bfd_mach_o_openr_next_archived_file (bfd *archive, bfd *prev) |
3139 { | 4306 { |
3140 mach_o_fat_data_struct *adata; | 4307 mach_o_fat_data_struct *adata; |
3141 mach_o_fat_archentry *entry = NULL; | 4308 mach_o_fat_archentry *entry = NULL; |
3142 unsigned long i; | 4309 unsigned long i; |
3143 bfd *nbfd; | 4310 bfd *nbfd; |
3144 enum bfd_architecture arch_type; | 4311 enum bfd_architecture arch_type; |
3145 unsigned long arch_subtype; | 4312 unsigned long arch_subtype; |
3146 | 4313 |
3147 adata = (mach_o_fat_data_struct *) archive->tdata.mach_o_fat_data; | 4314 adata = (mach_o_fat_data_struct *) archive->tdata.mach_o_fat_data; |
3148 BFD_ASSERT (adata != NULL); | 4315 BFD_ASSERT (adata != NULL); |
3149 | 4316 |
3150 /* Find index of previous entry. */ | 4317 /* Find index of previous entry. */ |
3151 if (prev == NULL) | 4318 if (prev == NULL) |
3152 i = 0;» /* Start at first one. */ | 4319 { |
| 4320 /* Start at first one. */ |
| 4321 i = 0; |
| 4322 } |
3153 else | 4323 else |
3154 { | 4324 { |
| 4325 /* Find index of PREV. */ |
3155 for (i = 0; i < adata->nfat_arch; i++) | 4326 for (i = 0; i < adata->nfat_arch; i++) |
3156 { | 4327 { |
3157 if (adata->archentries[i].offset == prev->origin) | 4328 if (adata->archentries[i].offset == prev->origin) |
3158 break; | 4329 break; |
3159 } | 4330 } |
3160 | 4331 |
3161 if (i == adata->nfat_arch) | 4332 if (i == adata->nfat_arch) |
3162 { | 4333 { |
3163 /* Not found. */ | 4334 /* Not found. */ |
3164 bfd_set_error (bfd_error_bad_value); | 4335 bfd_set_error (bfd_error_bad_value); |
3165 return NULL; | 4336 return NULL; |
3166 } | 4337 } |
3167 i++;» /* Get next entry. */ | 4338 |
3168 } | 4339 /* Get next entry. */ |
| 4340 i++; |
| 4341 } |
3169 | 4342 |
3170 if (i >= adata->nfat_arch) | 4343 if (i >= adata->nfat_arch) |
3171 { | 4344 { |
3172 bfd_set_error (bfd_error_no_more_archived_files); | 4345 bfd_set_error (bfd_error_no_more_archived_files); |
3173 return NULL; | 4346 return NULL; |
3174 } | 4347 } |
3175 | 4348 |
3176 entry = &adata->archentries[i]; | 4349 entry = &adata->archentries[i]; |
3177 nbfd = _bfd_new_bfd_contained_in (archive); | 4350 nbfd = _bfd_new_bfd_contained_in (archive); |
3178 if (nbfd == NULL) | 4351 if (nbfd == NULL) |
3179 return NULL; | 4352 return NULL; |
3180 | 4353 |
3181 nbfd->origin = entry->offset; | |
3182 | |
3183 bfd_mach_o_convert_architecture (entry->cputype, entry->cpusubtype, | 4354 bfd_mach_o_convert_architecture (entry->cputype, entry->cpusubtype, |
3184 &arch_type, &arch_subtype); | 4355 &arch_type, &arch_subtype); |
3185 | 4356 |
3186 /* Create the member filename. Use ARCH_NAME. */ | 4357 bfd_mach_o_fat_member_init (nbfd, arch_type, arch_subtype, entry); |
3187 nbfd->filename = bfd_printable_arch_mach (arch_type, arch_subtype); | 4358 |
3188 nbfd->iostream = NULL; | |
3189 bfd_set_arch_mach (nbfd, arch_type, arch_subtype); | 4359 bfd_set_arch_mach (nbfd, arch_type, arch_subtype); |
3190 | 4360 |
3191 return nbfd; | 4361 return nbfd; |
3192 } | 4362 } |
3193 | 4363 |
| 4364 /* Analogous to stat call. */ |
| 4365 |
| 4366 static int |
| 4367 bfd_mach_o_fat_stat_arch_elt (bfd *abfd, struct stat *buf) |
| 4368 { |
| 4369 if (abfd->arelt_data == NULL) |
| 4370 { |
| 4371 bfd_set_error (bfd_error_invalid_operation); |
| 4372 return -1; |
| 4373 } |
| 4374 |
| 4375 buf->st_mtime = 0; |
| 4376 buf->st_uid = 0; |
| 4377 buf->st_gid = 0; |
| 4378 buf->st_mode = 0644; |
| 4379 buf->st_size = arelt_size (abfd); |
| 4380 |
| 4381 return 0; |
| 4382 } |
| 4383 |
3194 /* If ABFD format is FORMAT and architecture is ARCH, return it. | 4384 /* If ABFD format is FORMAT and architecture is ARCH, return it. |
3195 If ABFD is a fat image containing a member that corresponds to FORMAT | 4385 If ABFD is a fat image containing a member that corresponds to FORMAT |
3196 and ARCH, returns it. | 4386 and ARCH, returns it. |
3197 In other case, returns NULL. | 4387 In other case, returns NULL. |
3198 This function allows transparent uses of fat images. */ | 4388 This function allows transparent uses of fat images. */ |
| 4389 |
3199 bfd * | 4390 bfd * |
3200 bfd_mach_o_fat_extract (bfd *abfd, | 4391 bfd_mach_o_fat_extract (bfd *abfd, |
3201 bfd_format format, | 4392 bfd_format format, |
3202 const bfd_arch_info_type *arch) | 4393 const bfd_arch_info_type *arch) |
3203 { | 4394 { |
3204 bfd *res; | 4395 bfd *res; |
3205 mach_o_fat_data_struct *adata; | 4396 mach_o_fat_data_struct *adata; |
3206 unsigned int i; | 4397 unsigned int i; |
3207 | 4398 |
3208 if (bfd_check_format (abfd, format)) | 4399 if (bfd_check_format (abfd, format)) |
(...skipping 19 matching lines...) Expand all Loading... |
3228 bfd_mach_o_convert_architecture (e->cputype, e->cpusubtype, | 4419 bfd_mach_o_convert_architecture (e->cputype, e->cpusubtype, |
3229 &cpu_type, &cpu_subtype); | 4420 &cpu_type, &cpu_subtype); |
3230 if (cpu_type != arch->arch || cpu_subtype != arch->mach) | 4421 if (cpu_type != arch->arch || cpu_subtype != arch->mach) |
3231 continue; | 4422 continue; |
3232 | 4423 |
3233 /* The architecture is found. */ | 4424 /* The architecture is found. */ |
3234 res = _bfd_new_bfd_contained_in (abfd); | 4425 res = _bfd_new_bfd_contained_in (abfd); |
3235 if (res == NULL) | 4426 if (res == NULL) |
3236 return NULL; | 4427 return NULL; |
3237 | 4428 |
3238 res->origin = e->offset; | 4429 bfd_mach_o_fat_member_init (res, cpu_type, cpu_subtype, e); |
3239 | |
3240 res->filename = bfd_printable_arch_mach (cpu_type, cpu_subtype); | |
3241 res->iostream = NULL; | |
3242 | 4430 |
3243 if (bfd_check_format (res, format)) | 4431 if (bfd_check_format (res, format)) |
3244 { | 4432 { |
3245 BFD_ASSERT (bfd_get_arch_info (res) == arch); | 4433 BFD_ASSERT (bfd_get_arch_info (res) == arch); |
3246 return res; | 4434 return res; |
3247 } | 4435 } |
3248 bfd_close (res); | 4436 bfd_close (res); |
3249 return NULL; | 4437 return NULL; |
3250 } | 4438 } |
3251 | 4439 |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3298 return 0xf0000000; | 4486 return 0xf0000000; |
3299 case BFD_MACH_O_CPU_TYPE_I860: | 4487 case BFD_MACH_O_CPU_TYPE_I860: |
3300 return 0; | 4488 return 0; |
3301 case BFD_MACH_O_CPU_TYPE_HPPA: | 4489 case BFD_MACH_O_CPU_TYPE_HPPA: |
3302 return 0xc0000000 - 0x04000000; | 4490 return 0xc0000000 - 0x04000000; |
3303 default: | 4491 default: |
3304 return 0; | 4492 return 0; |
3305 } | 4493 } |
3306 } | 4494 } |
3307 | 4495 |
| 4496 /* The following two tables should be kept, as far as possible, in order of |
| 4497 most frequently used entries to optimize their use from gas. */ |
| 4498 |
3308 const bfd_mach_o_xlat_name bfd_mach_o_section_type_name[] = | 4499 const bfd_mach_o_xlat_name bfd_mach_o_section_type_name[] = |
3309 { | 4500 { |
3310 { "regular", BFD_MACH_O_S_REGULAR}, | 4501 { "regular", BFD_MACH_O_S_REGULAR}, |
| 4502 { "coalesced", BFD_MACH_O_S_COALESCED}, |
3311 { "zerofill", BFD_MACH_O_S_ZEROFILL}, | 4503 { "zerofill", BFD_MACH_O_S_ZEROFILL}, |
3312 { "cstring_literals", BFD_MACH_O_S_CSTRING_LITERALS}, | 4504 { "cstring_literals", BFD_MACH_O_S_CSTRING_LITERALS}, |
3313 { "4byte_literals", BFD_MACH_O_S_4BYTE_LITERALS}, | 4505 { "4byte_literals", BFD_MACH_O_S_4BYTE_LITERALS}, |
3314 { "8byte_literals", BFD_MACH_O_S_8BYTE_LITERALS}, | 4506 { "8byte_literals", BFD_MACH_O_S_8BYTE_LITERALS}, |
| 4507 { "16byte_literals", BFD_MACH_O_S_16BYTE_LITERALS}, |
3315 { "literal_pointers", BFD_MACH_O_S_LITERAL_POINTERS}, | 4508 { "literal_pointers", BFD_MACH_O_S_LITERAL_POINTERS}, |
| 4509 { "mod_init_func_pointers", BFD_MACH_O_S_MOD_INIT_FUNC_POINTERS}, |
| 4510 { "mod_fini_func_pointers", BFD_MACH_O_S_MOD_FINI_FUNC_POINTERS}, |
| 4511 { "gb_zerofill", BFD_MACH_O_S_GB_ZEROFILL}, |
| 4512 { "interposing", BFD_MACH_O_S_INTERPOSING}, |
| 4513 { "dtrace_dof", BFD_MACH_O_S_DTRACE_DOF}, |
3316 { "non_lazy_symbol_pointers", BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS}, | 4514 { "non_lazy_symbol_pointers", BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS}, |
3317 { "lazy_symbol_pointers", BFD_MACH_O_S_LAZY_SYMBOL_POINTERS}, | 4515 { "lazy_symbol_pointers", BFD_MACH_O_S_LAZY_SYMBOL_POINTERS}, |
3318 { "symbol_stubs", BFD_MACH_O_S_SYMBOL_STUBS}, | 4516 { "symbol_stubs", BFD_MACH_O_S_SYMBOL_STUBS}, |
3319 { "mod_init_func_pointers", BFD_MACH_O_S_MOD_INIT_FUNC_POINTERS}, | |
3320 { "mod_fini_func_pointers", BFD_MACH_O_S_MOD_FINI_FUNC_POINTERS}, | |
3321 { "coalesced", BFD_MACH_O_S_COALESCED}, | |
3322 { "gb_zerofill", BFD_MACH_O_S_GB_ZEROFILL}, | |
3323 { "interposing", BFD_MACH_O_S_INTERPOSING}, | |
3324 { "16byte_literals", BFD_MACH_O_S_16BYTE_LITERALS}, | |
3325 { "dtrace_dof", BFD_MACH_O_S_DTRACE_DOF}, | |
3326 { "lazy_dylib_symbol_pointers", BFD_MACH_O_S_LAZY_DYLIB_SYMBOL_POINTERS}, | 4517 { "lazy_dylib_symbol_pointers", BFD_MACH_O_S_LAZY_DYLIB_SYMBOL_POINTERS}, |
3327 { NULL, 0} | 4518 { NULL, 0} |
3328 }; | 4519 }; |
3329 | 4520 |
3330 const bfd_mach_o_xlat_name bfd_mach_o_section_attribute_name[] = | 4521 const bfd_mach_o_xlat_name bfd_mach_o_section_attribute_name[] = |
3331 { | 4522 { |
| 4523 { "pure_instructions", BFD_MACH_O_S_ATTR_PURE_INSTRUCTIONS }, |
| 4524 { "some_instructions", BFD_MACH_O_S_ATTR_SOME_INSTRUCTIONS }, |
3332 { "loc_reloc", BFD_MACH_O_S_ATTR_LOC_RELOC }, | 4525 { "loc_reloc", BFD_MACH_O_S_ATTR_LOC_RELOC }, |
3333 { "ext_reloc", BFD_MACH_O_S_ATTR_EXT_RELOC }, | 4526 { "ext_reloc", BFD_MACH_O_S_ATTR_EXT_RELOC }, |
3334 { "some_instructions", BFD_MACH_O_S_ATTR_SOME_INSTRUCTIONS }, | |
3335 { "debug", BFD_MACH_O_S_ATTR_DEBUG }, | 4527 { "debug", BFD_MACH_O_S_ATTR_DEBUG }, |
3336 { "modifying_code", BFD_MACH_O_S_SELF_MODIFYING_CODE }, | |
3337 { "live_support", BFD_MACH_O_S_ATTR_LIVE_SUPPORT }, | 4528 { "live_support", BFD_MACH_O_S_ATTR_LIVE_SUPPORT }, |
3338 { "no_dead_strip", BFD_MACH_O_S_ATTR_NO_DEAD_STRIP }, | 4529 { "no_dead_strip", BFD_MACH_O_S_ATTR_NO_DEAD_STRIP }, |
3339 { "strip_static_syms", BFD_MACH_O_S_ATTR_STRIP_STATIC_SYMS }, | 4530 { "strip_static_syms", BFD_MACH_O_S_ATTR_STRIP_STATIC_SYMS }, |
3340 { "no_toc", BFD_MACH_O_S_ATTR_NO_TOC }, | 4531 { "no_toc", BFD_MACH_O_S_ATTR_NO_TOC }, |
3341 { "pure_instructions", BFD_MACH_O_S_ATTR_PURE_INSTRUCTIONS }, | 4532 { "self_modifying_code", BFD_MACH_O_S_SELF_MODIFYING_CODE }, |
| 4533 { "modifying_code", BFD_MACH_O_S_SELF_MODIFYING_CODE }, |
3342 { NULL, 0} | 4534 { NULL, 0} |
3343 }; | 4535 }; |
3344 | 4536 |
3345 /* Get the section type from NAME. Return -1 if NAME is unknown. */ | 4537 /* Get the section type from NAME. Return 256 if NAME is unknown. */ |
3346 | 4538 |
3347 unsigned int | 4539 unsigned int |
3348 bfd_mach_o_get_section_type_from_name (const char *name) | 4540 bfd_mach_o_get_section_type_from_name (bfd *abfd, const char *name) |
3349 { | 4541 { |
3350 const bfd_mach_o_xlat_name *x; | 4542 const bfd_mach_o_xlat_name *x; |
| 4543 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd); |
3351 | 4544 |
3352 for (x = bfd_mach_o_section_type_name; x->name; x++) | 4545 for (x = bfd_mach_o_section_type_name; x->name; x++) |
3353 if (strcmp (x->name, name) == 0) | 4546 if (strcmp (x->name, name) == 0) |
3354 return x->val; | 4547 { |
3355 return (unsigned int)-1; | 4548 » /* We found it... does the target support it? */ |
| 4549 » if (bed->bfd_mach_o_section_type_valid_for_target == NULL |
| 4550 » || bed->bfd_mach_o_section_type_valid_for_target (x->val)) |
| 4551 » return x->val; /* OK. */ |
| 4552 » else |
| 4553 » break; /* Not supported. */ |
| 4554 } |
| 4555 /* Maximum section ID = 0xff. */ |
| 4556 return 256; |
3356 } | 4557 } |
3357 | 4558 |
3358 /* Get the section attribute from NAME. Return -1 if NAME is unknown. */ | 4559 /* Get the section attribute from NAME. Return -1 if NAME is unknown. */ |
3359 | 4560 |
3360 unsigned int | 4561 unsigned int |
3361 bfd_mach_o_get_section_attribute_from_name (const char *name) | 4562 bfd_mach_o_get_section_attribute_from_name (const char *name) |
3362 { | 4563 { |
3363 const bfd_mach_o_xlat_name *x; | 4564 const bfd_mach_o_xlat_name *x; |
3364 | 4565 |
3365 for (x = bfd_mach_o_section_attribute_name; x->name; x++) | 4566 for (x = bfd_mach_o_section_attribute_name; x->name; x++) |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3473 | 4674 |
3474 return (char *) buf; | 4675 return (char *) buf; |
3475 } | 4676 } |
3476 | 4677 |
3477 int | 4678 int |
3478 bfd_mach_o_core_file_failing_signal (bfd *abfd ATTRIBUTE_UNUSED) | 4679 bfd_mach_o_core_file_failing_signal (bfd *abfd ATTRIBUTE_UNUSED) |
3479 { | 4680 { |
3480 return 0; | 4681 return 0; |
3481 } | 4682 } |
3482 | 4683 |
| 4684 static bfd_mach_o_uuid_command * |
| 4685 bfd_mach_o_lookup_uuid_command (bfd *abfd) |
| 4686 { |
| 4687 bfd_mach_o_load_command *uuid_cmd; |
| 4688 int ncmd = bfd_mach_o_lookup_command (abfd, BFD_MACH_O_LC_UUID, &uuid_cmd); |
| 4689 if (ncmd != 1) |
| 4690 return FALSE; |
| 4691 return &uuid_cmd->command.uuid; |
| 4692 } |
| 4693 |
| 4694 /* Return true if ABFD is a dSYM file and its UUID matches UUID_CMD. */ |
| 4695 |
| 4696 static bfd_boolean |
| 4697 bfd_mach_o_dsym_for_uuid_p (bfd *abfd, const bfd_mach_o_uuid_command *uuid_cmd) |
| 4698 { |
| 4699 bfd_mach_o_uuid_command *dsym_uuid_cmd; |
| 4700 |
| 4701 BFD_ASSERT (abfd); |
| 4702 BFD_ASSERT (uuid_cmd); |
| 4703 |
| 4704 if (!bfd_check_format (abfd, bfd_object)) |
| 4705 return FALSE; |
| 4706 |
| 4707 if (bfd_get_flavour (abfd) != bfd_target_mach_o_flavour |
| 4708 || bfd_mach_o_get_data (abfd) == NULL |
| 4709 || bfd_mach_o_get_data (abfd)->header.filetype != BFD_MACH_O_MH_DSYM) |
| 4710 return FALSE; |
| 4711 |
| 4712 dsym_uuid_cmd = bfd_mach_o_lookup_uuid_command (abfd); |
| 4713 if (dsym_uuid_cmd == NULL) |
| 4714 return FALSE; |
| 4715 |
| 4716 if (memcmp (uuid_cmd->uuid, dsym_uuid_cmd->uuid, |
| 4717 sizeof (uuid_cmd->uuid)) != 0) |
| 4718 return FALSE; |
| 4719 |
| 4720 return TRUE; |
| 4721 } |
| 4722 |
| 4723 /* Find a BFD in DSYM_FILENAME which matches ARCH and UUID_CMD. |
| 4724 The caller is responsible for closing the returned BFD object and |
| 4725 its my_archive if the returned BFD is in a fat dSYM. */ |
| 4726 |
| 4727 static bfd * |
| 4728 bfd_mach_o_find_dsym (const char *dsym_filename, |
| 4729 const bfd_mach_o_uuid_command *uuid_cmd, |
| 4730 const bfd_arch_info_type *arch) |
| 4731 { |
| 4732 bfd *base_dsym_bfd, *dsym_bfd; |
| 4733 |
| 4734 BFD_ASSERT (uuid_cmd); |
| 4735 |
| 4736 base_dsym_bfd = bfd_openr (dsym_filename, NULL); |
| 4737 if (base_dsym_bfd == NULL) |
| 4738 return NULL; |
| 4739 |
| 4740 dsym_bfd = bfd_mach_o_fat_extract (base_dsym_bfd, bfd_object, arch); |
| 4741 if (bfd_mach_o_dsym_for_uuid_p (dsym_bfd, uuid_cmd)) |
| 4742 return dsym_bfd; |
| 4743 |
| 4744 bfd_close (dsym_bfd); |
| 4745 if (base_dsym_bfd != dsym_bfd) |
| 4746 bfd_close (base_dsym_bfd); |
| 4747 |
| 4748 return NULL; |
| 4749 } |
| 4750 |
| 4751 /* Return a BFD created from a dSYM file for ABFD. |
| 4752 The caller is responsible for closing the returned BFD object, its |
| 4753 filename, and its my_archive if the returned BFD is in a fat dSYM. */ |
| 4754 |
| 4755 static bfd * |
| 4756 bfd_mach_o_follow_dsym (bfd *abfd) |
| 4757 { |
| 4758 char *dsym_filename; |
| 4759 bfd_mach_o_uuid_command *uuid_cmd; |
| 4760 bfd *dsym_bfd, *base_bfd = abfd; |
| 4761 const char *base_basename; |
| 4762 |
| 4763 if (abfd == NULL || bfd_get_flavour (abfd) != bfd_target_mach_o_flavour) |
| 4764 return NULL; |
| 4765 |
| 4766 if (abfd->my_archive) |
| 4767 base_bfd = abfd->my_archive; |
| 4768 /* BFD may have been opened from a stream. */ |
| 4769 if (base_bfd->filename == NULL) |
| 4770 { |
| 4771 bfd_set_error (bfd_error_invalid_operation); |
| 4772 return NULL; |
| 4773 } |
| 4774 base_basename = lbasename (base_bfd->filename); |
| 4775 |
| 4776 uuid_cmd = bfd_mach_o_lookup_uuid_command (abfd); |
| 4777 if (uuid_cmd == NULL) |
| 4778 return NULL; |
| 4779 |
| 4780 /* TODO: We assume the DWARF file has the same as the binary's. |
| 4781 It seems apple's GDB checks all files in the dSYM bundle directory. |
| 4782 http://opensource.apple.com/source/gdb/gdb-1708/src/gdb/macosx/macosx-tdep.
c |
| 4783 */ |
| 4784 dsym_filename = (char *)bfd_malloc (strlen (base_bfd->filename) |
| 4785 + strlen (dsym_subdir) + 1 |
| 4786 + strlen (base_basename) + 1); |
| 4787 sprintf (dsym_filename, "%s%s/%s", |
| 4788 base_bfd->filename, dsym_subdir, base_basename); |
| 4789 |
| 4790 dsym_bfd = bfd_mach_o_find_dsym (dsym_filename, uuid_cmd, |
| 4791 bfd_get_arch_info (abfd)); |
| 4792 if (dsym_bfd == NULL) |
| 4793 free (dsym_filename); |
| 4794 |
| 4795 return dsym_bfd; |
| 4796 } |
| 4797 |
| 4798 bfd_boolean |
| 4799 bfd_mach_o_find_nearest_line (bfd *abfd, |
| 4800 asection *section, |
| 4801 asymbol **symbols, |
| 4802 bfd_vma offset, |
| 4803 const char **filename_ptr, |
| 4804 const char **functionname_ptr, |
| 4805 unsigned int *line_ptr) |
| 4806 { |
| 4807 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd); |
| 4808 if (mdata == NULL) |
| 4809 return FALSE; |
| 4810 switch (mdata->header.filetype) |
| 4811 { |
| 4812 case BFD_MACH_O_MH_OBJECT: |
| 4813 break; |
| 4814 case BFD_MACH_O_MH_EXECUTE: |
| 4815 case BFD_MACH_O_MH_DYLIB: |
| 4816 case BFD_MACH_O_MH_BUNDLE: |
| 4817 case BFD_MACH_O_MH_KEXT_BUNDLE: |
| 4818 if (mdata->dwarf2_find_line_info == NULL) |
| 4819 { |
| 4820 mdata->dsym_bfd = bfd_mach_o_follow_dsym (abfd); |
| 4821 /* When we couldn't find dSYM for this binary, we look for |
| 4822 the debug information in the binary itself. In this way, |
| 4823 we won't try finding separated dSYM again because |
| 4824 mdata->dwarf2_find_line_info will be filled. */ |
| 4825 if (! mdata->dsym_bfd) |
| 4826 break; |
| 4827 if (! _bfd_dwarf2_slurp_debug_info (abfd, mdata->dsym_bfd, |
| 4828 dwarf_debug_sections, symbols, |
| 4829 &mdata->dwarf2_find_line_info)) |
| 4830 return FALSE; |
| 4831 } |
| 4832 break; |
| 4833 default: |
| 4834 return FALSE; |
| 4835 } |
| 4836 if (_bfd_dwarf2_find_nearest_line (abfd, dwarf_debug_sections, |
| 4837 section, symbols, offset, |
| 4838 filename_ptr, functionname_ptr, |
| 4839 line_ptr, 0, |
| 4840 &mdata->dwarf2_find_line_info)) |
| 4841 return TRUE; |
| 4842 return FALSE; |
| 4843 } |
| 4844 |
| 4845 bfd_boolean |
| 4846 bfd_mach_o_close_and_cleanup (bfd *abfd) |
| 4847 { |
| 4848 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd); |
| 4849 if (bfd_get_format (abfd) == bfd_object && mdata != NULL) |
| 4850 { |
| 4851 _bfd_dwarf2_cleanup_debug_info (abfd, &mdata->dwarf2_find_line_info); |
| 4852 bfd_mach_o_free_cached_info (abfd); |
| 4853 if (mdata->dsym_bfd != NULL) |
| 4854 { |
| 4855 bfd *fat_bfd = mdata->dsym_bfd->my_archive; |
| 4856 char *dsym_filename = (char *)(fat_bfd |
| 4857 ? fat_bfd->filename |
| 4858 : mdata->dsym_bfd->filename); |
| 4859 bfd_close (mdata->dsym_bfd); |
| 4860 mdata->dsym_bfd = NULL; |
| 4861 if (fat_bfd) |
| 4862 bfd_close (fat_bfd); |
| 4863 free (dsym_filename); |
| 4864 } |
| 4865 } |
| 4866 |
| 4867 return _bfd_generic_close_and_cleanup (abfd); |
| 4868 } |
| 4869 |
| 4870 bfd_boolean bfd_mach_o_free_cached_info (bfd *abfd) |
| 4871 { |
| 4872 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd); |
| 4873 asection *asect; |
| 4874 free (mdata->dyn_reloc_cache); |
| 4875 mdata->dyn_reloc_cache = NULL; |
| 4876 for (asect = abfd->sections; asect != NULL; asect = asect->next) |
| 4877 { |
| 4878 free (asect->relocation); |
| 4879 asect->relocation = NULL; |
| 4880 } |
| 4881 |
| 4882 return TRUE; |
| 4883 } |
| 4884 |
3483 #define bfd_mach_o_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup | 4885 #define bfd_mach_o_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup |
3484 #define bfd_mach_o_bfd_reloc_name_lookup _bfd_norelocs_bfd_reloc_name_lookup | 4886 #define bfd_mach_o_bfd_reloc_name_lookup _bfd_norelocs_bfd_reloc_name_lookup |
3485 | 4887 |
3486 #define bfd_mach_o_swap_reloc_in NULL | 4888 #define bfd_mach_o_swap_reloc_in NULL |
3487 #define bfd_mach_o_swap_reloc_out NULL | 4889 #define bfd_mach_o_swap_reloc_out NULL |
3488 #define bfd_mach_o_print_thread NULL | 4890 #define bfd_mach_o_print_thread NULL |
| 4891 #define bfd_mach_o_tgt_seg_table NULL |
| 4892 #define bfd_mach_o_section_type_valid_for_tgt NULL |
3489 | 4893 |
3490 #define TARGET_NAME mach_o_be_vec | 4894 #define TARGET_NAME mach_o_be_vec |
3491 #define TARGET_STRING "mach-o-be" | 4895 #define TARGET_STRING "mach-o-be" |
3492 #define TARGET_ARCHITECTURE bfd_arch_unknown | 4896 #define TARGET_ARCHITECTURE bfd_arch_unknown |
3493 #define TARGET_BIG_ENDIAN 1 | 4897 #define TARGET_BIG_ENDIAN 1 |
3494 #define TARGET_ARCHIVE 0 | 4898 #define TARGET_ARCHIVE 0 |
| 4899 #define TARGET_PRIORITY 1 |
3495 #include "mach-o-target.c" | 4900 #include "mach-o-target.c" |
3496 | 4901 |
3497 #undef TARGET_NAME | 4902 #undef TARGET_NAME |
3498 #undef TARGET_STRING | 4903 #undef TARGET_STRING |
3499 #undef TARGET_ARCHITECTURE | 4904 #undef TARGET_ARCHITECTURE |
3500 #undef TARGET_BIG_ENDIAN | 4905 #undef TARGET_BIG_ENDIAN |
3501 #undef TARGET_ARCHIVE | 4906 #undef TARGET_ARCHIVE |
| 4907 #undef TARGET_PRIORITY |
3502 | 4908 |
3503 #define TARGET_NAME mach_o_le_vec | 4909 #define TARGET_NAME mach_o_le_vec |
3504 #define TARGET_STRING "mach-o-le" | 4910 #define TARGET_STRING "mach-o-le" |
3505 #define TARGET_ARCHITECTURE bfd_arch_unknown | 4911 #define TARGET_ARCHITECTURE bfd_arch_unknown |
3506 #define TARGET_BIG_ENDIAN 0 | 4912 #define TARGET_BIG_ENDIAN 0 |
3507 #define TARGET_ARCHIVE 0 | 4913 #define TARGET_ARCHIVE 0 |
| 4914 #define TARGET_PRIORITY 1 |
3508 | 4915 |
3509 #include "mach-o-target.c" | 4916 #include "mach-o-target.c" |
3510 | 4917 |
3511 #undef TARGET_NAME | 4918 #undef TARGET_NAME |
3512 #undef TARGET_STRING | 4919 #undef TARGET_STRING |
3513 #undef TARGET_ARCHITECTURE | 4920 #undef TARGET_ARCHITECTURE |
3514 #undef TARGET_BIG_ENDIAN | 4921 #undef TARGET_BIG_ENDIAN |
3515 #undef TARGET_ARCHIVE | 4922 #undef TARGET_ARCHIVE |
| 4923 #undef TARGET_PRIORITY |
3516 | 4924 |
3517 /* Not yet handled: creating an archive. */ | 4925 /* Not yet handled: creating an archive. */ |
3518 #define bfd_mach_o_mkarchive _bfd_noarchive_mkarchive | 4926 #define bfd_mach_o_mkarchive _bfd_noarchive_mkarchive |
3519 | 4927 |
3520 /* Not used. */ | 4928 /* Not used. */ |
3521 #define bfd_mach_o_read_ar_hdr _bfd_noarchive_read_ar_hdr | 4929 #define bfd_mach_o_read_ar_hdr _bfd_noarchive_read_ar_hdr |
3522 #define bfd_mach_o_write_ar_hdr _bfd_noarchive_write_ar_hdr | 4930 #define bfd_mach_o_write_ar_hdr _bfd_noarchive_write_ar_hdr |
3523 #define bfd_mach_o_slurp_armap _bfd_noarchive_slurp_armap | 4931 #define bfd_mach_o_slurp_armap _bfd_noarchive_slurp_armap |
3524 #define bfd_mach_o_slurp_extended_name_table _bfd_noarchive_slurp_extended_
name_table | 4932 #define bfd_mach_o_slurp_extended_name_table _bfd_noarchive_slurp_extended_
name_table |
3525 #define bfd_mach_o_construct_extended_name_table _bfd_noarchive_construct_exten
ded_name_table | 4933 #define bfd_mach_o_construct_extended_name_table _bfd_noarchive_construct_exten
ded_name_table |
3526 #define bfd_mach_o_truncate_arname _bfd_noarchive_truncate_arname | 4934 #define bfd_mach_o_truncate_arname _bfd_noarchive_truncate_arname |
3527 #define bfd_mach_o_write_armap _bfd_noarchive_write_armap | 4935 #define bfd_mach_o_write_armap _bfd_noarchive_write_armap |
3528 #define bfd_mach_o_get_elt_at_index _bfd_noarchive_get_elt_at_inde
x | 4936 #define bfd_mach_o_get_elt_at_index _bfd_noarchive_get_elt_at_inde
x |
3529 #define bfd_mach_o_generic_stat_arch_elt _bfd_noarchive_generic_stat_ar
ch_elt | 4937 #define bfd_mach_o_generic_stat_arch_elt bfd_mach_o_fat_stat_arch_elt |
3530 #define bfd_mach_o_update_armap_timestamp _bfd_noarchive_update_armap_ti
mestamp | 4938 #define bfd_mach_o_update_armap_timestamp _bfd_noarchive_update_armap_ti
mestamp |
3531 | 4939 |
3532 #define TARGET_NAME mach_o_fat_vec | 4940 #define TARGET_NAME mach_o_fat_vec |
3533 #define TARGET_STRING "mach-o-fat" | 4941 #define TARGET_STRING "mach-o-fat" |
3534 #define TARGET_ARCHITECTURE bfd_arch_unknown | 4942 #define TARGET_ARCHITECTURE bfd_arch_unknown |
3535 #define TARGET_BIG_ENDIAN 1 | 4943 #define TARGET_BIG_ENDIAN 1 |
3536 #define TARGET_ARCHIVE 1 | 4944 #define TARGET_ARCHIVE 1 |
| 4945 #define TARGET_PRIORITY 0 |
3537 | 4946 |
3538 #include "mach-o-target.c" | 4947 #include "mach-o-target.c" |
3539 | 4948 |
3540 #undef TARGET_NAME | 4949 #undef TARGET_NAME |
3541 #undef TARGET_STRING | 4950 #undef TARGET_STRING |
3542 #undef TARGET_ARCHITECTURE | 4951 #undef TARGET_ARCHITECTURE |
3543 #undef TARGET_BIG_ENDIAN | 4952 #undef TARGET_BIG_ENDIAN |
3544 #undef TARGET_ARCHIVE | 4953 #undef TARGET_ARCHIVE |
| 4954 #undef TARGET_PRIORITY |
OLD | NEW |