]>
Commit | Line | Data |
---|---|---|
f58809fd SC |
1 | /* libbfd.c -- random BFD support routines, only used internally. |
2 | Copyright (C) 1990-1991 Free Software Foundation, Inc. | |
3 | Written by Cygnus Support. | |
4a81b561 | 4 | |
f58809fd | 5 | This file is part of BFD, the Binary File Descriptor library. |
4a81b561 | 6 | |
f58809fd | 7 | This program is free software; you can redistribute it and/or modify |
4a81b561 | 8 | it under the terms of the GNU General Public License as published by |
f58809fd SC |
9 | the Free Software Foundation; either version 2 of the License, or |
10 | (at your option) any later version. | |
4a81b561 | 11 | |
f58809fd | 12 | This program is distributed in the hope that it will be useful, |
4a81b561 DHW |
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | GNU General Public License for more details. | |
16 | ||
17 | You should have received a copy of the GNU General Public License | |
f58809fd SC |
18 | along with this program; if not, write to the Free Software |
19 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ | |
4a81b561 DHW |
20 | |
21 | /* $Id$ */ | |
22 | ||
4a81b561 | 23 | #include "bfd.h" |
f58809fd | 24 | #include "sysdep.h" |
4a81b561 DHW |
25 | #include "libbfd.h" |
26 | ||
4a81b561 DHW |
27 | /** Dummies for targets that don't want or need to implement |
28 | certain operations */ | |
29 | ||
30 | boolean | |
536b27a5 SC |
31 | DEFUN(_bfd_dummy_new_section_hook,(ignore, ignore_newsect), |
32 | bfd *ignore AND | |
33 | asection *ignore_newsect) | |
4a81b561 DHW |
34 | { |
35 | return true; | |
36 | } | |
37 | ||
38 | boolean | |
536b27a5 SC |
39 | DEFUN(bfd_false ,(ignore), |
40 | bfd *ignore) | |
4a81b561 DHW |
41 | { |
42 | return false; | |
43 | } | |
44 | ||
45 | boolean | |
536b27a5 SC |
46 | DEFUN(bfd_true,(ignore), |
47 | bfd *ignore) | |
4a81b561 DHW |
48 | { |
49 | return true; | |
50 | } | |
51 | ||
d0ec7a8e | 52 | PTR |
536b27a5 SC |
53 | DEFUN(bfd_nullvoidptr,(ignore), |
54 | bfd *ignore) | |
4a81b561 | 55 | { |
d0ec7a8e | 56 | return (PTR)NULL; |
4a81b561 | 57 | } |
fc723380 | 58 | |
4a81b561 | 59 | int |
536b27a5 SC |
60 | DEFUN(bfd_0,(ignore), |
61 | bfd *ignore) | |
4a81b561 DHW |
62 | { |
63 | return 0; | |
64 | } | |
fc723380 | 65 | |
4a81b561 | 66 | unsigned int |
536b27a5 SC |
67 | DEFUN(bfd_0u,(ignore), |
68 | bfd *ignore) | |
4a81b561 DHW |
69 | { |
70 | return 0; | |
71 | } | |
72 | ||
73 | void | |
536b27a5 SC |
74 | DEFUN(bfd_void,(ignore), |
75 | bfd *ignore) | |
4a81b561 DHW |
76 | { |
77 | } | |
78 | ||
79 | boolean | |
536b27a5 SC |
80 | DEFUN(_bfd_dummy_core_file_matches_executable_p,(ignore_core_bfd, ignore_exec_bfd), |
81 | bfd *ignore_core_bfd AND | |
82 | bfd *ignore_exec_bfd) | |
4a81b561 DHW |
83 | { |
84 | bfd_error = invalid_operation; | |
85 | return false; | |
86 | } | |
87 | ||
88 | /* of course you can't initialize a function to be the same as another, grr */ | |
89 | ||
90 | char * | |
0f268757 | 91 | DEFUN(_bfd_dummy_core_file_failing_command,(ignore_abfd), |
536b27a5 | 92 | bfd *ignore_abfd) |
4a81b561 DHW |
93 | { |
94 | return (char *)NULL; | |
95 | } | |
96 | ||
97 | int | |
536b27a5 SC |
98 | DEFUN(_bfd_dummy_core_file_failing_signal,(ignore_abfd), |
99 | bfd *ignore_abfd) | |
4a81b561 DHW |
100 | { |
101 | return 0; | |
102 | } | |
103 | ||
104 | bfd_target * | |
536b27a5 SC |
105 | DEFUN(_bfd_dummy_target,(ignore_abfd), |
106 | bfd *ignore_abfd) | |
4a81b561 DHW |
107 | { |
108 | return 0; | |
109 | } | |
110 | \f | |
111 | /** zalloc -- allocate and clear storage */ | |
112 | ||
113 | ||
114 | #ifndef zalloc | |
115 | char * | |
536b27a5 SC |
116 | DEFUN(zalloc,(size), |
117 | bfd_size_type size) | |
4a81b561 | 118 | { |
7ed4093a | 119 | char *ptr = (char *) malloc ((int)size); |
4a81b561 DHW |
120 | |
121 | if ((ptr != NULL) && (size != 0)) | |
301dfc71 | 122 | memset(ptr,0, size); |
4a81b561 DHW |
123 | |
124 | return ptr; | |
125 | } | |
126 | #endif | |
1e310759 JG |
127 | |
128 | /*proto-internal* bfd_xmalloc | |
129 | bfd_xmalloc -- Like malloc, but exit if no more memory. | |
130 | *; PROTO(PTR, bfd_xmalloc,( bfd_size_type size)); | |
131 | */ | |
132 | /** There is major inconsistency in how running out of memory is handled. | |
133 | Some routines return a NULL, and set bfd_error to no_memory. | |
134 | However, obstack routines can't do this ... */ | |
135 | ||
136 | ||
137 | DEFUN(PTR bfd_xmalloc,(size), | |
138 | bfd_size_type size) | |
139 | { | |
140 | static char no_memory_message[] = "Virtual memory exhausted!\n"; | |
141 | PTR ptr; | |
142 | if (size == 0) size = 1; | |
143 | ptr = (PTR)malloc(size); | |
144 | if (ptr == NULL) | |
145 | if (!ptr) | |
146 | { | |
147 | write (2, no_memory_message, sizeof(no_memory_message)-1); | |
148 | exit (-1); | |
149 | } | |
150 | return ptr; | |
151 | } | |
4a81b561 DHW |
152 | \f |
153 | /* Some IO code */ | |
154 | ||
155 | ||
156 | /* Note that archive entries don't have streams; they share their parent's. | |
f58809fd | 157 | This allows someone to play with the iostream behind BFD's back. |
4a81b561 DHW |
158 | |
159 | Also, note that the origin pointer points to the beginning of a file's | |
160 | contents (0 for non-archive elements). For archive entries this is the | |
161 | first octet in the file, NOT the beginning of the archive header. */ | |
162 | ||
7ed4093a SC |
163 | static |
164 | int DEFUN(real_read,(where, a,b, file), | |
6f715d66 SC |
165 | PTR where AND |
166 | int a AND | |
167 | int b AND | |
168 | FILE *file) | |
7ed4093a SC |
169 | { |
170 | return fread(where, a,b,file); | |
171 | } | |
23b0b558 | 172 | bfd_size_type |
7ed4093a SC |
173 | DEFUN(bfd_read,(ptr, size, nitems, abfd), |
174 | PTR ptr AND | |
175 | bfd_size_type size AND | |
176 | bfd_size_type nitems AND | |
177 | bfd *abfd) | |
4a81b561 | 178 | { |
7ed4093a | 179 | return (bfd_size_type)real_read (ptr, 1, (int)(size*nitems), bfd_cache_lookup(abfd)); |
4a81b561 DHW |
180 | } |
181 | ||
23b0b558 | 182 | bfd_size_type |
7ed4093a | 183 | DEFUN(bfd_write,(ptr, size, nitems, abfd), |
f58809fd | 184 | CONST PTR ptr AND |
7ed4093a SC |
185 | bfd_size_type size AND |
186 | bfd_size_type nitems AND | |
187 | bfd *abfd) | |
4a81b561 | 188 | { |
7ed4093a | 189 | return fwrite (ptr, 1, (int)(size*nitems), bfd_cache_lookup(abfd)); |
4a81b561 DHW |
190 | } |
191 | ||
1e310759 JG |
192 | /*proto-internal* bfd_write_bigendian_4byte_int |
193 | ||
194 | *; PROTO(void, bfd_write_bigendian_4byte_int,( bfd *abfd, int i)); | |
195 | */ | |
f58809fd SC |
196 | void |
197 | DEFUN(bfd_write_bigendian_4byte_int,(abfd, i), | |
198 | bfd *abfd AND | |
199 | int i) | |
200 | { | |
1e310759 | 201 | bfd_byte buffer[4]; |
f58809fd | 202 | _do_putb32(i, buffer); |
1e310759 | 203 | bfd_write((PTR)buffer, 4, 1, abfd); |
f58809fd SC |
204 | } |
205 | ||
4a81b561 | 206 | int |
7ed4093a SC |
207 | DEFUN(bfd_seek,(abfd, position, direction), |
208 | bfd * CONST abfd AND | |
209 | CONST file_ptr position AND | |
210 | CONST int direction) | |
4a81b561 | 211 | { |
f58809fd | 212 | /* For the time being, a BFD may not seek to it's end. The |
6f715d66 SC |
213 | problem is that we don't easily have a way to recognize |
214 | the end of an element in an archive. */ | |
215 | ||
216 | BFD_ASSERT(direction == SEEK_SET | |
217 | || direction == SEEK_CUR); | |
218 | ||
219 | if (direction == SEEK_SET && abfd->my_archive != NULL) | |
220 | { | |
221 | /* This is a set within an archive, so we need to | |
222 | add the base of the object within the archive */ | |
223 | return(fseek(bfd_cache_lookup(abfd), | |
224 | position + abfd->origin, | |
225 | direction)); | |
226 | } | |
227 | else | |
228 | { | |
229 | return(fseek(bfd_cache_lookup(abfd), position, direction)); | |
230 | } | |
4a81b561 DHW |
231 | } |
232 | ||
233 | long | |
536b27a5 SC |
234 | DEFUN(bfd_tell,(abfd), |
235 | bfd *abfd) | |
4a81b561 | 236 | { |
6f715d66 | 237 | file_ptr ptr; |
4a81b561 | 238 | |
6f715d66 | 239 | ptr = ftell (bfd_cache_lookup(abfd)); |
4a81b561 | 240 | |
6f715d66 SC |
241 | if (abfd->my_archive) |
242 | ptr -= abfd->origin; | |
243 | return ptr; | |
4a81b561 DHW |
244 | } |
245 | \f | |
246 | /** Make a string table */ | |
247 | ||
6f715d66 SC |
248 | /*>bfd.h< |
249 | Add string to table pointed to by table, at location starting with free_ptr. | |
4a81b561 DHW |
250 | resizes the table if necessary (if it's NULL, creates it, ignoring |
251 | table_length). Updates free_ptr, table, table_length */ | |
252 | ||
253 | boolean | |
536b27a5 SC |
254 | DEFUN(bfd_add_to_string_table,(table, new_string, table_length, free_ptr), |
255 | char **table AND | |
536b27a5 | 256 | char *new_string AND |
5ad1d830 SC |
257 | unsigned int *table_length AND |
258 | char **free_ptr) | |
4a81b561 DHW |
259 | { |
260 | size_t string_length = strlen (new_string) + 1; /* include null here */ | |
261 | char *base = *table; | |
262 | size_t space_length = *table_length; | |
263 | unsigned int offset = (base ? *free_ptr - base : 0); | |
264 | ||
265 | if (base == NULL) { | |
266 | /* Avoid a useless regrow if we can (but of course we still | |
267 | take it next time */ | |
268 | space_length = (string_length < DEFAULT_STRING_SPACE_SIZE ? | |
6f715d66 | 269 | DEFAULT_STRING_SPACE_SIZE : string_length+1); |
4a81b561 DHW |
270 | base = zalloc (space_length); |
271 | ||
272 | if (base == NULL) { | |
273 | bfd_error = no_memory; | |
274 | return false; | |
275 | } | |
276 | } | |
277 | ||
278 | if ((size_t)(offset + string_length) >= space_length) { | |
279 | /* Make sure we will have enough space */ | |
280 | while ((size_t)(offset + string_length) >= space_length) | |
281 | space_length += space_length/2; /* grow by 50% */ | |
282 | ||
283 | base = (char *) realloc (base, space_length); | |
284 | if (base == NULL) { | |
285 | bfd_error = no_memory; | |
286 | return false; | |
287 | } | |
288 | ||
289 | } | |
290 | ||
291 | memcpy (base + offset, new_string, string_length); | |
292 | *table = base; | |
293 | *table_length = space_length; | |
294 | *free_ptr = base + offset + string_length; | |
295 | ||
296 | return true; | |
297 | } | |
298 | \f | |
299 | /** The do-it-yourself (byte) sex-change kit */ | |
300 | ||
301 | /* The middle letter e.g. get<b>short indicates Big or Little endian | |
302 | target machine. It doesn't matter what the byte order of the host | |
303 | machine is; these routines work for either. */ | |
304 | ||
305 | /* FIXME: Should these take a count argument? | |
306 | Answer ([email protected]): No, but perhaps they should be inline | |
6f715d66 SC |
307 | functions in swap.h #ifdef __GNUC__. |
308 | Gprof them later and find out. */ | |
309 | ||
310 | /*proto* | |
311 | *i bfd_put_size | |
312 | *i bfd_get_size | |
313 | These macros as used for reading and writing raw data in sections; | |
314 | each access (except for bytes) is vectored through the target format | |
f58809fd | 315 | of the BFD and mangled accordingly. The mangling performs any |
6f715d66 SC |
316 | necessary endian translations and removes alignment restrictions. |
317 | *+ | |
318 | #define bfd_put_8(abfd, val, ptr) \ | |
319 | (*((char *)ptr) = (char)val) | |
320 | #define bfd_get_8(abfd, ptr) \ | |
321 | (*((char *)ptr)) | |
322 | #define bfd_put_16(abfd, val, ptr) \ | |
323 | BFD_SEND(abfd, bfd_putx16, (val,ptr)) | |
324 | #define bfd_get_16(abfd, ptr) \ | |
325 | BFD_SEND(abfd, bfd_getx16, (ptr)) | |
326 | #define bfd_put_32(abfd, val, ptr) \ | |
327 | BFD_SEND(abfd, bfd_putx32, (val,ptr)) | |
328 | #define bfd_get_32(abfd, ptr) \ | |
329 | BFD_SEND(abfd, bfd_getx32, (ptr)) | |
330 | #define bfd_put_64(abfd, val, ptr) \ | |
331 | BFD_SEND(abfd, bfd_putx64, (val, ptr)) | |
332 | #define bfd_get_64(abfd, ptr) \ | |
333 | BFD_SEND(abfd, bfd_getx64, (ptr)) | |
334 | *- | |
335 | *-*/ | |
336 | ||
337 | /*proto* | |
338 | *i bfd_h_put_size | |
339 | *i bfd_h_get_size | |
340 | These macros have the same function as their @code{bfd_get_x} | |
341 | bretherin, except that they are used for removing information for the | |
342 | header records of object files. Believe it or not, some object files | |
343 | keep their header records in big endian order, and their data in little | |
344 | endan order. | |
345 | *+ | |
346 | #define bfd_h_put_8(abfd, val, ptr) \ | |
347 | (*((char *)ptr) = (char)val) | |
348 | #define bfd_h_get_8(abfd, ptr) \ | |
349 | (*((char *)ptr)) | |
350 | #define bfd_h_put_16(abfd, val, ptr) \ | |
351 | BFD_SEND(abfd, bfd_h_putx16,(val,ptr)) | |
352 | #define bfd_h_get_16(abfd, ptr) \ | |
353 | BFD_SEND(abfd, bfd_h_getx16,(ptr)) | |
354 | #define bfd_h_put_32(abfd, val, ptr) \ | |
355 | BFD_SEND(abfd, bfd_h_putx32,(val,ptr)) | |
356 | #define bfd_h_get_32(abfd, ptr) \ | |
357 | BFD_SEND(abfd, bfd_h_getx32,(ptr)) | |
358 | #define bfd_h_put_64(abfd, val, ptr) \ | |
359 | BFD_SEND(abfd, bfd_h_putx64,(val, ptr)) | |
360 | #define bfd_h_get_64(abfd, ptr) \ | |
361 | BFD_SEND(abfd, bfd_h_getx64,(ptr)) | |
362 | *- | |
363 | *-*/ | |
4a81b561 | 364 | |
f58809fd | 365 | bfd_vma |
536b27a5 SC |
366 | DEFUN(_do_getb16,(addr), |
367 | register bfd_byte *addr) | |
4a81b561 | 368 | { |
6f715d66 | 369 | return (addr[0] << 8) | addr[1]; |
4a81b561 DHW |
370 | } |
371 | ||
f58809fd | 372 | bfd_vma |
536b27a5 SC |
373 | DEFUN(_do_getl16,(addr), |
374 | register bfd_byte *addr) | |
4a81b561 | 375 | { |
6f715d66 | 376 | return (addr[1] << 8) | addr[0]; |
4a81b561 DHW |
377 | } |
378 | ||
379 | void | |
536b27a5 | 380 | DEFUN(_do_putb16,(data, addr), |
f58809fd | 381 | bfd_vma data AND |
536b27a5 | 382 | register bfd_byte *addr) |
4a81b561 | 383 | { |
6f715d66 SC |
384 | addr[0] = (bfd_byte)(data >> 8); |
385 | addr[1] = (bfd_byte )data; | |
4a81b561 DHW |
386 | } |
387 | ||
388 | void | |
536b27a5 | 389 | DEFUN(_do_putl16,(data, addr), |
f58809fd | 390 | bfd_vma data AND |
536b27a5 | 391 | register bfd_byte *addr) |
4a81b561 | 392 | { |
6f715d66 SC |
393 | addr[0] = (bfd_byte )data; |
394 | addr[1] = (bfd_byte)(data >> 8); | |
4a81b561 DHW |
395 | } |
396 | ||
f58809fd | 397 | bfd_vma |
536b27a5 SC |
398 | DEFUN(_do_getb32,(addr), |
399 | register bfd_byte *addr) | |
4a81b561 | 400 | { |
6f715d66 | 401 | return ((((addr[0] << 8) | addr[1]) << 8) | addr[2]) << 8 | addr[3]; |
4a81b561 DHW |
402 | } |
403 | ||
f58809fd | 404 | bfd_vma |
7ed4093a | 405 | _do_getl32 (addr) |
6f715d66 | 406 | register bfd_byte *addr; |
4a81b561 | 407 | { |
6f715d66 | 408 | return ((((addr[3] << 8) | addr[2]) << 8) | addr[1]) << 8 | addr[0]; |
4a81b561 DHW |
409 | } |
410 | ||
f58809fd | 411 | bfd_vma |
536b27a5 SC |
412 | DEFUN(_do_getb64,(addr), |
413 | register bfd_byte *addr) | |
7ed4093a | 414 | { |
536b27a5 | 415 | #ifdef HOST_64_BIT |
7ed4093a | 416 | bfd_64_type low, high; |
536b27a5 | 417 | |
7ed4093a | 418 | high= ((((((((addr[0]) << 8) | |
6f715d66 SC |
419 | addr[1]) << 8) | |
420 | addr[2]) << 8) | | |
421 | addr[3]) ); | |
7ed4093a SC |
422 | |
423 | low = ((((((((addr[4]) << 8) | | |
6f715d66 SC |
424 | addr[5]) << 8) | |
425 | addr[6]) << 8) | | |
426 | addr[7])); | |
7ed4093a SC |
427 | |
428 | return high << 32 | low; | |
429 | #else | |
430 | BFD_FAIL(); | |
f58809fd | 431 | return 0; |
7ed4093a SC |
432 | #endif |
433 | ||
434 | } | |
435 | ||
f58809fd | 436 | bfd_vma |
5ad1d830 | 437 | DEFUN(_do_getl64,(addr), |
536b27a5 | 438 | register bfd_byte *addr) |
7ed4093a | 439 | { |
6f715d66 | 440 | |
536b27a5 | 441 | #ifdef HOST_64_BIT |
6f715d66 | 442 | bfd_64_type low, high; |
7ed4093a | 443 | high= (((((((addr[7] << 8) | |
6f715d66 SC |
444 | addr[6]) << 8) | |
445 | addr[5]) << 8) | | |
446 | addr[4])); | |
7ed4093a SC |
447 | |
448 | low = (((((((addr[3] << 8) | | |
6f715d66 SC |
449 | addr[2]) << 8) | |
450 | addr[1]) << 8) | | |
451 | addr[0]) ); | |
7ed4093a SC |
452 | |
453 | return high << 32 | low; | |
454 | #else | |
455 | BFD_FAIL(); | |
f58809fd | 456 | return 0; |
7ed4093a | 457 | #endif |
6f715d66 | 458 | |
7ed4093a SC |
459 | } |
460 | ||
4a81b561 | 461 | void |
536b27a5 | 462 | DEFUN(_do_putb32,(data, addr), |
f58809fd | 463 | bfd_vma data AND |
536b27a5 | 464 | register bfd_byte *addr) |
4a81b561 | 465 | { |
6f715d66 SC |
466 | addr[0] = (bfd_byte)(data >> 24); |
467 | addr[1] = (bfd_byte)(data >> 16); | |
468 | addr[2] = (bfd_byte)(data >> 8); | |
469 | addr[3] = (bfd_byte)data; | |
4a81b561 DHW |
470 | } |
471 | ||
472 | void | |
536b27a5 | 473 | DEFUN(_do_putl32,(data, addr), |
f58809fd | 474 | bfd_vma data AND |
536b27a5 | 475 | register bfd_byte *addr) |
4a81b561 | 476 | { |
6f715d66 SC |
477 | addr[0] = (bfd_byte)data; |
478 | addr[1] = (bfd_byte)(data >> 8); | |
479 | addr[2] = (bfd_byte)(data >> 16); | |
480 | addr[3] = (bfd_byte)(data >> 24); | |
4a81b561 | 481 | } |
7ed4093a | 482 | void |
536b27a5 | 483 | DEFUN(_do_putb64,(data, addr), |
f58809fd | 484 | bfd_vma data AND |
6f715d66 | 485 | register bfd_byte *addr) |
7ed4093a | 486 | { |
536b27a5 SC |
487 | #ifdef HOST_64_BIT |
488 | addr[0] = (bfd_byte)(data >> (7*8)); | |
489 | addr[1] = (bfd_byte)(data >> (6*8)); | |
490 | addr[2] = (bfd_byte)(data >> (5*8)); | |
491 | addr[3] = (bfd_byte)(data >> (4*8)); | |
492 | addr[4] = (bfd_byte)(data >> (3*8)); | |
493 | addr[5] = (bfd_byte)(data >> (2*8)); | |
494 | addr[6] = (bfd_byte)(data >> (1*8)); | |
495 | addr[7] = (bfd_byte)(data >> (0*8)); | |
7ed4093a | 496 | #else |
536b27a5 | 497 | BFD_FAIL(); |
7ed4093a SC |
498 | #endif |
499 | ||
500 | } | |
501 | ||
502 | void | |
536b27a5 | 503 | DEFUN(_do_putl64,(data, addr), |
f58809fd | 504 | bfd_vma data AND |
536b27a5 | 505 | register bfd_byte *addr) |
7ed4093a | 506 | { |
536b27a5 SC |
507 | #ifdef HOST_64_BIT |
508 | addr[7] = (bfd_byte)(data >> (7*8)); | |
509 | addr[6] = (bfd_byte)(data >> (6*8)); | |
510 | addr[5] = (bfd_byte)(data >> (5*8)); | |
511 | addr[4] = (bfd_byte)(data >> (4*8)); | |
512 | addr[3] = (bfd_byte)(data >> (3*8)); | |
513 | addr[2] = (bfd_byte)(data >> (2*8)); | |
514 | addr[1] = (bfd_byte)(data >> (1*8)); | |
515 | addr[0] = (bfd_byte)(data >> (0*8)); | |
7ed4093a | 516 | #else |
536b27a5 | 517 | BFD_FAIL(); |
7ed4093a SC |
518 | #endif |
519 | ||
520 | } | |
521 | ||
2203f786 JG |
522 | \f |
523 | /* Default implementation */ | |
4a81b561 | 524 | |
2203f786 | 525 | boolean |
7ed4093a SC |
526 | DEFUN(bfd_generic_get_section_contents, (abfd, section, location, offset, count), |
527 | bfd *abfd AND | |
528 | sec_ptr section AND | |
529 | PTR location AND | |
530 | file_ptr offset AND | |
531 | bfd_size_type count) | |
2203f786 JG |
532 | { |
533 | if (count == 0) | |
6f715d66 | 534 | return true; |
f58809fd | 535 | if ((bfd_size_type)(offset+count) > section->size |
6f715d66 SC |
536 | || bfd_seek(abfd,(file_ptr)( section->filepos + offset), SEEK_SET) == -1 |
537 | || bfd_read(location, (bfd_size_type)1, count, abfd) != count) | |
538 | return (false); /* on error */ | |
2203f786 JG |
539 | return (true); |
540 | } | |
6f715d66 | 541 | |
f58809fd SC |
542 | /* This generic function can only be used in implementations where creating |
543 | NEW sections is disallowed. It is useful in patching existing sections | |
544 | in read-write files, though. See other set_section_contents functions | |
545 | to see why it doesn't work for new sections. */ | |
546 | boolean | |
547 | DEFUN(bfd_generic_set_section_contents, (abfd, section, location, offset, count), | |
548 | bfd *abfd AND | |
549 | sec_ptr section AND | |
550 | PTR location AND | |
551 | file_ptr offset AND | |
552 | bfd_size_type count) | |
553 | { | |
554 | if (count == 0) | |
555 | return true; | |
556 | if ((bfd_size_type)(offset+count) > section->size | |
557 | || bfd_seek(abfd, (file_ptr)(section->filepos + offset), SEEK_SET) == -1 | |
558 | || bfd_write(location, (bfd_size_type)1, count, abfd) != count) | |
559 | return (false); /* on error */ | |
560 | return (true); | |
561 | } | |
562 | ||
6f715d66 SC |
563 | /*proto-internal* |
564 | *i bfd_log2 | |
565 | Return the log base 2 of the value supplied, rounded up. eg an arg | |
566 | of 1025 would return 11. | |
567 | *; PROTO(bfd_vma, bfd_log2,(bfd_vma x)); | |
568 | *-*/ | |
569 | ||
570 | bfd_vma bfd_log2(x) | |
571 | bfd_vma x; | |
572 | { | |
573 | bfd_vma result = 0; | |
574 | while ( (bfd_vma)(1<< result) < x) | |
575 | result++; | |
576 | return result; | |
577 | } |