Rev 5197 | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 5197 | Rev 6324 | ||
---|---|---|---|
Line 1... | Line 1... | ||
1 | /* Generic BFD library interface and support routines. |
1 | /* Generic BFD library interface and support routines. |
2 | Copyright 1990-2013 Free Software Foundation, Inc. |
2 | Copyright (C) 1990-2015 Free Software Foundation, Inc. |
3 | Written by Cygnus Support. |
3 | Written by Cygnus Support. |
Line 4... | Line 4... | ||
4 | 4 | ||
Line 5... | Line 5... | ||
5 | This file is part of BFD, the Binary File Descriptor library. |
5 | This file is part of BFD, the Binary File Descriptor library. |
Line 42... | Line 42... | ||
42 | . read_direction = 1, |
42 | . read_direction = 1, |
43 | . write_direction = 2, |
43 | . write_direction = 2, |
44 | . both_direction = 3 |
44 | . both_direction = 3 |
45 | . }; |
45 | . }; |
46 | . |
46 | . |
47 | .struct bfd |
47 | .enum bfd_plugin_format |
48 | .{ |
48 | . { |
49 | . {* A unique identifier of the BFD *} |
49 | . bfd_plugin_uknown = 0, |
- | 50 | . bfd_plugin_yes = 1, |
|
50 | . unsigned int id; |
51 | . bfd_plugin_no = 2 |
- | 52 | . }; |
|
51 | . |
53 | . |
- | 54 | .struct bfd_build_id |
|
- | 55 | . { |
|
- | 56 | . bfd_size_type size; |
|
- | 57 | . bfd_byte data[1]; |
|
- | 58 | . }; |
|
- | 59 | . |
|
- | 60 | .struct bfd |
|
- | 61 | .{ |
|
52 | . {* The filename the application opened the BFD with. *} |
62 | . {* The filename the application opened the BFD with. *} |
53 | . const char *filename; |
63 | . const char *filename; |
54 | . |
64 | . |
55 | . {* A pointer to the target jump table. *} |
65 | . {* A pointer to the target jump table. *} |
56 | . const struct bfd_target *xvec; |
66 | . const struct bfd_target *xvec; |
Line 69... | Line 79... | ||
69 | . ufile_ptr where; |
79 | . ufile_ptr where; |
70 | . |
80 | . |
71 | . {* File modified time, if mtime_set is TRUE. *} |
81 | . {* File modified time, if mtime_set is TRUE. *} |
72 | . long mtime; |
82 | . long mtime; |
73 | . |
83 | . |
74 | . {* Reserved for an unimplemented file locking extension. *} |
84 | . {* A unique identifier of the BFD *} |
75 | . int ifd; |
85 | . unsigned int id; |
76 | . |
86 | . |
77 | . {* The format which belongs to the BFD. (object, core, etc.) *} |
87 | . {* The format which belongs to the BFD. (object, core, etc.) *} |
78 | . bfd_format format; |
88 | . ENUM_BITFIELD (bfd_format) format : 3; |
79 | . |
89 | . |
80 | . {* The direction with which the BFD was opened. *} |
90 | . {* The direction with which the BFD was opened. *} |
81 | . enum bfd_direction direction; |
91 | . ENUM_BITFIELD (bfd_direction) direction : 2; |
82 | . |
92 | . |
83 | . {* Format_specific flags. *} |
93 | . {* Format_specific flags. *} |
84 | . flagword flags; |
94 | . flagword flags : 18; |
85 | . |
95 | . |
86 | . {* Values that may appear in the flags field of a BFD. These also |
96 | . {* Values that may appear in the flags field of a BFD. These also |
87 | . appear in the object_flags field of the bfd_target structure, where |
97 | . appear in the object_flags field of the bfd_target structure, where |
88 | . they indicate the set of flags used by that backend (not all flags |
98 | . they indicate the set of flags used by that backend (not all flags |
89 | . are meaningful for all object file formats) (FIXME: at the moment, |
99 | . are meaningful for all object file formats) (FIXME: at the moment, |
Line 138... | Line 148... | ||
138 | . {* This flag indicates that the BFD contents are actually cached |
148 | . {* This flag indicates that the BFD contents are actually cached |
139 | . in memory. If this is set, iostream points to a bfd_in_memory |
149 | . in memory. If this is set, iostream points to a bfd_in_memory |
140 | . struct. *} |
150 | . struct. *} |
141 | .#define BFD_IN_MEMORY 0x800 |
151 | .#define BFD_IN_MEMORY 0x800 |
142 | . |
152 | . |
143 | . {* The sections in this BFD specify a memory page. *} |
- | |
144 | .#define HAS_LOAD_PAGE 0x1000 |
- | |
145 | . |
- | |
146 | . {* This BFD has been created by the linker and doesn't correspond |
153 | . {* This BFD has been created by the linker and doesn't correspond |
147 | . to any input file. *} |
154 | . to any input file. *} |
148 | .#define BFD_LINKER_CREATED 0x2000 |
155 | .#define BFD_LINKER_CREATED 0x1000 |
149 | . |
156 | . |
150 | . {* This may be set before writing out a BFD to request that it |
157 | . {* This may be set before writing out a BFD to request that it |
151 | . be written using values for UIDs, GIDs, timestamps, etc. that |
158 | . be written using values for UIDs, GIDs, timestamps, etc. that |
152 | . will be consistent from run to run. *} |
159 | . will be consistent from run to run. *} |
153 | .#define BFD_DETERMINISTIC_OUTPUT 0x4000 |
160 | .#define BFD_DETERMINISTIC_OUTPUT 0x2000 |
154 | . |
161 | . |
155 | . {* Compress sections in this BFD. *} |
162 | . {* Compress sections in this BFD. *} |
156 | .#define BFD_COMPRESS 0x8000 |
163 | .#define BFD_COMPRESS 0x4000 |
157 | . |
164 | . |
158 | . {* Decompress sections in this BFD. *} |
165 | . {* Decompress sections in this BFD. *} |
159 | .#define BFD_DECOMPRESS 0x10000 |
166 | .#define BFD_DECOMPRESS 0x8000 |
160 | . |
167 | . |
161 | . {* BFD is a dummy, for plugins. *} |
168 | . {* BFD is a dummy, for plugins. *} |
162 | .#define BFD_PLUGIN 0x20000 |
169 | .#define BFD_PLUGIN 0x10000 |
- | 170 | . |
|
- | 171 | . {* Compress sections in this BFD with SHF_COMPRESSED from gABI. *} |
|
- | 172 | .#define BFD_COMPRESS_GABI 0x20000 |
|
163 | . |
173 | . |
164 | . {* Flags bits to be saved in bfd_preserve_save. *} |
174 | . {* Flags bits to be saved in bfd_preserve_save. *} |
165 | .#define BFD_FLAGS_SAVED \ |
175 | .#define BFD_FLAGS_SAVED \ |
166 | . (BFD_IN_MEMORY | BFD_COMPRESS | BFD_DECOMPRESS | BFD_PLUGIN) |
176 | . (BFD_IN_MEMORY | BFD_COMPRESS | BFD_DECOMPRESS | BFD_PLUGIN \ |
- | 177 | . | BFD_COMPRESS_GABI) |
|
167 | . |
178 | . |
168 | . {* Flags bits which are for BFD use only. *} |
179 | . {* Flags bits which are for BFD use only. *} |
169 | .#define BFD_FLAGS_FOR_BFD_USE_MASK \ |
180 | .#define BFD_FLAGS_FOR_BFD_USE_MASK \ |
170 | . (BFD_IN_MEMORY | BFD_COMPRESS | BFD_DECOMPRESS | BFD_LINKER_CREATED \ |
181 | . (BFD_IN_MEMORY | BFD_COMPRESS | BFD_DECOMPRESS | BFD_LINKER_CREATED \ |
171 | . | BFD_PLUGIN | BFD_TRADITIONAL_FORMAT | BFD_DETERMINISTIC_OUTPUT) |
182 | . | BFD_PLUGIN | BFD_TRADITIONAL_FORMAT | BFD_DETERMINISTIC_OUTPUT \ |
- | 183 | . | BFD_COMPRESS_GABI) |
|
- | 184 | . |
|
- | 185 | . {* Is the file descriptor being cached? That is, can it be closed as |
|
- | 186 | . needed, and re-opened when accessed later? *} |
|
- | 187 | . unsigned int cacheable : 1; |
|
- | 188 | . |
|
- | 189 | . {* Marks whether there was a default target specified when the |
|
- | 190 | . BFD was opened. This is used to select which matching algorithm |
|
- | 191 | . to use to choose the back end. *} |
|
- | 192 | . unsigned int target_defaulted : 1; |
|
- | 193 | . |
|
- | 194 | . {* ... and here: (``once'' means at least once). *} |
|
- | 195 | . unsigned int opened_once : 1; |
|
- | 196 | . |
|
- | 197 | . {* Set if we have a locally maintained mtime value, rather than |
|
- | 198 | . getting it from the file each time. *} |
|
- | 199 | . unsigned int mtime_set : 1; |
|
- | 200 | . |
|
- | 201 | . {* Flag set if symbols from this BFD should not be exported. *} |
|
- | 202 | . unsigned int no_export : 1; |
|
- | 203 | . |
|
- | 204 | . {* Remember when output has begun, to stop strange things |
|
- | 205 | . from happening. *} |
|
- | 206 | . unsigned int output_has_begun : 1; |
|
- | 207 | . |
|
- | 208 | . {* Have archive map. *} |
|
- | 209 | . unsigned int has_armap : 1; |
|
- | 210 | . |
|
- | 211 | . {* Set if this is a thin archive. *} |
|
- | 212 | . unsigned int is_thin_archive : 1; |
|
- | 213 | . |
|
- | 214 | . {* Set if only required symbols should be added in the link hash table for |
|
- | 215 | . this object. Used by VMS linkers. *} |
|
- | 216 | . unsigned int selective_search : 1; |
|
- | 217 | . |
|
- | 218 | . {* Set if this is the linker output BFD. *} |
|
- | 219 | . unsigned int is_linker_output : 1; |
|
- | 220 | . |
|
- | 221 | . {* Set if this is the linker input BFD. *} |
|
- | 222 | . unsigned int is_linker_input : 1; |
|
- | 223 | . |
|
- | 224 | . {* If this is an input for a compiler plug-in library. *} |
|
- | 225 | . ENUM_BITFIELD (bfd_plugin_format) plugin_format : 2; |
|
- | 226 | . |
|
- | 227 | . {* Set if this is a plugin output file. *} |
|
- | 228 | . unsigned int lto_output : 1; |
|
- | 229 | . |
|
- | 230 | . {* Set to dummy BFD created when claimed by a compiler plug-in |
|
- | 231 | . library. *} |
|
- | 232 | . bfd *plugin_dummy_bfd; |
|
172 | . |
233 | . |
173 | . {* Currently my_archive is tested before adding origin to |
234 | . {* Currently my_archive is tested before adding origin to |
174 | . anything. I believe that this can become always an add of |
235 | . anything. I believe that this can become always an add of |
175 | . origin, with origin set to 0 for non archive files. *} |
236 | . origin, with origin set to 0 for non archive files. *} |
176 | . ufile_ptr origin; |
237 | . ufile_ptr origin; |
Line 192... | Line 253... | ||
192 | . struct bfd_section *section_last; |
253 | . struct bfd_section *section_last; |
193 | . |
254 | . |
194 | . {* The number of sections. *} |
255 | . {* The number of sections. *} |
195 | . unsigned int section_count; |
256 | . unsigned int section_count; |
196 | . |
257 | . |
- | 258 | . {* A field used by _bfd_generic_link_add_archive_symbols. This will |
|
- | 259 | . be used only for archive elements. *} |
|
- | 260 | . int archive_pass; |
|
- | 261 | . |
|
197 | . {* Stuff only useful for object files: |
262 | . {* Stuff only useful for object files: |
198 | . The start address. *} |
263 | . The start address. *} |
199 | . bfd_vma start_address; |
264 | . bfd_vma start_address; |
200 | . |
265 | . |
201 | . {* Used for input and output. *} |
- | |
202 | . unsigned int symcount; |
- | |
203 | . |
- | |
204 | . {* Symbol table for output BFD (with symcount entries). |
266 | . {* Symbol table for output BFD (with symcount entries). |
205 | . Also used by the linker to cache input BFD symbols. *} |
267 | . Also used by the linker to cache input BFD symbols. *} |
206 | . struct bfd_symbol **outsymbols; |
268 | . struct bfd_symbol **outsymbols; |
207 | . |
269 | . |
- | 270 | . {* Used for input and output. *} |
|
- | 271 | . unsigned int symcount; |
|
- | 272 | . |
|
208 | . {* Used for slurped dynamic symbol tables. *} |
273 | . {* Used for slurped dynamic symbol tables. *} |
209 | . unsigned int dynsymcount; |
274 | . unsigned int dynsymcount; |
210 | . |
275 | . |
211 | . {* Pointer to structure which contains architecture information. *} |
276 | . {* Pointer to structure which contains architecture information. *} |
212 | . const struct bfd_arch_info *arch_info; |
277 | . const struct bfd_arch_info *arch_info; |
Line 217... | Line 282... | ||
217 | . struct bfd *archive_next; {* The next BFD in the archive. *} |
282 | . struct bfd *archive_next; {* The next BFD in the archive. *} |
218 | . struct bfd *archive_head; {* The first BFD in the archive. *} |
283 | . struct bfd *archive_head; {* The first BFD in the archive. *} |
219 | . struct bfd *nested_archives; {* List of nested archive in a flattened |
284 | . struct bfd *nested_archives; {* List of nested archive in a flattened |
220 | . thin archive. *} |
285 | . thin archive. *} |
221 | . |
286 | . |
- | 287 | . union { |
|
222 | . {* A chain of BFD structures involved in a link. *} |
288 | . {* For input BFDs, a chain of BFDs involved in a link. *} |
223 | . struct bfd *link_next; |
289 | . struct bfd *next; |
224 | . |
- | |
225 | . {* A field used by _bfd_generic_link_add_archive_symbols. This will |
290 | . {* For output BFD, the linker hash table. *} |
226 | . be used only for archive elements. *} |
291 | . struct bfd_link_hash_table *hash; |
227 | . int archive_pass; |
292 | . } link; |
228 | . |
293 | . |
229 | . {* Used by the back end to hold private data. *} |
294 | . {* Used by the back end to hold private data. *} |
230 | . union |
295 | . union |
231 | . { |
296 | . { |
232 | . struct aout_data_struct *aout_data; |
297 | . struct aout_data_struct *aout_data; |
Line 275... | Line 340... | ||
275 | . {* Where all the allocated stuff under this BFD goes. This is a |
340 | . {* Where all the allocated stuff under this BFD goes. This is a |
276 | . struct objalloc *, but we use void * to avoid requiring the inclusion |
341 | . struct objalloc *, but we use void * to avoid requiring the inclusion |
277 | . of objalloc.h. *} |
342 | . of objalloc.h. *} |
278 | . void *memory; |
343 | . void *memory; |
279 | . |
344 | . |
280 | . {* Is the file descriptor being cached? That is, can it be closed as |
- | |
281 | . needed, and re-opened when accessed later? *} |
- | |
282 | . unsigned int cacheable : 1; |
- | |
283 | . |
- | |
284 | . {* Marks whether there was a default target specified when the |
- | |
285 | . BFD was opened. This is used to select which matching algorithm |
- | |
286 | . to use to choose the back end. *} |
- | |
287 | . unsigned int target_defaulted : 1; |
- | |
288 | . |
- | |
289 | . {* ... and here: (``once'' means at least once). *} |
345 | . {* For input BFDs, the build ID, if the object has one. *} |
290 | . unsigned int opened_once : 1; |
- | |
291 | . |
- | |
292 | . {* Set if we have a locally maintained mtime value, rather than |
- | |
293 | . getting it from the file each time. *} |
- | |
294 | . unsigned int mtime_set : 1; |
- | |
295 | . |
- | |
296 | . {* Flag set if symbols from this BFD should not be exported. *} |
- | |
297 | . unsigned int no_export : 1; |
- | |
298 | . |
- | |
299 | . {* Remember when output has begun, to stop strange things |
- | |
300 | . from happening. *} |
- | |
301 | . unsigned int output_has_begun : 1; |
- | |
302 | . |
- | |
303 | . {* Have archive map. *} |
- | |
304 | . unsigned int has_armap : 1; |
- | |
305 | . |
- | |
306 | . {* Set if this is a thin archive. *} |
- | |
307 | . unsigned int is_thin_archive : 1; |
346 | . const struct bfd_build_id *build_id; |
308 | . |
- | |
309 | . {* Set if only required symbols should be added in the link hash table for |
- | |
310 | . this object. Used by VMS linkers. *} |
- | |
311 | . unsigned int selective_search : 1; |
- | |
312 | .}; |
347 | .}; |
313 | . |
348 | . |
- | 349 | .{* See note beside bfd_set_section_userdata. *} |
|
- | 350 | .static inline bfd_boolean |
|
- | 351 | .bfd_set_cacheable (bfd * abfd, bfd_boolean val) |
|
- | 352 | .{ |
|
- | 353 | . abfd->cacheable = val; |
|
- | 354 | . return TRUE; |
|
- | 355 | .} |
|
- | 356 | . |
|
314 | */ |
357 | */ |
Line 315... | Line 358... | ||
315 | 358 | ||
316 | #include "sysdep.h" |
359 | #include "sysdep.h" |
317 | #include |
360 | #include |
Line 1045... | Line 1088... | ||
1045 | void |
1088 | void |
1046 | _bfd_abort (const char *file, int line, const char *fn) |
1089 | _bfd_abort (const char *file, int line, const char *fn) |
1047 | { |
1090 | { |
1048 | if (fn != NULL) |
1091 | if (fn != NULL) |
1049 | (*_bfd_error_handler) |
1092 | (*_bfd_error_handler) |
1050 | (_("BFD %s internal error, aborting at %s line %d in %s\n"), |
1093 | (_("BFD %s internal error, aborting at %s:%d in %s\n"), |
1051 | BFD_VERSION_STRING, file, line, fn); |
1094 | BFD_VERSION_STRING, file, line, fn); |
1052 | else |
1095 | else |
1053 | (*_bfd_error_handler) |
1096 | (*_bfd_error_handler) |
1054 | (_("BFD %s internal error, aborting at %s line %d\n"), |
1097 | (_("BFD %s internal error, aborting at %s:%d\n"), |
1055 | BFD_VERSION_STRING, file, line); |
1098 | BFD_VERSION_STRING, file, line); |
1056 | (*_bfd_error_handler) (_("Please report this bug.\n")); |
1099 | (*_bfd_error_handler) (_("Please report this bug.\n")); |
1057 | _exit (EXIT_FAILURE); |
1100 | _exit (EXIT_FAILURE); |
1058 | } |
1101 | } |
Line 1063... | Line 1106... | ||
1063 | 1106 | ||
1064 | SYNOPSIS |
1107 | SYNOPSIS |
Line 1065... | Line 1108... | ||
1065 | int bfd_get_arch_size (bfd *abfd); |
1108 | int bfd_get_arch_size (bfd *abfd); |
1066 | 1109 | ||
1067 | DESCRIPTION |
1110 | DESCRIPTION |
- | 1111 | Returns the normalized architecture address size, in bits, as |
|
- | 1112 | determined by the object file's format. By normalized, we mean |
|
1068 | Returns the architecture address size, in bits, as determined |
1113 | either 32 or 64. For ELF, this information is included in the |
Line 1069... | Line 1114... | ||
1069 | by the object file's format. For ELF, this information is |
1114 | header. Use bfd_arch_bits_per_address for number of bits in |
1070 | included in the header. |
1115 | the architecture address. |
1071 | 1116 | ||
Line 1077... | Line 1122... | ||
1077 | bfd_get_arch_size (bfd *abfd) |
1122 | bfd_get_arch_size (bfd *abfd) |
1078 | { |
1123 | { |
1079 | if (abfd->xvec->flavour == bfd_target_elf_flavour) |
1124 | if (abfd->xvec->flavour == bfd_target_elf_flavour) |
1080 | return get_elf_backend_data (abfd)->s->arch_size; |
1125 | return get_elf_backend_data (abfd)->s->arch_size; |
Line 1081... | Line 1126... | ||
1081 | 1126 | ||
1082 | return -1; |
1127 | return bfd_arch_bits_per_address (abfd) > 32 ? 64 : 32; |
Line 1083... | Line 1128... | ||
1083 | } |
1128 | } |
1084 | 1129 | ||
1085 | /* |
1130 | /* |
Line 1431... | Line 1476... | ||
1431 | .#define bfd_sizeof_headers(abfd, info) \ |
1476 | .#define bfd_sizeof_headers(abfd, info) \ |
1432 | . BFD_SEND (abfd, _bfd_sizeof_headers, (abfd, info)) |
1477 | . BFD_SEND (abfd, _bfd_sizeof_headers, (abfd, info)) |
1433 | . |
1478 | . |
1434 | .#define bfd_find_nearest_line(abfd, sec, syms, off, file, func, line) \ |
1479 | .#define bfd_find_nearest_line(abfd, sec, syms, off, file, func, line) \ |
1435 | . BFD_SEND (abfd, _bfd_find_nearest_line, \ |
1480 | . BFD_SEND (abfd, _bfd_find_nearest_line, \ |
1436 | . (abfd, sec, syms, off, file, func, line)) |
1481 | . (abfd, syms, sec, off, file, func, line, NULL)) |
1437 | . |
1482 | . |
1438 | .#define bfd_find_nearest_line_discriminator(abfd, sec, syms, off, file, func, \ |
1483 | .#define bfd_find_nearest_line_discriminator(abfd, sec, syms, off, file, func, \ |
1439 | . line, disc) \ |
1484 | . line, disc) \ |
1440 | . BFD_SEND (abfd, _bfd_find_nearest_line_discriminator, \ |
1485 | . BFD_SEND (abfd, _bfd_find_nearest_line, \ |
1441 | . (abfd, sec, syms, off, file, func, line, disc)) |
1486 | . (abfd, syms, sec, off, file, func, line, disc)) |
1442 | . |
1487 | . |
1443 | .#define bfd_find_line(abfd, syms, sym, file, line) \ |
1488 | .#define bfd_find_line(abfd, syms, sym, file, line) \ |
1444 | . BFD_SEND (abfd, _bfd_find_line, \ |
1489 | . BFD_SEND (abfd, _bfd_find_line, \ |
1445 | . (abfd, syms, sym, file, line)) |
1490 | . (abfd, syms, sym, file, line)) |
1446 | . |
1491 | . |
Line 1485... | Line 1530... | ||
1485 | . BFD_SEND (abfd, _bfd_discard_group, (abfd, sec)) |
1530 | . BFD_SEND (abfd, _bfd_discard_group, (abfd, sec)) |
1486 | . |
1531 | . |
1487 | .#define bfd_link_hash_table_create(abfd) \ |
1532 | .#define bfd_link_hash_table_create(abfd) \ |
1488 | . BFD_SEND (abfd, _bfd_link_hash_table_create, (abfd)) |
1533 | . BFD_SEND (abfd, _bfd_link_hash_table_create, (abfd)) |
1489 | . |
1534 | . |
1490 | .#define bfd_link_hash_table_free(abfd, hash) \ |
- | |
1491 | . BFD_SEND (abfd, _bfd_link_hash_table_free, (hash)) |
- | |
1492 | . |
- | |
1493 | .#define bfd_link_add_symbols(abfd, info) \ |
1535 | .#define bfd_link_add_symbols(abfd, info) \ |
1494 | . BFD_SEND (abfd, _bfd_link_add_symbols, (abfd, info)) |
1536 | . BFD_SEND (abfd, _bfd_link_add_symbols, (abfd, info)) |
1495 | . |
1537 | . |
1496 | .#define bfd_link_just_syms(abfd, sec, info) \ |
1538 | .#define bfd_link_just_syms(abfd, sec, info) \ |
1497 | . BFD_SEND (abfd, _bfd_link_just_syms, (sec, info)) |
1539 | . BFD_SEND (abfd, _bfd_link_just_syms, (sec, info)) |
Line 1913... | Line 1955... | ||
1913 | res = final; |
1955 | res = final; |
1914 | } |
1956 | } |
Line 1915... | Line 1957... | ||
1915 | 1957 | ||
1916 | return res; |
1958 | return res; |
- | 1959 | } |
|
- | 1960 | ||
- | 1961 | /* |
|
- | 1962 | FUNCTION |
|
- | 1963 | bfd_update_compression_header |
|
- | 1964 | ||
- | 1965 | SYNOPSIS |
|
- | 1966 | void bfd_update_compression_header |
|
- | 1967 | (bfd *abfd, bfd_byte *contents, asection *sec); |
|
- | 1968 | ||
- | 1969 | DESCRIPTION |
|
- | 1970 | Set the compression header at CONTENTS of SEC in ABFD and update |
|
- | 1971 | elf_section_flags for compression. |
|
- | 1972 | */ |
|
- | 1973 | ||
- | 1974 | void |
|
- | 1975 | bfd_update_compression_header (bfd *abfd, bfd_byte *contents, |
|
- | 1976 | asection *sec) |
|
- | 1977 | { |
|
- | 1978 | if ((abfd->flags & BFD_COMPRESS) != 0) |
|
- | 1979 | { |
|
- | 1980 | if (bfd_get_flavour (abfd) == bfd_target_elf_flavour) |
|
- | 1981 | { |
|
- | 1982 | if ((abfd->flags & BFD_COMPRESS_GABI) != 0) |
|
- | 1983 | { |
|
- | 1984 | const struct elf_backend_data *bed |
|
- | 1985 | = get_elf_backend_data (abfd); |
|
- | 1986 | ||
- | 1987 | /* Set the SHF_COMPRESSED bit. */ |
|
- | 1988 | elf_section_flags (sec) |= SHF_COMPRESSED; |
|
- | 1989 | ||
- | 1990 | if (bed->s->elfclass == ELFCLASS32) |
|
- | 1991 | { |
|
- | 1992 | Elf32_External_Chdr *echdr |
|
- | 1993 | = (Elf32_External_Chdr *) contents; |
|
- | 1994 | bfd_put_32 (abfd, ELFCOMPRESS_ZLIB, &echdr->ch_type); |
|
- | 1995 | bfd_put_32 (abfd, sec->size, &echdr->ch_size); |
|
- | 1996 | bfd_put_32 (abfd, 1 << sec->alignment_power, |
|
- | 1997 | &echdr->ch_addralign); |
|
- | 1998 | } |
|
- | 1999 | else |
|
- | 2000 | { |
|
- | 2001 | Elf64_External_Chdr *echdr |
|
- | 2002 | = (Elf64_External_Chdr *) contents; |
|
- | 2003 | bfd_put_32 (abfd, ELFCOMPRESS_ZLIB, &echdr->ch_type); |
|
- | 2004 | bfd_put_32 (abfd, 0, &echdr->ch_reserved); |
|
- | 2005 | bfd_put_64 (abfd, sec->size, &echdr->ch_size); |
|
- | 2006 | bfd_put_64 (abfd, 1 << sec->alignment_power, |
|
- | 2007 | &echdr->ch_addralign); |
|
- | 2008 | } |
|
- | 2009 | } |
|
- | 2010 | else |
|
- | 2011 | { |
|
- | 2012 | /* Clear the SHF_COMPRESSED bit. */ |
|
- | 2013 | elf_section_flags (sec) &= ~SHF_COMPRESSED; |
|
- | 2014 | ||
- | 2015 | /* Write the zlib header. It should be "ZLIB" followed by |
|
- | 2016 | the uncompressed section size, 8 bytes in big-endian |
|
- | 2017 | order. */ |
|
- | 2018 | memcpy (contents, "ZLIB", 4); |
|
- | 2019 | bfd_putb64 (sec->size, contents + 4); |
|
- | 2020 | } |
|
- | 2021 | } |
|
- | 2022 | } |
|
- | 2023 | else |
|
- | 2024 | abort (); |
|
- | 2025 | } |
|
- | 2026 | ||
- | 2027 | /* |
|
- | 2028 | FUNCTION |
|
- | 2029 | bfd_check_compression_header |
|
- | 2030 | ||
- | 2031 | SYNOPSIS |
|
- | 2032 | bfd_boolean bfd_check_compression_header |
|
- | 2033 | (bfd *abfd, bfd_byte *contents, asection *sec, |
|
- | 2034 | bfd_size_type *uncompressed_size); |
|
- | 2035 | ||
- | 2036 | DESCRIPTION |
|
- | 2037 | Check the compression header at CONTENTS of SEC in ABFD and |
|
- | 2038 | store the uncompressed size in UNCOMPRESSED_SIZE if the |
|
- | 2039 | compression header is valid. |
|
- | 2040 | ||
- | 2041 | RETURNS |
|
- | 2042 | Return TRUE if the compression header is valid. |
|
- | 2043 | */ |
|
- | 2044 | ||
- | 2045 | bfd_boolean |
|
- | 2046 | bfd_check_compression_header (bfd *abfd, bfd_byte *contents, |
|
- | 2047 | asection *sec, |
|
- | 2048 | bfd_size_type *uncompressed_size) |
|
- | 2049 | { |
|
- | 2050 | if (bfd_get_flavour (abfd) == bfd_target_elf_flavour |
|
- | 2051 | && (elf_section_flags (sec) & SHF_COMPRESSED) != 0) |
|
- | 2052 | { |
|
- | 2053 | Elf_Internal_Chdr chdr; |
|
- | 2054 | const struct elf_backend_data *bed = get_elf_backend_data (abfd); |
|
- | 2055 | if (bed->s->elfclass == ELFCLASS32) |
|
- | 2056 | { |
|
- | 2057 | Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) contents; |
|
- | 2058 | chdr.ch_type = bfd_get_32 (abfd, &echdr->ch_type); |
|
- | 2059 | chdr.ch_size = bfd_get_32 (abfd, &echdr->ch_size); |
|
- | 2060 | chdr.ch_addralign = bfd_get_32 (abfd, &echdr->ch_addralign); |
|
- | 2061 | } |
|
- | 2062 | else |
|
- | 2063 | { |
|
- | 2064 | Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) contents; |
|
- | 2065 | chdr.ch_type = bfd_get_32 (abfd, &echdr->ch_type); |
|
- | 2066 | chdr.ch_size = bfd_get_64 (abfd, &echdr->ch_size); |
|
- | 2067 | chdr.ch_addralign = bfd_get_64 (abfd, &echdr->ch_addralign); |
|
- | 2068 | } |
|
- | 2069 | if (chdr.ch_type == ELFCOMPRESS_ZLIB |
|
- | 2070 | && chdr.ch_addralign == 1U << sec->alignment_power) |
|
- | 2071 | { |
|
- | 2072 | *uncompressed_size = chdr.ch_size; |
|
- | 2073 | return TRUE; |
|
- | 2074 | } |
|
- | 2075 | } |
|
- | 2076 | ||
- | 2077 | return FALSE; |
|
- | 2078 | } |
|
- | 2079 | ||
- | 2080 | /* |
|
- | 2081 | FUNCTION |
|
- | 2082 | bfd_get_compression_header_size |
|
- | 2083 | ||
- | 2084 | SYNOPSIS |
|
- | 2085 | int bfd_get_compression_header_size (bfd *abfd, asection *sec); |
|
- | 2086 | ||
- | 2087 | DESCRIPTION |
|
- | 2088 | Return the size of the compression header of SEC in ABFD. |
|
- | 2089 | ||
- | 2090 | RETURNS |
|
- | 2091 | Return the size of the compression header in bytes. |
|
- | 2092 | */ |
|
- | 2093 | ||
- | 2094 | int |
|
- | 2095 | bfd_get_compression_header_size (bfd *abfd, asection *sec) |
|
- | 2096 | { |
|
- | 2097 | if (bfd_get_flavour (abfd) == bfd_target_elf_flavour) |
|
- | 2098 | { |
|
- | 2099 | if (sec == NULL) |
|
- | 2100 | { |
|
- | 2101 | if (!(abfd->flags & BFD_COMPRESS_GABI)) |
|
- | 2102 | return 0; |
|
- | 2103 | } |
|
- | 2104 | else if (!(elf_section_flags (sec) & SHF_COMPRESSED)) |
|
- | 2105 | return 0; |
|
- | 2106 | ||
- | 2107 | if (get_elf_backend_data (abfd)->s->elfclass == ELFCLASS32) |
|
- | 2108 | return sizeof (Elf32_External_Chdr); |
|
- | 2109 | else |
|
- | 2110 | return sizeof (Elf64_External_Chdr); |
|
- | 2111 | } |
|
- | 2112 | ||
- | 2113 | return 0; |
|
- | 2114 | } |
|
- | 2115 | ||
- | 2116 | /* |
|
- | 2117 | FUNCTION |
|
- | 2118 | bfd_convert_section_size |
|
- | 2119 | ||
- | 2120 | SYNOPSIS |
|
- | 2121 | bfd_size_type bfd_convert_section_size |
|
- | 2122 | (bfd *ibfd, asection *isec, bfd *obfd, bfd_size_type size); |
|
- | 2123 | ||
- | 2124 | DESCRIPTION |
|
- | 2125 | Convert the size @var{size} of the section @var{isec} in input |
|
- | 2126 | BFD @var{ibfd} to the section size in output BFD @var{obfd}. |
|
- | 2127 | */ |
|
- | 2128 | ||
- | 2129 | bfd_size_type |
|
- | 2130 | bfd_convert_section_size (bfd *ibfd, sec_ptr isec, bfd *obfd, |
|
- | 2131 | bfd_size_type size) |
|
- | 2132 | { |
|
- | 2133 | bfd_size_type hdr_size; |
|
- | 2134 | ||
- | 2135 | /* Do nothing if input file will be decompressed. */ |
|
- | 2136 | if ((ibfd->flags & BFD_DECOMPRESS)) |
|
- | 2137 | return size; |
|
- | 2138 | ||
- | 2139 | /* Do nothing if either input or output aren't ELF. */ |
|
- | 2140 | if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour |
|
- | 2141 | || bfd_get_flavour (obfd) != bfd_target_elf_flavour) |
|
- | 2142 | return size; |
|
- | 2143 | ||
- | 2144 | /* Do nothing if ELF classes of input and output are the same. */ |
|
- | 2145 | if (get_elf_backend_data (ibfd)->s->elfclass |
|
- | 2146 | == get_elf_backend_data (obfd)->s->elfclass) |
|
- | 2147 | return size; |
|
- | 2148 | ||
- | 2149 | /* Do nothing if the input section isn't a SHF_COMPRESSED section. */ |
|
- | 2150 | hdr_size = bfd_get_compression_header_size (ibfd, isec); |
|
- | 2151 | if (hdr_size == 0) |
|
- | 2152 | return size; |
|
- | 2153 | ||
- | 2154 | /* Adjust the size of the output SHF_COMPRESSED section. */ |
|
- | 2155 | if (hdr_size == sizeof (Elf32_External_Chdr)) |
|
- | 2156 | return (size - sizeof (Elf32_External_Chdr) |
|
- | 2157 | + sizeof (Elf64_External_Chdr)); |
|
- | 2158 | else |
|
- | 2159 | return (size - sizeof (Elf64_External_Chdr) |
|
- | 2160 | + sizeof (Elf32_External_Chdr)); |
|
- | 2161 | } |
|
- | 2162 | ||
- | 2163 | /* |
|
- | 2164 | FUNCTION |
|
- | 2165 | bfd_convert_section_contents |
|
- | 2166 | ||
- | 2167 | SYNOPSIS |
|
- | 2168 | bfd_boolean bfd_convert_section_contents |
|
- | 2169 | (bfd *ibfd, asection *isec, bfd *obfd, |
|
- | 2170 | bfd_byte **ptr, bfd_size_type *ptr_size); |
|
- | 2171 | ||
- | 2172 | DESCRIPTION |
|
- | 2173 | Convert the contents, stored in @var{*ptr}, of the section |
|
- | 2174 | @var{isec} in input BFD @var{ibfd} to output BFD @var{obfd} |
|
- | 2175 | if needed. The original buffer pointed to by @var{*ptr} may |
|
- | 2176 | be freed and @var{*ptr} is returned with memory malloc'd by this |
|
- | 2177 | function, and the new size written to @var{ptr_size}. |
|
- | 2178 | */ |
|
- | 2179 | ||
- | 2180 | bfd_boolean |
|
- | 2181 | bfd_convert_section_contents (bfd *ibfd, sec_ptr isec, bfd *obfd, |
|
- | 2182 | bfd_byte **ptr, bfd_size_type *ptr_size) |
|
- | 2183 | { |
|
- | 2184 | bfd_byte *contents; |
|
- | 2185 | bfd_size_type ihdr_size, ohdr_size, size; |
|
- | 2186 | Elf_Internal_Chdr chdr; |
|
- | 2187 | bfd_boolean use_memmove; |
|
- | 2188 | ||
- | 2189 | /* Do nothing if input file will be decompressed. */ |
|
- | 2190 | if ((ibfd->flags & BFD_DECOMPRESS)) |
|
- | 2191 | return TRUE; |
|
- | 2192 | ||
- | 2193 | /* Do nothing if either input or output aren't ELF. */ |
|
- | 2194 | if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour |
|
- | 2195 | || bfd_get_flavour (obfd) != bfd_target_elf_flavour) |
|
- | 2196 | return TRUE; |
|
- | 2197 | ||
- | 2198 | /* Do nothing if ELF classes of input and output are the same. */ |
|
- | 2199 | if (get_elf_backend_data (ibfd)->s->elfclass |
|
- | 2200 | == get_elf_backend_data (obfd)->s->elfclass) |
|
- | 2201 | return TRUE; |
|
- | 2202 | ||
- | 2203 | /* Do nothing if the input section isn't a SHF_COMPRESSED section. */ |
|
- | 2204 | ihdr_size = bfd_get_compression_header_size (ibfd, isec); |
|
- | 2205 | if (ihdr_size == 0) |
|
- | 2206 | return TRUE; |
|
- | 2207 | ||
- | 2208 | contents = *ptr; |
|
- | 2209 | ||
- | 2210 | /* Convert the contents of the input SHF_COMPRESSED section to |
|
- | 2211 | output. Get the input compression header and the size of the |
|
- | 2212 | output compression header. */ |
|
- | 2213 | if (ihdr_size == sizeof (Elf32_External_Chdr)) |
|
- | 2214 | { |
|
- | 2215 | Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) contents; |
|
- | 2216 | chdr.ch_type = bfd_get_32 (ibfd, &echdr->ch_type); |
|
- | 2217 | chdr.ch_size = bfd_get_32 (ibfd, &echdr->ch_size); |
|
- | 2218 | chdr.ch_addralign = bfd_get_32 (ibfd, &echdr->ch_addralign); |
|
- | 2219 | ||
- | 2220 | ohdr_size = sizeof (Elf64_External_Chdr); |
|
- | 2221 | ||
- | 2222 | use_memmove = FALSE; |
|
- | 2223 | } |
|
- | 2224 | else |
|
- | 2225 | { |
|
- | 2226 | Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) contents; |
|
- | 2227 | chdr.ch_type = bfd_get_32 (ibfd, &echdr->ch_type); |
|
- | 2228 | chdr.ch_size = bfd_get_64 (ibfd, &echdr->ch_size); |
|
- | 2229 | chdr.ch_addralign = bfd_get_64 (ibfd, &echdr->ch_addralign); |
|
- | 2230 | ||
- | 2231 | ohdr_size = sizeof (Elf32_External_Chdr); |
|
- | 2232 | use_memmove = TRUE; |
|
- | 2233 | } |
|
- | 2234 | ||
- | 2235 | size = bfd_get_section_size (isec) - ihdr_size + ohdr_size; |
|
- | 2236 | if (!use_memmove) |
|
- | 2237 | { |
|
- | 2238 | contents = (bfd_byte *) bfd_malloc (size); |
|
- | 2239 | if (contents == NULL) |
|
- | 2240 | return FALSE; |
|
- | 2241 | } |
|
- | 2242 | ||
- | 2243 | /* Write out the output compression header. */ |
|
- | 2244 | if (ohdr_size == sizeof (Elf32_External_Chdr)) |
|
- | 2245 | { |
|
- | 2246 | Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) contents; |
|
- | 2247 | bfd_put_32 (obfd, ELFCOMPRESS_ZLIB, &echdr->ch_type); |
|
- | 2248 | bfd_put_32 (obfd, chdr.ch_size, &echdr->ch_size); |
|
- | 2249 | bfd_put_32 (obfd, chdr.ch_addralign, &echdr->ch_addralign); |
|
- | 2250 | } |
|
- | 2251 | else |
|
- | 2252 | { |
|
- | 2253 | Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) contents; |
|
- | 2254 | bfd_put_32 (obfd, ELFCOMPRESS_ZLIB, &echdr->ch_type); |
|
- | 2255 | bfd_put_32 (obfd, 0, &echdr->ch_reserved); |
|
- | 2256 | bfd_put_64 (obfd, chdr.ch_size, &echdr->ch_size); |
|
- | 2257 | bfd_put_64 (obfd, chdr.ch_addralign, &echdr->ch_addralign); |
|
- | 2258 | } |
|
- | 2259 | ||
- | 2260 | /* Copy the compressed contents. */ |
|
- | 2261 | if (use_memmove) |
|
- | 2262 | memmove (contents + ohdr_size, *ptr + ihdr_size, size - ohdr_size); |
|
- | 2263 | else |
|
- | 2264 | { |
|
- | 2265 | memcpy (contents + ohdr_size, *ptr + ihdr_size, size - ohdr_size); |
|
- | 2266 | free (*ptr); |
|
- | 2267 | *ptr = contents; |
|
- | 2268 | } |
|
- | 2269 | ||
- | 2270 | *ptr_size = size; |
|
- | 2271 | return TRUE; |