]>
Commit | Line | Data |
---|---|---|
252b5132 | 1 | /* Assorted BFD support routines, only used internally. |
7898deda | 2 | Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, |
ca09e32b | 3 | 2000, 2001, 2002 |
252b5132 RH |
4 | Free Software Foundation, Inc. |
5 | Written by Cygnus Support. | |
6 | ||
ca09e32b | 7 | This file is part of BFD, the Binary File Descriptor library. |
252b5132 | 8 | |
ca09e32b NC |
9 | This program is free software; you can redistribute it and/or modify |
10 | it under the terms of the GNU General Public License as published by | |
11 | the Free Software Foundation; either version 2 of the License, or | |
12 | (at your option) any later version. | |
252b5132 | 13 | |
ca09e32b NC |
14 | This program is distributed in the hope that it will be useful, |
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
17 | GNU General Public License for more details. | |
252b5132 | 18 | |
ca09e32b NC |
19 | You should have received a copy of the GNU General Public License |
20 | along with this program; if not, write to the Free Software | |
21 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | |
252b5132 RH |
22 | |
23 | #include "bfd.h" | |
24 | #include "sysdep.h" | |
25 | #include "libbfd.h" | |
26 | ||
27 | #ifndef HAVE_GETPAGESIZE | |
28 | #define getpagesize() 2048 | |
29 | #endif | |
30 | ||
252b5132 RH |
31 | /* |
32 | SECTION | |
33 | Internal functions | |
34 | ||
35 | DESCRIPTION | |
36 | These routines are used within BFD. | |
37 | They are not intended for export, but are documented here for | |
38 | completeness. | |
39 | */ | |
40 | ||
41 | /* A routine which is used in target vectors for unsupported | |
42 | operations. */ | |
43 | ||
b34976b6 | 44 | bfd_boolean |
252b5132 | 45 | bfd_false (ignore) |
7442e600 | 46 | bfd *ignore ATTRIBUTE_UNUSED; |
252b5132 RH |
47 | { |
48 | bfd_set_error (bfd_error_invalid_operation); | |
b34976b6 | 49 | return FALSE; |
252b5132 RH |
50 | } |
51 | ||
52 | /* A routine which is used in target vectors for supported operations | |
53 | which do not actually do anything. */ | |
54 | ||
b34976b6 | 55 | bfd_boolean |
252b5132 | 56 | bfd_true (ignore) |
7442e600 | 57 | bfd *ignore ATTRIBUTE_UNUSED; |
252b5132 | 58 | { |
b34976b6 | 59 | return TRUE; |
252b5132 RH |
60 | } |
61 | ||
62 | /* A routine which is used in target vectors for unsupported | |
63 | operations which return a pointer value. */ | |
64 | ||
252b5132 RH |
65 | PTR |
66 | bfd_nullvoidptr (ignore) | |
7442e600 | 67 | bfd *ignore ATTRIBUTE_UNUSED; |
252b5132 RH |
68 | { |
69 | bfd_set_error (bfd_error_invalid_operation); | |
70 | return NULL; | |
71 | } | |
72 | ||
509945ae | 73 | int |
252b5132 | 74 | bfd_0 (ignore) |
7442e600 | 75 | bfd *ignore ATTRIBUTE_UNUSED; |
252b5132 RH |
76 | { |
77 | return 0; | |
78 | } | |
79 | ||
509945ae | 80 | unsigned int |
252b5132 | 81 | bfd_0u (ignore) |
7442e600 | 82 | bfd *ignore ATTRIBUTE_UNUSED; |
252b5132 RH |
83 | { |
84 | return 0; | |
85 | } | |
86 | ||
252b5132 RH |
87 | long |
88 | bfd_0l (ignore) | |
7442e600 | 89 | bfd *ignore ATTRIBUTE_UNUSED; |
252b5132 RH |
90 | { |
91 | return 0; | |
92 | } | |
93 | ||
94 | /* A routine which is used in target vectors for unsupported | |
95 | operations which return -1 on error. */ | |
96 | ||
252b5132 RH |
97 | long |
98 | _bfd_n1 (ignore_abfd) | |
7442e600 | 99 | bfd *ignore_abfd ATTRIBUTE_UNUSED; |
252b5132 RH |
100 | { |
101 | bfd_set_error (bfd_error_invalid_operation); | |
102 | return -1; | |
103 | } | |
104 | ||
509945ae | 105 | void |
252b5132 | 106 | bfd_void (ignore) |
7442e600 | 107 | bfd *ignore ATTRIBUTE_UNUSED; |
252b5132 RH |
108 | { |
109 | } | |
110 | ||
b34976b6 | 111 | bfd_boolean |
252b5132 | 112 | _bfd_nocore_core_file_matches_executable_p (ignore_core_bfd, ignore_exec_bfd) |
7442e600 ILT |
113 | bfd *ignore_core_bfd ATTRIBUTE_UNUSED; |
114 | bfd *ignore_exec_bfd ATTRIBUTE_UNUSED; | |
252b5132 RH |
115 | { |
116 | bfd_set_error (bfd_error_invalid_operation); | |
b34976b6 | 117 | return FALSE; |
252b5132 RH |
118 | } |
119 | ||
120 | /* Routine to handle core_file_failing_command entry point for targets | |
121 | without core file support. */ | |
122 | ||
252b5132 RH |
123 | char * |
124 | _bfd_nocore_core_file_failing_command (ignore_abfd) | |
7442e600 | 125 | bfd *ignore_abfd ATTRIBUTE_UNUSED; |
252b5132 RH |
126 | { |
127 | bfd_set_error (bfd_error_invalid_operation); | |
128 | return (char *)NULL; | |
129 | } | |
130 | ||
131 | /* Routine to handle core_file_failing_signal entry point for targets | |
132 | without core file support. */ | |
133 | ||
252b5132 RH |
134 | int |
135 | _bfd_nocore_core_file_failing_signal (ignore_abfd) | |
7442e600 | 136 | bfd *ignore_abfd ATTRIBUTE_UNUSED; |
252b5132 RH |
137 | { |
138 | bfd_set_error (bfd_error_invalid_operation); | |
139 | return 0; | |
140 | } | |
141 | ||
252b5132 RH |
142 | const bfd_target * |
143 | _bfd_dummy_target (ignore_abfd) | |
7442e600 | 144 | bfd *ignore_abfd ATTRIBUTE_UNUSED; |
252b5132 RH |
145 | { |
146 | bfd_set_error (bfd_error_wrong_format); | |
147 | return 0; | |
148 | } | |
149 | \f | |
150 | /* Allocate memory using malloc. */ | |
151 | ||
152 | PTR | |
153 | bfd_malloc (size) | |
dc810e39 | 154 | bfd_size_type size; |
252b5132 RH |
155 | { |
156 | PTR ptr; | |
157 | ||
dc810e39 AM |
158 | if (size != (size_t) size) |
159 | { | |
160 | bfd_set_error (bfd_error_no_memory); | |
161 | return NULL; | |
162 | } | |
163 | ||
164 | ptr = (PTR) malloc ((size_t) size); | |
165 | if (ptr == NULL && (size_t) size != 0) | |
252b5132 | 166 | bfd_set_error (bfd_error_no_memory); |
dc810e39 | 167 | |
252b5132 RH |
168 | return ptr; |
169 | } | |
170 | ||
171 | /* Reallocate memory using realloc. */ | |
172 | ||
173 | PTR | |
174 | bfd_realloc (ptr, size) | |
175 | PTR ptr; | |
dc810e39 | 176 | bfd_size_type size; |
252b5132 RH |
177 | { |
178 | PTR ret; | |
179 | ||
dc810e39 AM |
180 | if (size != (size_t) size) |
181 | { | |
182 | bfd_set_error (bfd_error_no_memory); | |
183 | return NULL; | |
184 | } | |
185 | ||
252b5132 | 186 | if (ptr == NULL) |
d45913a0 | 187 | ret = (PTR) malloc ((size_t) size); |
252b5132 | 188 | else |
d45913a0 | 189 | ret = (PTR) realloc (ptr, (size_t) size); |
252b5132 | 190 | |
dc810e39 | 191 | if (ret == NULL && (size_t) size != 0) |
252b5132 RH |
192 | bfd_set_error (bfd_error_no_memory); |
193 | ||
194 | return ret; | |
195 | } | |
196 | ||
197 | /* Allocate memory using malloc and clear it. */ | |
198 | ||
199 | PTR | |
200 | bfd_zmalloc (size) | |
dc810e39 | 201 | bfd_size_type size; |
252b5132 RH |
202 | { |
203 | PTR ptr; | |
204 | ||
dc810e39 AM |
205 | if (size != (size_t) size) |
206 | { | |
207 | bfd_set_error (bfd_error_no_memory); | |
208 | return NULL; | |
209 | } | |
252b5132 | 210 | |
dc810e39 AM |
211 | ptr = (PTR) malloc ((size_t) size); |
212 | ||
213 | if ((size_t) size != 0) | |
252b5132 RH |
214 | { |
215 | if (ptr == NULL) | |
216 | bfd_set_error (bfd_error_no_memory); | |
217 | else | |
dc810e39 | 218 | memset (ptr, 0, (size_t) size); |
252b5132 RH |
219 | } |
220 | ||
221 | return ptr; | |
222 | } | |
252b5132 RH |
223 | /* |
224 | INTERNAL_FUNCTION | |
225 | bfd_write_bigendian_4byte_int | |
226 | ||
227 | SYNOPSIS | |
b34976b6 | 228 | bfd_boolean bfd_write_bigendian_4byte_int (bfd *, unsigned int); |
252b5132 RH |
229 | |
230 | DESCRIPTION | |
231 | Write a 4 byte integer @var{i} to the output BFD @var{abfd}, in big | |
232 | endian order regardless of what else is going on. This is useful in | |
233 | archives. | |
234 | ||
235 | */ | |
b34976b6 | 236 | bfd_boolean |
252b5132 RH |
237 | bfd_write_bigendian_4byte_int (abfd, i) |
238 | bfd *abfd; | |
dc810e39 | 239 | unsigned int i; |
252b5132 RH |
240 | { |
241 | bfd_byte buffer[4]; | |
dc810e39 | 242 | bfd_putb32 ((bfd_vma) i, buffer); |
b34976b6 | 243 | return bfd_bwrite ((PTR) buffer, (bfd_size_type) 4, abfd) == 4; |
252b5132 RH |
244 | } |
245 | ||
252b5132 RH |
246 | \f |
247 | /** The do-it-yourself (byte) sex-change kit */ | |
248 | ||
249 | /* The middle letter e.g. get<b>short indicates Big or Little endian | |
250 | target machine. It doesn't matter what the byte order of the host | |
251 | machine is; these routines work for either. */ | |
252 | ||
253 | /* FIXME: Should these take a count argument? | |
254 | Answer ([email protected]): No, but perhaps they should be inline | |
509945ae | 255 | functions in swap.h #ifdef __GNUC__. |
252b5132 RH |
256 | Gprof them later and find out. */ |
257 | ||
258 | /* | |
259 | FUNCTION | |
260 | bfd_put_size | |
261 | FUNCTION | |
262 | bfd_get_size | |
263 | ||
264 | DESCRIPTION | |
265 | These macros as used for reading and writing raw data in | |
266 | sections; each access (except for bytes) is vectored through | |
267 | the target format of the BFD and mangled accordingly. The | |
268 | mangling performs any necessary endian translations and | |
269 | removes alignment restrictions. Note that types accepted and | |
270 | returned by these macros are identical so they can be swapped | |
271 | around in macros---for example, @file{libaout.h} defines <<GET_WORD>> | |
272 | to either <<bfd_get_32>> or <<bfd_get_64>>. | |
273 | ||
274 | In the put routines, @var{val} must be a <<bfd_vma>>. If we are on a | |
275 | system without prototypes, the caller is responsible for making | |
276 | sure that is true, with a cast if necessary. We don't cast | |
277 | them in the macro definitions because that would prevent <<lint>> | |
278 | or <<gcc -Wall>> from detecting sins such as passing a pointer. | |
279 | To detect calling these with less than a <<bfd_vma>>, use | |
280 | <<gcc -Wconversion>> on a host with 64 bit <<bfd_vma>>'s. | |
281 | ||
282 | . | |
283 | .{* Byte swapping macros for user section data. *} | |
284 | . | |
285 | .#define bfd_put_8(abfd, val, ptr) \ | |
509945ae | 286 | . ((void) (*((unsigned char *) (ptr)) = (unsigned char) (val))) |
252b5132 RH |
287 | .#define bfd_put_signed_8 \ |
288 | . bfd_put_8 | |
289 | .#define bfd_get_8(abfd, ptr) \ | |
dc810e39 | 290 | . (*(unsigned char *) (ptr) & 0xff) |
252b5132 | 291 | .#define bfd_get_signed_8(abfd, ptr) \ |
dc810e39 | 292 | . (((*(unsigned char *) (ptr) & 0xff) ^ 0x80) - 0x80) |
252b5132 RH |
293 | . |
294 | .#define bfd_put_16(abfd, val, ptr) \ | |
295 | . BFD_SEND(abfd, bfd_putx16, ((val),(ptr))) | |
296 | .#define bfd_put_signed_16 \ | |
297 | . bfd_put_16 | |
298 | .#define bfd_get_16(abfd, ptr) \ | |
299 | . BFD_SEND(abfd, bfd_getx16, (ptr)) | |
300 | .#define bfd_get_signed_16(abfd, ptr) \ | |
301 | . BFD_SEND (abfd, bfd_getx_signed_16, (ptr)) | |
302 | . | |
303 | .#define bfd_put_32(abfd, val, ptr) \ | |
304 | . BFD_SEND(abfd, bfd_putx32, ((val),(ptr))) | |
305 | .#define bfd_put_signed_32 \ | |
306 | . bfd_put_32 | |
307 | .#define bfd_get_32(abfd, ptr) \ | |
308 | . BFD_SEND(abfd, bfd_getx32, (ptr)) | |
309 | .#define bfd_get_signed_32(abfd, ptr) \ | |
310 | . BFD_SEND(abfd, bfd_getx_signed_32, (ptr)) | |
311 | . | |
312 | .#define bfd_put_64(abfd, val, ptr) \ | |
313 | . BFD_SEND(abfd, bfd_putx64, ((val), (ptr))) | |
314 | .#define bfd_put_signed_64 \ | |
315 | . bfd_put_64 | |
316 | .#define bfd_get_64(abfd, ptr) \ | |
317 | . BFD_SEND(abfd, bfd_getx64, (ptr)) | |
318 | .#define bfd_get_signed_64(abfd, ptr) \ | |
319 | . BFD_SEND(abfd, bfd_getx_signed_64, (ptr)) | |
320 | . | |
c7ac6ff8 | 321 | .#define bfd_get(bits, abfd, ptr) \ |
1e738b87 | 322 | . ( (bits) == 8 ? (bfd_vma) bfd_get_8 (abfd, ptr) \ |
c7ac6ff8 MM |
323 | . : (bits) == 16 ? bfd_get_16 (abfd, ptr) \ |
324 | . : (bits) == 32 ? bfd_get_32 (abfd, ptr) \ | |
325 | . : (bits) == 64 ? bfd_get_64 (abfd, ptr) \ | |
326 | . : (abort (), (bfd_vma) - 1)) | |
327 | . | |
328 | .#define bfd_put(bits, abfd, val, ptr) \ | |
1e738b87 | 329 | . ( (bits) == 8 ? bfd_put_8 (abfd, val, ptr) \ |
c7ac6ff8 MM |
330 | . : (bits) == 16 ? bfd_put_16 (abfd, val, ptr) \ |
331 | . : (bits) == 32 ? bfd_put_32 (abfd, val, ptr) \ | |
332 | . : (bits) == 64 ? bfd_put_64 (abfd, val, ptr) \ | |
333 | . : (abort (), (void) 0)) | |
334 | . | |
509945ae | 335 | */ |
252b5132 RH |
336 | |
337 | /* | |
338 | FUNCTION | |
339 | bfd_h_put_size | |
340 | bfd_h_get_size | |
341 | ||
342 | DESCRIPTION | |
343 | These macros have the same function as their <<bfd_get_x>> | |
dc810e39 | 344 | brethren, except that they are used for removing information |
252b5132 RH |
345 | for the header records of object files. Believe it or not, |
346 | some object files keep their header records in big endian | |
347 | order and their data in little endian order. | |
348 | . | |
349 | .{* Byte swapping macros for file header data. *} | |
350 | . | |
351 | .#define bfd_h_put_8(abfd, val, ptr) \ | |
dc810e39 | 352 | . bfd_put_8 (abfd, val, ptr) |
252b5132 | 353 | .#define bfd_h_put_signed_8(abfd, val, ptr) \ |
dc810e39 | 354 | . bfd_put_8 (abfd, val, ptr) |
252b5132 | 355 | .#define bfd_h_get_8(abfd, ptr) \ |
dc810e39 | 356 | . bfd_get_8 (abfd, ptr) |
252b5132 | 357 | .#define bfd_h_get_signed_8(abfd, ptr) \ |
dc810e39 | 358 | . bfd_get_signed_8 (abfd, ptr) |
252b5132 RH |
359 | . |
360 | .#define bfd_h_put_16(abfd, val, ptr) \ | |
dc810e39 | 361 | . BFD_SEND (abfd, bfd_h_putx16, (val, ptr)) |
252b5132 | 362 | .#define bfd_h_put_signed_16 \ |
dc810e39 | 363 | . bfd_h_put_16 |
252b5132 | 364 | .#define bfd_h_get_16(abfd, ptr) \ |
dc810e39 | 365 | . BFD_SEND (abfd, bfd_h_getx16, (ptr)) |
252b5132 | 366 | .#define bfd_h_get_signed_16(abfd, ptr) \ |
dc810e39 | 367 | . BFD_SEND (abfd, bfd_h_getx_signed_16, (ptr)) |
252b5132 RH |
368 | . |
369 | .#define bfd_h_put_32(abfd, val, ptr) \ | |
dc810e39 | 370 | . BFD_SEND (abfd, bfd_h_putx32, (val, ptr)) |
252b5132 | 371 | .#define bfd_h_put_signed_32 \ |
dc810e39 | 372 | . bfd_h_put_32 |
252b5132 | 373 | .#define bfd_h_get_32(abfd, ptr) \ |
dc810e39 | 374 | . BFD_SEND (abfd, bfd_h_getx32, (ptr)) |
252b5132 | 375 | .#define bfd_h_get_signed_32(abfd, ptr) \ |
dc810e39 | 376 | . BFD_SEND (abfd, bfd_h_getx_signed_32, (ptr)) |
252b5132 RH |
377 | . |
378 | .#define bfd_h_put_64(abfd, val, ptr) \ | |
dc810e39 | 379 | . BFD_SEND (abfd, bfd_h_putx64, (val, ptr)) |
252b5132 | 380 | .#define bfd_h_put_signed_64 \ |
dc810e39 | 381 | . bfd_h_put_64 |
252b5132 | 382 | .#define bfd_h_get_64(abfd, ptr) \ |
dc810e39 | 383 | . BFD_SEND (abfd, bfd_h_getx64, (ptr)) |
252b5132 | 384 | .#define bfd_h_get_signed_64(abfd, ptr) \ |
dc810e39 | 385 | . BFD_SEND (abfd, bfd_h_getx_signed_64, (ptr)) |
252b5132 | 386 | . |
dc810e39 AM |
387 | .{* Refinements on the above, which should eventually go away. Save |
388 | . cluttering the source with (bfd_vma) and (bfd_byte *) casts. *} | |
389 | . | |
390 | .#define H_PUT_64(abfd, val, where) \ | |
391 | . bfd_h_put_64 ((abfd), (bfd_vma) (val), (bfd_byte *) (where)) | |
392 | . | |
393 | .#define H_PUT_32(abfd, val, where) \ | |
394 | . bfd_h_put_32 ((abfd), (bfd_vma) (val), (bfd_byte *) (where)) | |
395 | . | |
396 | .#define H_PUT_16(abfd, val, where) \ | |
397 | . bfd_h_put_16 ((abfd), (bfd_vma) (val), (bfd_byte *) (where)) | |
398 | . | |
399 | .#define H_PUT_8 bfd_h_put_8 | |
400 | . | |
401 | .#define H_PUT_S64(abfd, val, where) \ | |
402 | . bfd_h_put_signed_64 ((abfd), (bfd_vma) (val), (bfd_byte *) (where)) | |
403 | . | |
404 | .#define H_PUT_S32(abfd, val, where) \ | |
405 | . bfd_h_put_signed_32 ((abfd), (bfd_vma) (val), (bfd_byte *) (where)) | |
406 | . | |
407 | .#define H_PUT_S16(abfd, val, where) \ | |
408 | . bfd_h_put_signed_16 ((abfd), (bfd_vma) (val), (bfd_byte *) (where)) | |
409 | . | |
410 | .#define H_PUT_S8 bfd_h_put_signed_8 | |
411 | . | |
412 | .#define H_GET_64(abfd, where) \ | |
413 | . bfd_h_get_64 ((abfd), (bfd_byte *) (where)) | |
414 | . | |
415 | .#define H_GET_32(abfd, where) \ | |
416 | . bfd_h_get_32 ((abfd), (bfd_byte *) (where)) | |
417 | . | |
418 | .#define H_GET_16(abfd, where) \ | |
419 | . bfd_h_get_16 ((abfd), (bfd_byte *) (where)) | |
420 | . | |
421 | .#define H_GET_8 bfd_h_get_8 | |
422 | . | |
423 | .#define H_GET_S64(abfd, where) \ | |
424 | . bfd_h_get_signed_64 ((abfd), (bfd_byte *) (where)) | |
425 | . | |
426 | .#define H_GET_S32(abfd, where) \ | |
427 | . bfd_h_get_signed_32 ((abfd), (bfd_byte *) (where)) | |
428 | . | |
429 | .#define H_GET_S16(abfd, where) \ | |
430 | . bfd_h_get_signed_16 ((abfd), (bfd_byte *) (where)) | |
431 | . | |
432 | .#define H_GET_S8 bfd_h_get_signed_8 | |
433 | . | |
434 | .*/ | |
252b5132 RH |
435 | |
436 | /* Sign extension to bfd_signed_vma. */ | |
437 | #define COERCE16(x) (((bfd_signed_vma) (x) ^ 0x8000) - 0x8000) | |
438 | #define COERCE32(x) \ | |
439 | ((bfd_signed_vma) (long) (((unsigned long) (x) ^ 0x80000000) - 0x80000000)) | |
440 | #define EIGHT_GAZILLION (((BFD_HOST_64_BIT)0x80000000) << 32) | |
441 | #define COERCE64(x) \ | |
442 | (((bfd_signed_vma) (x) ^ EIGHT_GAZILLION) - EIGHT_GAZILLION) | |
443 | ||
444 | bfd_vma | |
445 | bfd_getb16 (addr) | |
446 | register const bfd_byte *addr; | |
447 | { | |
448 | return (addr[0] << 8) | addr[1]; | |
449 | } | |
450 | ||
451 | bfd_vma | |
452 | bfd_getl16 (addr) | |
453 | register const bfd_byte *addr; | |
454 | { | |
455 | return (addr[1] << 8) | addr[0]; | |
456 | } | |
457 | ||
458 | bfd_signed_vma | |
459 | bfd_getb_signed_16 (addr) | |
460 | register const bfd_byte *addr; | |
461 | { | |
462 | return COERCE16((addr[0] << 8) | addr[1]); | |
463 | } | |
464 | ||
465 | bfd_signed_vma | |
466 | bfd_getl_signed_16 (addr) | |
467 | register const bfd_byte *addr; | |
468 | { | |
469 | return COERCE16((addr[1] << 8) | addr[0]); | |
470 | } | |
471 | ||
472 | void | |
473 | bfd_putb16 (data, addr) | |
474 | bfd_vma data; | |
475 | register bfd_byte *addr; | |
476 | { | |
509945ae | 477 | addr[0] = (bfd_byte) (data >> 8); |
708b82c7 | 478 | addr[1] = (bfd_byte) data; |
252b5132 RH |
479 | } |
480 | ||
481 | void | |
482 | bfd_putl16 (data, addr) | |
509945ae | 483 | bfd_vma data; |
252b5132 RH |
484 | register bfd_byte *addr; |
485 | { | |
708b82c7 | 486 | addr[0] = (bfd_byte) data; |
509945ae | 487 | addr[1] = (bfd_byte) (data >> 8); |
252b5132 RH |
488 | } |
489 | ||
490 | bfd_vma | |
491 | bfd_getb32 (addr) | |
492 | register const bfd_byte *addr; | |
493 | { | |
494 | unsigned long v; | |
495 | ||
496 | v = (unsigned long) addr[0] << 24; | |
497 | v |= (unsigned long) addr[1] << 16; | |
498 | v |= (unsigned long) addr[2] << 8; | |
499 | v |= (unsigned long) addr[3]; | |
500 | return (bfd_vma) v; | |
501 | } | |
502 | ||
503 | bfd_vma | |
504 | bfd_getl32 (addr) | |
505 | register const bfd_byte *addr; | |
506 | { | |
507 | unsigned long v; | |
508 | ||
509 | v = (unsigned long) addr[0]; | |
510 | v |= (unsigned long) addr[1] << 8; | |
511 | v |= (unsigned long) addr[2] << 16; | |
512 | v |= (unsigned long) addr[3] << 24; | |
513 | return (bfd_vma) v; | |
514 | } | |
515 | ||
516 | bfd_signed_vma | |
517 | bfd_getb_signed_32 (addr) | |
518 | register const bfd_byte *addr; | |
519 | { | |
520 | unsigned long v; | |
521 | ||
522 | v = (unsigned long) addr[0] << 24; | |
523 | v |= (unsigned long) addr[1] << 16; | |
524 | v |= (unsigned long) addr[2] << 8; | |
525 | v |= (unsigned long) addr[3]; | |
526 | return COERCE32 (v); | |
527 | } | |
528 | ||
529 | bfd_signed_vma | |
530 | bfd_getl_signed_32 (addr) | |
531 | register const bfd_byte *addr; | |
532 | { | |
533 | unsigned long v; | |
534 | ||
535 | v = (unsigned long) addr[0]; | |
536 | v |= (unsigned long) addr[1] << 8; | |
537 | v |= (unsigned long) addr[2] << 16; | |
538 | v |= (unsigned long) addr[3] << 24; | |
539 | return COERCE32 (v); | |
540 | } | |
541 | ||
542 | bfd_vma | |
543 | bfd_getb64 (addr) | |
7442e600 | 544 | register const bfd_byte *addr ATTRIBUTE_UNUSED; |
252b5132 RH |
545 | { |
546 | #ifdef BFD64 | |
547 | bfd_vma low, high; | |
548 | ||
549 | high= ((((((((addr[0]) << 8) | | |
550 | addr[1]) << 8) | | |
551 | addr[2]) << 8) | | |
552 | addr[3]) ); | |
553 | ||
554 | low = (((((((((bfd_vma)addr[4]) << 8) | | |
555 | addr[5]) << 8) | | |
556 | addr[6]) << 8) | | |
557 | addr[7])); | |
558 | ||
559 | return high << 32 | low; | |
560 | #else | |
561 | BFD_FAIL(); | |
562 | return 0; | |
563 | #endif | |
564 | } | |
565 | ||
566 | bfd_vma | |
567 | bfd_getl64 (addr) | |
7442e600 | 568 | register const bfd_byte *addr ATTRIBUTE_UNUSED; |
252b5132 RH |
569 | { |
570 | #ifdef BFD64 | |
571 | bfd_vma low, high; | |
572 | high= (((((((addr[7] << 8) | | |
573 | addr[6]) << 8) | | |
574 | addr[5]) << 8) | | |
575 | addr[4])); | |
576 | ||
577 | low = ((((((((bfd_vma)addr[3] << 8) | | |
578 | addr[2]) << 8) | | |
579 | addr[1]) << 8) | | |
580 | addr[0]) ); | |
581 | ||
582 | return high << 32 | low; | |
583 | #else | |
584 | BFD_FAIL(); | |
585 | return 0; | |
586 | #endif | |
587 | ||
588 | } | |
589 | ||
590 | bfd_signed_vma | |
591 | bfd_getb_signed_64 (addr) | |
7442e600 | 592 | register const bfd_byte *addr ATTRIBUTE_UNUSED; |
252b5132 RH |
593 | { |
594 | #ifdef BFD64 | |
595 | bfd_vma low, high; | |
596 | ||
597 | high= ((((((((addr[0]) << 8) | | |
598 | addr[1]) << 8) | | |
599 | addr[2]) << 8) | | |
600 | addr[3]) ); | |
601 | ||
602 | low = (((((((((bfd_vma)addr[4]) << 8) | | |
603 | addr[5]) << 8) | | |
604 | addr[6]) << 8) | | |
605 | addr[7])); | |
606 | ||
607 | return COERCE64(high << 32 | low); | |
608 | #else | |
609 | BFD_FAIL(); | |
610 | return 0; | |
611 | #endif | |
612 | } | |
613 | ||
614 | bfd_signed_vma | |
615 | bfd_getl_signed_64 (addr) | |
7442e600 | 616 | register const bfd_byte *addr ATTRIBUTE_UNUSED; |
252b5132 RH |
617 | { |
618 | #ifdef BFD64 | |
619 | bfd_vma low, high; | |
620 | high= (((((((addr[7] << 8) | | |
621 | addr[6]) << 8) | | |
622 | addr[5]) << 8) | | |
623 | addr[4])); | |
624 | ||
625 | low = ((((((((bfd_vma)addr[3] << 8) | | |
626 | addr[2]) << 8) | | |
627 | addr[1]) << 8) | | |
628 | addr[0]) ); | |
629 | ||
630 | return COERCE64(high << 32 | low); | |
631 | #else | |
632 | BFD_FAIL(); | |
633 | return 0; | |
634 | #endif | |
635 | } | |
636 | ||
637 | void | |
638 | bfd_putb32 (data, addr) | |
639 | bfd_vma data; | |
640 | register bfd_byte *addr; | |
641 | { | |
509945ae KH |
642 | addr[0] = (bfd_byte) (data >> 24); |
643 | addr[1] = (bfd_byte) (data >> 16); | |
644 | addr[2] = (bfd_byte) (data >> 8); | |
708b82c7 | 645 | addr[3] = (bfd_byte) data; |
252b5132 RH |
646 | } |
647 | ||
648 | void | |
649 | bfd_putl32 (data, addr) | |
650 | bfd_vma data; | |
651 | register bfd_byte *addr; | |
652 | { | |
708b82c7 | 653 | addr[0] = (bfd_byte) data; |
509945ae KH |
654 | addr[1] = (bfd_byte) (data >> 8); |
655 | addr[2] = (bfd_byte) (data >> 16); | |
656 | addr[3] = (bfd_byte) (data >> 24); | |
252b5132 RH |
657 | } |
658 | ||
659 | void | |
660 | bfd_putb64 (data, addr) | |
7442e600 ILT |
661 | bfd_vma data ATTRIBUTE_UNUSED; |
662 | register bfd_byte *addr ATTRIBUTE_UNUSED; | |
252b5132 RH |
663 | { |
664 | #ifdef BFD64 | |
509945ae KH |
665 | addr[0] = (bfd_byte) (data >> (7*8)); |
666 | addr[1] = (bfd_byte) (data >> (6*8)); | |
667 | addr[2] = (bfd_byte) (data >> (5*8)); | |
668 | addr[3] = (bfd_byte) (data >> (4*8)); | |
669 | addr[4] = (bfd_byte) (data >> (3*8)); | |
670 | addr[5] = (bfd_byte) (data >> (2*8)); | |
671 | addr[6] = (bfd_byte) (data >> (1*8)); | |
672 | addr[7] = (bfd_byte) (data >> (0*8)); | |
252b5132 RH |
673 | #else |
674 | BFD_FAIL(); | |
675 | #endif | |
676 | } | |
677 | ||
678 | void | |
679 | bfd_putl64 (data, addr) | |
7442e600 ILT |
680 | bfd_vma data ATTRIBUTE_UNUSED; |
681 | register bfd_byte *addr ATTRIBUTE_UNUSED; | |
252b5132 RH |
682 | { |
683 | #ifdef BFD64 | |
509945ae KH |
684 | addr[7] = (bfd_byte) (data >> (7*8)); |
685 | addr[6] = (bfd_byte) (data >> (6*8)); | |
686 | addr[5] = (bfd_byte) (data >> (5*8)); | |
687 | addr[4] = (bfd_byte) (data >> (4*8)); | |
688 | addr[3] = (bfd_byte) (data >> (3*8)); | |
689 | addr[2] = (bfd_byte) (data >> (2*8)); | |
690 | addr[1] = (bfd_byte) (data >> (1*8)); | |
691 | addr[0] = (bfd_byte) (data >> (0*8)); | |
252b5132 RH |
692 | #else |
693 | BFD_FAIL(); | |
694 | #endif | |
695 | } | |
8c603c85 NC |
696 | |
697 | void | |
698 | bfd_put_bits (data, addr, bits, big_p) | |
699 | bfd_vma data; | |
700 | bfd_byte *addr; | |
701 | int bits; | |
b34976b6 | 702 | bfd_boolean big_p; |
8c603c85 NC |
703 | { |
704 | int i; | |
705 | int bytes; | |
706 | ||
707 | if (bits % 8 != 0) | |
708 | abort (); | |
709 | ||
710 | bytes = bits / 8; | |
711 | for (i = 0; i < bytes; i++) | |
712 | { | |
713 | int index = big_p ? bytes - i - 1 : i; | |
714 | ||
715 | addr[index] = (bfd_byte) data; | |
716 | data >>= 8; | |
717 | } | |
718 | } | |
719 | ||
720 | bfd_vma | |
721 | bfd_get_bits (addr, bits, big_p) | |
722 | bfd_byte *addr; | |
723 | int bits; | |
b34976b6 | 724 | bfd_boolean big_p; |
8c603c85 NC |
725 | { |
726 | bfd_vma data; | |
727 | int i; | |
728 | int bytes; | |
729 | ||
730 | if (bits % 8 != 0) | |
731 | abort (); | |
732 | ||
733 | data = 0; | |
734 | bytes = bits / 8; | |
735 | for (i = 0; i < bytes; i++) | |
736 | { | |
737 | int index = big_p ? i : bytes - i - 1; | |
509945ae | 738 | |
8c603c85 NC |
739 | data = (data << 8) | addr[index]; |
740 | } | |
741 | ||
742 | return data; | |
743 | } | |
252b5132 RH |
744 | \f |
745 | /* Default implementation */ | |
746 | ||
b34976b6 | 747 | bfd_boolean |
252b5132 RH |
748 | _bfd_generic_get_section_contents (abfd, section, location, offset, count) |
749 | bfd *abfd; | |
750 | sec_ptr section; | |
751 | PTR location; | |
752 | file_ptr offset; | |
753 | bfd_size_type count; | |
754 | { | |
0bff3f4b | 755 | if (count == 0) |
b34976b6 | 756 | return TRUE; |
0bff3f4b | 757 | |
dc810e39 | 758 | if (offset + count > section->_raw_size) |
0bff3f4b ILT |
759 | { |
760 | bfd_set_error (bfd_error_invalid_operation); | |
b34976b6 | 761 | return FALSE; |
0bff3f4b ILT |
762 | } |
763 | ||
764 | if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0 | |
dc810e39 | 765 | || bfd_bread (location, count, abfd) != count) |
b34976b6 | 766 | return FALSE; |
0bff3f4b | 767 | |
b34976b6 | 768 | return TRUE; |
252b5132 RH |
769 | } |
770 | ||
b34976b6 | 771 | bfd_boolean |
252b5132 | 772 | _bfd_generic_get_section_contents_in_window (abfd, section, w, offset, count) |
7442e600 ILT |
773 | bfd *abfd ATTRIBUTE_UNUSED; |
774 | sec_ptr section ATTRIBUTE_UNUSED; | |
775 | bfd_window *w ATTRIBUTE_UNUSED; | |
776 | file_ptr offset ATTRIBUTE_UNUSED; | |
777 | bfd_size_type count ATTRIBUTE_UNUSED; | |
252b5132 RH |
778 | { |
779 | #ifdef USE_MMAP | |
780 | if (count == 0) | |
b34976b6 | 781 | return TRUE; |
252b5132 RH |
782 | if (abfd->xvec->_bfd_get_section_contents != _bfd_generic_get_section_contents) |
783 | { | |
784 | /* We don't know what changes the bfd's get_section_contents | |
785 | method may have to make. So punt trying to map the file | |
786 | window, and let get_section_contents do its thing. */ | |
787 | /* @@ FIXME : If the internal window has a refcount of 1 and was | |
788 | allocated with malloc instead of mmap, just reuse it. */ | |
789 | bfd_free_window (w); | |
dc810e39 AM |
790 | w->i = ((bfd_window_internal *) |
791 | bfd_zmalloc ((bfd_size_type) sizeof (bfd_window_internal))); | |
252b5132 | 792 | if (w->i == NULL) |
b34976b6 | 793 | return FALSE; |
dc810e39 | 794 | w->i->data = (PTR) bfd_malloc (count); |
252b5132 RH |
795 | if (w->i->data == NULL) |
796 | { | |
797 | free (w->i); | |
798 | w->i = NULL; | |
b34976b6 | 799 | return FALSE; |
252b5132 RH |
800 | } |
801 | w->i->mapped = 0; | |
802 | w->i->refcount = 1; | |
803 | w->size = w->i->size = count; | |
804 | w->data = w->i->data; | |
805 | return bfd_get_section_contents (abfd, section, w->data, offset, count); | |
806 | } | |
dc810e39 | 807 | if (offset + count > section->_raw_size |
82e51918 | 808 | || ! bfd_get_file_window (abfd, section->filepos + offset, count, w, |
b34976b6 AM |
809 | TRUE)) |
810 | return FALSE; | |
811 | return TRUE; | |
252b5132 RH |
812 | #else |
813 | abort (); | |
814 | #endif | |
815 | } | |
816 | ||
817 | /* This generic function can only be used in implementations where creating | |
818 | NEW sections is disallowed. It is useful in patching existing sections | |
819 | in read-write files, though. See other set_section_contents functions | |
820 | to see why it doesn't work for new sections. */ | |
b34976b6 | 821 | bfd_boolean |
252b5132 RH |
822 | _bfd_generic_set_section_contents (abfd, section, location, offset, count) |
823 | bfd *abfd; | |
824 | sec_ptr section; | |
825 | PTR location; | |
826 | file_ptr offset; | |
827 | bfd_size_type count; | |
828 | { | |
829 | if (count == 0) | |
b34976b6 | 830 | return TRUE; |
252b5132 | 831 | |
dc810e39 AM |
832 | if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0 |
833 | || bfd_bwrite (location, count, abfd) != count) | |
b34976b6 | 834 | return FALSE; |
252b5132 | 835 | |
b34976b6 | 836 | return TRUE; |
252b5132 RH |
837 | } |
838 | ||
839 | /* | |
840 | INTERNAL_FUNCTION | |
841 | bfd_log2 | |
842 | ||
843 | SYNOPSIS | |
dc810e39 | 844 | unsigned int bfd_log2 (bfd_vma x); |
252b5132 RH |
845 | |
846 | DESCRIPTION | |
847 | Return the log base 2 of the value supplied, rounded up. E.g., an | |
dc810e39 | 848 | @var{x} of 1025 returns 11. A @var{x} of 0 returns 0. |
252b5132 RH |
849 | */ |
850 | ||
851 | unsigned int | |
852 | bfd_log2 (x) | |
853 | bfd_vma x; | |
854 | { | |
855 | unsigned int result = 0; | |
856 | ||
86b21447 | 857 | while ((x = (x >> 1)) != 0) |
252b5132 RH |
858 | ++result; |
859 | return result; | |
860 | } | |
861 | ||
b34976b6 | 862 | bfd_boolean |
252b5132 RH |
863 | bfd_generic_is_local_label_name (abfd, name) |
864 | bfd *abfd; | |
865 | const char *name; | |
866 | { | |
867 | char locals_prefix = (bfd_get_symbol_leading_char (abfd) == '_') ? 'L' : '.'; | |
868 | ||
b34976b6 | 869 | return name[0] == locals_prefix; |
252b5132 RH |
870 | } |
871 | ||
875f7f69 JR |
872 | /* Can be used from / for bfd_merge_private_bfd_data to check that |
873 | endianness matches between input and output file. Returns | |
b34976b6 AM |
874 | TRUE for a match, otherwise returns FALSE and emits an error. */ |
875 | bfd_boolean | |
875f7f69 JR |
876 | _bfd_generic_verify_endian_match (ibfd, obfd) |
877 | bfd *ibfd; | |
878 | bfd *obfd; | |
879 | { | |
880 | if (ibfd->xvec->byteorder != obfd->xvec->byteorder | |
1fe494a5 | 881 | && ibfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN |
875f7f69 JR |
882 | && obfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN) |
883 | { | |
1fe494a5 NC |
884 | const char *msg; |
885 | ||
886 | if (bfd_big_endian (ibfd)) | |
887 | msg = _("%s: compiled for a big endian system and target is little endian"); | |
888 | else | |
889 | msg = _("%s: compiled for a little endian system and target is big endian"); | |
890 | ||
8f615d07 | 891 | (*_bfd_error_handler) (msg, bfd_archive_filename (ibfd)); |
875f7f69 JR |
892 | |
893 | bfd_set_error (bfd_error_wrong_format); | |
b34976b6 | 894 | return FALSE; |
875f7f69 JR |
895 | } |
896 | ||
b34976b6 | 897 | return TRUE; |
875f7f69 | 898 | } |
dc810e39 AM |
899 | |
900 | /* Give a warning at runtime if someone compiles code which calls | |
901 | old routines. */ | |
ca09e32b | 902 | |
dc810e39 AM |
903 | void |
904 | warn_deprecated (what, file, line, func) | |
905 | const char *what; | |
906 | const char *file; | |
907 | int line; | |
908 | const char *func; | |
909 | { | |
910 | /* Poor man's tracking of functions we've already warned about. */ | |
911 | static size_t mask = 0; | |
912 | ||
913 | if (~(size_t) func & ~mask) | |
914 | { | |
73722af0 | 915 | /* Note: separate sentences in order to allow |
ca09e32b | 916 | for translation into other languages. */ |
dc810e39 | 917 | if (func) |
ca09e32b NC |
918 | fprintf (stderr, _("Deprecated %s called at %s line %d in %s\n"), |
919 | what, file, line, func); | |
dc810e39 | 920 | else |
ca09e32b | 921 | fprintf (stderr, _("Deprecated %s called\n"), what); |
dc810e39 AM |
922 | mask |= ~(size_t) func; |
923 | } | |
924 | } |