Automatic date update in version.in
[deliverable/binutils-gdb.git] / bfd / bfdio.c
1 /* Low-level I/O routines for BFDs.
2
3 Copyright (C) 1990-2020 Free Software Foundation, Inc.
4
5 Written by Cygnus Support.
6
7 This file is part of BFD, the Binary File Descriptor library.
8
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 3 of the License, or
12 (at your option) any later version.
13
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.
18
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., 51 Franklin Street - Fifth Floor, Boston,
22 MA 02110-1301, USA. */
23
24 #include "sysdep.h"
25 #include <limits.h>
26 #include "bfd.h"
27 #include "libbfd.h"
28 #include "aout/ar.h"
29 #if defined (_WIN32)
30 #include <windows.h>
31 #endif
32
33 #ifndef S_IXUSR
34 #define S_IXUSR 0100 /* Execute by owner. */
35 #endif
36 #ifndef S_IXGRP
37 #define S_IXGRP 0010 /* Execute by group. */
38 #endif
39 #ifndef S_IXOTH
40 #define S_IXOTH 0001 /* Execute by others. */
41 #endif
42
43 #ifndef FD_CLOEXEC
44 #define FD_CLOEXEC 1
45 #endif
46
47 file_ptr
48 _bfd_real_ftell (FILE *file)
49 {
50 #if defined (HAVE_FTELLO64)
51 return ftello64 (file);
52 #elif defined (HAVE_FTELLO)
53 return ftello (file);
54 #else
55 return ftell (file);
56 #endif
57 }
58
59 int
60 _bfd_real_fseek (FILE *file, file_ptr offset, int whence)
61 {
62 #if defined (HAVE_FSEEKO64)
63 return fseeko64 (file, offset, whence);
64 #elif defined (HAVE_FSEEKO)
65 return fseeko (file, offset, whence);
66 #else
67 return fseek (file, offset, whence);
68 #endif
69 }
70
71 /* Mark FILE as close-on-exec. Return FILE. FILE may be NULL, in
72 which case nothing is done. */
73 static FILE *
74 close_on_exec (FILE *file)
75 {
76 #if defined (HAVE_FILENO) && defined (F_GETFD)
77 if (file)
78 {
79 int fd = fileno (file);
80 int old = fcntl (fd, F_GETFD, 0);
81 if (old >= 0)
82 fcntl (fd, F_SETFD, old | FD_CLOEXEC);
83 }
84 #endif
85 return file;
86 }
87
88 FILE *
89 _bfd_real_fopen (const char *filename, const char *modes)
90 {
91 #ifdef VMS
92 char *vms_attr;
93
94 /* On VMS, fopen allows file attributes as optional arguments.
95 We need to use them but we'd better to use the common prototype.
96 In fopen-vms.h, they are separated from the mode with a comma.
97 Split here. */
98 vms_attr = strchr (modes, ',');
99 if (vms_attr != NULL)
100 {
101 /* Attributes found. Split. */
102 size_t modes_len = strlen (modes) + 1;
103 char attrs[modes_len + 1];
104 char *at[3];
105 int i;
106
107 memcpy (attrs, modes, modes_len);
108 at[0] = attrs;
109 for (i = 0; i < 2; i++)
110 {
111 at[i + 1] = strchr (at[i], ',');
112 BFD_ASSERT (at[i + 1] != NULL);
113 *(at[i + 1]++) = 0; /* Replace ',' with a nul, and skip it. */
114 }
115 return close_on_exec (fopen (filename, at[0], at[1], at[2]));
116 }
117
118 #elif defined (_WIN32)
119 size_t filelen = strlen (filename) + 1;
120
121 if (filelen > MAX_PATH - 1)
122 {
123 FILE *file;
124 char* fullpath = (char *) malloc (filelen + 8);
125
126 /* Add a Microsoft recommended prefix that
127 will allow the extra-long path to work. */
128 strcpy (fullpath, "\\\\?\\");
129 strcat (fullpath, filename);
130 file = close_on_exec (fopen (fullpath, modes));
131 free (fullpath);
132 return file;
133 }
134
135 #elif defined (HAVE_FOPEN64)
136 return close_on_exec (fopen64 (filename, modes));
137 #endif
138
139 return close_on_exec (fopen (filename, modes));
140 }
141
142 /*
143 INTERNAL_DEFINITION
144 struct bfd_iovec
145
146 DESCRIPTION
147
148 The <<struct bfd_iovec>> contains the internal file I/O class.
149 Each <<BFD>> has an instance of this class and all file I/O is
150 routed through it (it is assumed that the instance implements
151 all methods listed below).
152
153 .struct bfd_iovec
154 .{
155 . {* To avoid problems with macros, a "b" rather than "f"
156 . prefix is prepended to each method name. *}
157 . {* Attempt to read/write NBYTES on ABFD's IOSTREAM storing/fetching
158 . bytes starting at PTR. Return the number of bytes actually
159 . transfered (a read past end-of-file returns less than NBYTES),
160 . or -1 (setting <<bfd_error>>) if an error occurs. *}
161 . file_ptr (*bread) (struct bfd *abfd, void *ptr, file_ptr nbytes);
162 . file_ptr (*bwrite) (struct bfd *abfd, const void *ptr,
163 . file_ptr nbytes);
164 . {* Return the current IOSTREAM file offset, or -1 (setting <<bfd_error>>
165 . if an error occurs. *}
166 . file_ptr (*btell) (struct bfd *abfd);
167 . {* For the following, on successful completion a value of 0 is returned.
168 . Otherwise, a value of -1 is returned (and <<bfd_error>> is set). *}
169 . int (*bseek) (struct bfd *abfd, file_ptr offset, int whence);
170 . int (*bclose) (struct bfd *abfd);
171 . int (*bflush) (struct bfd *abfd);
172 . int (*bstat) (struct bfd *abfd, struct stat *sb);
173 . {* Mmap a part of the files. ADDR, LEN, PROT, FLAGS and OFFSET are the usual
174 . mmap parameter, except that LEN and OFFSET do not need to be page
175 . aligned. Returns (void *)-1 on failure, mmapped address on success.
176 . Also write in MAP_ADDR the address of the page aligned buffer and in
177 . MAP_LEN the size mapped (a page multiple). Use unmap with MAP_ADDR and
178 . MAP_LEN to unmap. *}
179 . void *(*bmmap) (struct bfd *abfd, void *addr, bfd_size_type len,
180 . int prot, int flags, file_ptr offset,
181 . void **map_addr, bfd_size_type *map_len);
182 .};
183
184 .extern const struct bfd_iovec _bfd_memory_iovec;
185
186 */
187
188
189 /* Return value is amount read. */
190
191 bfd_size_type
192 bfd_bread (void *ptr, bfd_size_type size, bfd *abfd)
193 {
194 file_ptr nread;
195 bfd *element_bfd = abfd;
196 ufile_ptr offset = 0;
197
198 while (abfd->my_archive != NULL
199 && !bfd_is_thin_archive (abfd->my_archive))
200 {
201 offset += abfd->origin;
202 abfd = abfd->my_archive;
203 }
204 offset += abfd->origin;
205
206 /* If this is an archive element, don't read past the end of
207 this element. */
208 if (element_bfd->arelt_data != NULL)
209 {
210 bfd_size_type maxbytes = arelt_size (element_bfd);
211
212 if (abfd->where < offset || abfd->where - offset >= maxbytes)
213 {
214 bfd_set_error (bfd_error_invalid_operation);
215 return -1;
216 }
217 if (abfd->where - offset + size > maxbytes)
218 size = maxbytes - (abfd->where - offset);
219 }
220
221 if (abfd->iovec == NULL)
222 {
223 bfd_set_error (bfd_error_invalid_operation);
224 return -1;
225 }
226
227 nread = abfd->iovec->bread (abfd, ptr, size);
228 if (nread != -1)
229 abfd->where += nread;
230
231 return nread;
232 }
233
234 bfd_size_type
235 bfd_bwrite (const void *ptr, bfd_size_type size, bfd *abfd)
236 {
237 file_ptr nwrote;
238
239 while (abfd->my_archive != NULL
240 && !bfd_is_thin_archive (abfd->my_archive))
241 abfd = abfd->my_archive;
242
243 if (abfd->iovec == NULL)
244 {
245 bfd_set_error (bfd_error_invalid_operation);
246 return -1;
247 }
248
249 nwrote = abfd->iovec->bwrite (abfd, ptr, size);
250 if (nwrote != -1)
251 abfd->where += nwrote;
252 if ((bfd_size_type) nwrote != size)
253 {
254 #ifdef ENOSPC
255 errno = ENOSPC;
256 #endif
257 bfd_set_error (bfd_error_system_call);
258 }
259 return nwrote;
260 }
261
262 file_ptr
263 bfd_tell (bfd *abfd)
264 {
265 ufile_ptr offset = 0;
266 file_ptr ptr;
267
268 while (abfd->my_archive != NULL
269 && !bfd_is_thin_archive (abfd->my_archive))
270 {
271 offset += abfd->origin;
272 abfd = abfd->my_archive;
273 }
274 offset += abfd->origin;
275
276 if (abfd->iovec == NULL)
277 return 0;
278
279 ptr = abfd->iovec->btell (abfd);
280 abfd->where = ptr;
281 return ptr - offset;
282 }
283
284 int
285 bfd_flush (bfd *abfd)
286 {
287 while (abfd->my_archive != NULL
288 && !bfd_is_thin_archive (abfd->my_archive))
289 abfd = abfd->my_archive;
290
291 if (abfd->iovec == NULL)
292 return 0;
293
294 return abfd->iovec->bflush (abfd);
295 }
296
297 /* Returns 0 for success, negative value for failure (in which case
298 bfd_get_error can retrieve the error code). */
299 int
300 bfd_stat (bfd *abfd, struct stat *statbuf)
301 {
302 int result;
303
304 while (abfd->my_archive != NULL
305 && !bfd_is_thin_archive (abfd->my_archive))
306 abfd = abfd->my_archive;
307
308 if (abfd->iovec == NULL)
309 {
310 bfd_set_error (bfd_error_invalid_operation);
311 return -1;
312 }
313
314 result = abfd->iovec->bstat (abfd, statbuf);
315 if (result < 0)
316 bfd_set_error (bfd_error_system_call);
317 return result;
318 }
319
320 /* Returns 0 for success, nonzero for failure (in which case bfd_get_error
321 can retrieve the error code). */
322
323 int
324 bfd_seek (bfd *abfd, file_ptr position, int direction)
325 {
326 int result;
327 ufile_ptr offset = 0;
328
329 while (abfd->my_archive != NULL
330 && !bfd_is_thin_archive (abfd->my_archive))
331 {
332 offset += abfd->origin;
333 abfd = abfd->my_archive;
334 }
335 offset += abfd->origin;
336
337 if (abfd->iovec == NULL)
338 {
339 bfd_set_error (bfd_error_invalid_operation);
340 return -1;
341 }
342
343 /* For the time being, a BFD may not seek to it's end. The problem
344 is that we don't easily have a way to recognize the end of an
345 element in an archive. */
346 BFD_ASSERT (direction == SEEK_SET || direction == SEEK_CUR);
347
348 if (direction != SEEK_CUR)
349 position += offset;
350
351 if ((direction == SEEK_CUR && position == 0)
352 || (direction == SEEK_SET && (ufile_ptr) position == abfd->where))
353 return 0;
354
355 result = abfd->iovec->bseek (abfd, position, direction);
356 if (result != 0)
357 {
358 /* An EINVAL error probably means that the file offset was
359 absurd. */
360 if (errno == EINVAL)
361 bfd_set_error (bfd_error_file_truncated);
362 else
363 bfd_set_error (bfd_error_system_call);
364 }
365 else
366 {
367 /* Adjust `where' field. */
368 if (direction == SEEK_CUR)
369 abfd->where += position;
370 else
371 abfd->where = position;
372 }
373
374 return result;
375 }
376
377 /*
378 FUNCTION
379 bfd_get_mtime
380
381 SYNOPSIS
382 long bfd_get_mtime (bfd *abfd);
383
384 DESCRIPTION
385 Return the file modification time (as read from the file system, or
386 from the archive header for archive members).
387
388 */
389
390 long
391 bfd_get_mtime (bfd *abfd)
392 {
393 struct stat buf;
394
395 if (abfd->mtime_set)
396 return abfd->mtime;
397
398 if (bfd_stat (abfd, &buf) != 0)
399 return 0;
400
401 abfd->mtime = buf.st_mtime; /* Save value in case anyone wants it */
402 return buf.st_mtime;
403 }
404
405 /*
406 FUNCTION
407 bfd_get_size
408
409 SYNOPSIS
410 ufile_ptr bfd_get_size (bfd *abfd);
411
412 DESCRIPTION
413 Return the file size (as read from file system) for the file
414 associated with BFD @var{abfd}.
415
416 The initial motivation for, and use of, this routine is not
417 so we can get the exact size of the object the BFD applies to, since
418 that might not be generally possible (archive members for example).
419 It would be ideal if someone could eventually modify
420 it so that such results were guaranteed.
421
422 Instead, we want to ask questions like "is this NNN byte sized
423 object I'm about to try read from file offset YYY reasonable?"
424 As as example of where we might do this, some object formats
425 use string tables for which the first <<sizeof (long)>> bytes of the
426 table contain the size of the table itself, including the size bytes.
427 If an application tries to read what it thinks is one of these
428 string tables, without some way to validate the size, and for
429 some reason the size is wrong (byte swapping error, wrong location
430 for the string table, etc.), the only clue is likely to be a read
431 error when it tries to read the table, or a "virtual memory
432 exhausted" error when it tries to allocate 15 bazillon bytes
433 of space for the 15 bazillon byte table it is about to read.
434 This function at least allows us to answer the question, "is the
435 size reasonable?".
436
437 A return value of zero indicates the file size is unknown.
438 */
439
440 ufile_ptr
441 bfd_get_size (bfd *abfd)
442 {
443 /* A size of 0 means we haven't yet called bfd_stat. A size of 1
444 means we have a cached value of 0, ie. unknown. */
445 if (abfd->size <= 1 || bfd_write_p (abfd))
446 {
447 struct stat buf;
448
449 if (abfd->size == 1 && !bfd_write_p (abfd))
450 return 0;
451
452 if (bfd_stat (abfd, &buf) != 0
453 || buf.st_size == 0
454 || buf.st_size - (ufile_ptr) buf.st_size != 0)
455 {
456 abfd->size = 1;
457 return 0;
458 }
459 abfd->size = buf.st_size;
460 }
461 return abfd->size;
462 }
463
464 /*
465 FUNCTION
466 bfd_get_file_size
467
468 SYNOPSIS
469 ufile_ptr bfd_get_file_size (bfd *abfd);
470
471 DESCRIPTION
472 Return the file size (as read from file system) for the file
473 associated with BFD @var{abfd}. It supports both normal files
474 and archive elements.
475
476 */
477
478 ufile_ptr
479 bfd_get_file_size (bfd *abfd)
480 {
481 ufile_ptr file_size, archive_size = (ufile_ptr) -1;
482
483 if (abfd->my_archive != NULL
484 && !bfd_is_thin_archive (abfd->my_archive))
485 {
486 struct areltdata *adata = (struct areltdata *) abfd->arelt_data;
487 archive_size = adata->parsed_size;
488 /* If the archive is compressed we can't compare against file size. */
489 if (memcmp (((struct ar_hdr *) adata->arch_header)->ar_fmag,
490 "Z\012", 2) == 0)
491 return archive_size;
492 abfd = abfd->my_archive;
493 }
494
495 file_size = bfd_get_size (abfd);
496 if (archive_size < file_size)
497 return archive_size;
498 return file_size;
499 }
500
501 /*
502 FUNCTION
503 bfd_mmap
504
505 SYNOPSIS
506 void *bfd_mmap (bfd *abfd, void *addr, bfd_size_type len,
507 int prot, int flags, file_ptr offset,
508 void **map_addr, bfd_size_type *map_len);
509
510 DESCRIPTION
511 Return mmap()ed region of the file, if possible and implemented.
512 LEN and OFFSET do not need to be page aligned. The page aligned
513 address and length are written to MAP_ADDR and MAP_LEN.
514
515 */
516
517 void *
518 bfd_mmap (bfd *abfd, void *addr, bfd_size_type len,
519 int prot, int flags, file_ptr offset,
520 void **map_addr, bfd_size_type *map_len)
521 {
522 while (abfd->my_archive != NULL
523 && !bfd_is_thin_archive (abfd->my_archive))
524 {
525 offset += abfd->origin;
526 abfd = abfd->my_archive;
527 }
528 offset += abfd->origin;
529
530 if (abfd->iovec == NULL)
531 {
532 bfd_set_error (bfd_error_invalid_operation);
533 return (void *) -1;
534 }
535
536 return abfd->iovec->bmmap (abfd, addr, len, prot, flags, offset,
537 map_addr, map_len);
538 }
539
540 /* Memory file I/O operations. */
541
542 static file_ptr
543 memory_bread (bfd *abfd, void *ptr, file_ptr size)
544 {
545 struct bfd_in_memory *bim;
546 bfd_size_type get;
547
548 bim = (struct bfd_in_memory *) abfd->iostream;
549 get = size;
550 if (abfd->where + get > bim->size)
551 {
552 if (bim->size < (bfd_size_type) abfd->where)
553 get = 0;
554 else
555 get = bim->size - abfd->where;
556 bfd_set_error (bfd_error_file_truncated);
557 }
558 memcpy (ptr, bim->buffer + abfd->where, (size_t) get);
559 return get;
560 }
561
562 static file_ptr
563 memory_bwrite (bfd *abfd, const void *ptr, file_ptr size)
564 {
565 struct bfd_in_memory *bim = (struct bfd_in_memory *) abfd->iostream;
566
567 if (abfd->where + size > bim->size)
568 {
569 bfd_size_type newsize, oldsize;
570
571 oldsize = (bim->size + 127) & ~(bfd_size_type) 127;
572 bim->size = abfd->where + size;
573 /* Round up to cut down on memory fragmentation */
574 newsize = (bim->size + 127) & ~(bfd_size_type) 127;
575 if (newsize > oldsize)
576 {
577 bim->buffer = (bfd_byte *) bfd_realloc_or_free (bim->buffer, newsize);
578 if (bim->buffer == NULL)
579 {
580 bim->size = 0;
581 return 0;
582 }
583 if (newsize > bim->size)
584 memset (bim->buffer + bim->size, 0, newsize - bim->size);
585 }
586 }
587 memcpy (bim->buffer + abfd->where, ptr, (size_t) size);
588 return size;
589 }
590
591 static file_ptr
592 memory_btell (bfd *abfd)
593 {
594 return abfd->where;
595 }
596
597 static int
598 memory_bseek (bfd *abfd, file_ptr position, int direction)
599 {
600 file_ptr nwhere;
601 struct bfd_in_memory *bim;
602
603 bim = (struct bfd_in_memory *) abfd->iostream;
604
605 if (direction == SEEK_SET)
606 nwhere = position;
607 else
608 nwhere = abfd->where + position;
609
610 if (nwhere < 0)
611 {
612 abfd->where = 0;
613 errno = EINVAL;
614 return -1;
615 }
616
617 if ((bfd_size_type)nwhere > bim->size)
618 {
619 if (abfd->direction == write_direction
620 || abfd->direction == both_direction)
621 {
622 bfd_size_type newsize, oldsize;
623
624 oldsize = (bim->size + 127) & ~(bfd_size_type) 127;
625 bim->size = nwhere;
626 /* Round up to cut down on memory fragmentation */
627 newsize = (bim->size + 127) & ~(bfd_size_type) 127;
628 if (newsize > oldsize)
629 {
630 bim->buffer = (bfd_byte *) bfd_realloc_or_free (bim->buffer, newsize);
631 if (bim->buffer == NULL)
632 {
633 errno = EINVAL;
634 bim->size = 0;
635 return -1;
636 }
637 memset (bim->buffer + oldsize, 0, newsize - oldsize);
638 }
639 }
640 else
641 {
642 abfd->where = bim->size;
643 errno = EINVAL;
644 bfd_set_error (bfd_error_file_truncated);
645 return -1;
646 }
647 }
648 return 0;
649 }
650
651 static int
652 memory_bclose (struct bfd *abfd)
653 {
654 struct bfd_in_memory *bim = (struct bfd_in_memory *) abfd->iostream;
655
656 if (bim->buffer != NULL)
657 free (bim->buffer);
658 free (bim);
659 abfd->iostream = NULL;
660
661 return 0;
662 }
663
664 static int
665 memory_bflush (bfd *abfd ATTRIBUTE_UNUSED)
666 {
667 return 0;
668 }
669
670 static int
671 memory_bstat (bfd *abfd, struct stat *statbuf)
672 {
673 struct bfd_in_memory *bim = (struct bfd_in_memory *) abfd->iostream;
674
675 memset (statbuf, 0, sizeof (*statbuf));
676 statbuf->st_size = bim->size;
677
678 return 0;
679 }
680
681 static void *
682 memory_bmmap (bfd *abfd ATTRIBUTE_UNUSED, void *addr ATTRIBUTE_UNUSED,
683 bfd_size_type len ATTRIBUTE_UNUSED, int prot ATTRIBUTE_UNUSED,
684 int flags ATTRIBUTE_UNUSED, file_ptr offset ATTRIBUTE_UNUSED,
685 void **map_addr ATTRIBUTE_UNUSED,
686 bfd_size_type *map_len ATTRIBUTE_UNUSED)
687 {
688 return (void *)-1;
689 }
690
691 const struct bfd_iovec _bfd_memory_iovec =
692 {
693 &memory_bread, &memory_bwrite, &memory_btell, &memory_bseek,
694 &memory_bclose, &memory_bflush, &memory_bstat, &memory_bmmap
695 };
This page took 0.042963 seconds and 4 git commands to generate.