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-2021 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;
120
121 /* PR 25713: Handle extra long path names.
122 For relative paths, convert them to absolute, in case that version is too long. */
123 if (! IS_ABSOLUTE_PATH (filename) && (strstr (filename, ".o") != NULL))
124 {
125 char cwd[1024];
126
127 getcwd (cwd, sizeof (cwd));
128 filelen = strlen (cwd) + 1;
129 strncat (cwd, "\\", sizeof (cwd) - filelen);
130 ++ filelen;
131 strncat (cwd, filename, sizeof (cwd) - filelen);
132
133 filename = cwd;
134 }
135
136 filelen = strlen (filename) + 1;
137
138 if (filelen > MAX_PATH - 1)
139 {
140 FILE * file;
141 char * fullpath;
142 int i;
143
144 fullpath = (char *) malloc (filelen + 8);
145
146 /* Add a Microsoft recommended prefix that
147 will allow the extra-long path to work. */
148 strcpy (fullpath, "\\\\?\\");
149 strcat (fullpath, filename);
150
151 /* Convert any UNIX style path separators into the DOS form. */
152 for (i = 0; fullpath[i]; i++)
153 {
154 if (IS_UNIX_DIR_SEPARATOR (fullpath[i]))
155 fullpath[i] = '\\';
156 }
157
158 file = close_on_exec (fopen (fullpath, modes));
159 free (fullpath);
160 return file;
161 }
162
163 #elif defined (HAVE_FOPEN64)
164 return close_on_exec (fopen64 (filename, modes));
165 #endif
166
167 return close_on_exec (fopen (filename, modes));
168 }
169
170 /*
171 INTERNAL_DEFINITION
172 struct bfd_iovec
173
174 DESCRIPTION
175
176 The <<struct bfd_iovec>> contains the internal file I/O class.
177 Each <<BFD>> has an instance of this class and all file I/O is
178 routed through it (it is assumed that the instance implements
179 all methods listed below).
180
181 .struct bfd_iovec
182 .{
183 . {* To avoid problems with macros, a "b" rather than "f"
184 . prefix is prepended to each method name. *}
185 . {* Attempt to read/write NBYTES on ABFD's IOSTREAM storing/fetching
186 . bytes starting at PTR. Return the number of bytes actually
187 . transfered (a read past end-of-file returns less than NBYTES),
188 . or -1 (setting <<bfd_error>>) if an error occurs. *}
189 . file_ptr (*bread) (struct bfd *abfd, void *ptr, file_ptr nbytes);
190 . file_ptr (*bwrite) (struct bfd *abfd, const void *ptr,
191 . file_ptr nbytes);
192 . {* Return the current IOSTREAM file offset, or -1 (setting <<bfd_error>>
193 . if an error occurs. *}
194 . file_ptr (*btell) (struct bfd *abfd);
195 . {* For the following, on successful completion a value of 0 is returned.
196 . Otherwise, a value of -1 is returned (and <<bfd_error>> is set). *}
197 . int (*bseek) (struct bfd *abfd, file_ptr offset, int whence);
198 . int (*bclose) (struct bfd *abfd);
199 . int (*bflush) (struct bfd *abfd);
200 . int (*bstat) (struct bfd *abfd, struct stat *sb);
201 . {* Mmap a part of the files. ADDR, LEN, PROT, FLAGS and OFFSET are the usual
202 . mmap parameter, except that LEN and OFFSET do not need to be page
203 . aligned. Returns (void *)-1 on failure, mmapped address on success.
204 . Also write in MAP_ADDR the address of the page aligned buffer and in
205 . MAP_LEN the size mapped (a page multiple). Use unmap with MAP_ADDR and
206 . MAP_LEN to unmap. *}
207 . void *(*bmmap) (struct bfd *abfd, void *addr, bfd_size_type len,
208 . int prot, int flags, file_ptr offset,
209 . void **map_addr, bfd_size_type *map_len);
210 .};
211
212 .extern const struct bfd_iovec _bfd_memory_iovec;
213
214 */
215
216
217 /* Return value is amount read. */
218
219 bfd_size_type
220 bfd_bread (void *ptr, bfd_size_type size, bfd *abfd)
221 {
222 file_ptr nread;
223 bfd *element_bfd = abfd;
224 ufile_ptr offset = 0;
225
226 while (abfd->my_archive != NULL
227 && !bfd_is_thin_archive (abfd->my_archive))
228 {
229 offset += abfd->origin;
230 abfd = abfd->my_archive;
231 }
232 offset += abfd->origin;
233
234 /* If this is an archive element, don't read past the end of
235 this element. */
236 if (element_bfd->arelt_data != NULL)
237 {
238 bfd_size_type maxbytes = arelt_size (element_bfd);
239
240 if (abfd->where < offset || abfd->where - offset >= maxbytes)
241 {
242 bfd_set_error (bfd_error_invalid_operation);
243 return -1;
244 }
245 if (abfd->where - offset + size > maxbytes)
246 size = maxbytes - (abfd->where - offset);
247 }
248
249 if (abfd->iovec == NULL)
250 {
251 bfd_set_error (bfd_error_invalid_operation);
252 return -1;
253 }
254
255 nread = abfd->iovec->bread (abfd, ptr, size);
256 if (nread != -1)
257 abfd->where += nread;
258
259 return nread;
260 }
261
262 bfd_size_type
263 bfd_bwrite (const void *ptr, bfd_size_type size, bfd *abfd)
264 {
265 file_ptr nwrote;
266
267 while (abfd->my_archive != NULL
268 && !bfd_is_thin_archive (abfd->my_archive))
269 abfd = abfd->my_archive;
270
271 if (abfd->iovec == NULL)
272 {
273 bfd_set_error (bfd_error_invalid_operation);
274 return -1;
275 }
276
277 nwrote = abfd->iovec->bwrite (abfd, ptr, size);
278 if (nwrote != -1)
279 abfd->where += nwrote;
280 if ((bfd_size_type) nwrote != size)
281 {
282 #ifdef ENOSPC
283 errno = ENOSPC;
284 #endif
285 bfd_set_error (bfd_error_system_call);
286 }
287 return nwrote;
288 }
289
290 file_ptr
291 bfd_tell (bfd *abfd)
292 {
293 ufile_ptr offset = 0;
294 file_ptr ptr;
295
296 while (abfd->my_archive != NULL
297 && !bfd_is_thin_archive (abfd->my_archive))
298 {
299 offset += abfd->origin;
300 abfd = abfd->my_archive;
301 }
302 offset += abfd->origin;
303
304 if (abfd->iovec == NULL)
305 return 0;
306
307 ptr = abfd->iovec->btell (abfd);
308 abfd->where = ptr;
309 return ptr - offset;
310 }
311
312 int
313 bfd_flush (bfd *abfd)
314 {
315 while (abfd->my_archive != NULL
316 && !bfd_is_thin_archive (abfd->my_archive))
317 abfd = abfd->my_archive;
318
319 if (abfd->iovec == NULL)
320 return 0;
321
322 return abfd->iovec->bflush (abfd);
323 }
324
325 /* Returns 0 for success, negative value for failure (in which case
326 bfd_get_error can retrieve the error code). */
327 int
328 bfd_stat (bfd *abfd, struct stat *statbuf)
329 {
330 int result;
331
332 while (abfd->my_archive != NULL
333 && !bfd_is_thin_archive (abfd->my_archive))
334 abfd = abfd->my_archive;
335
336 if (abfd->iovec == NULL)
337 {
338 bfd_set_error (bfd_error_invalid_operation);
339 return -1;
340 }
341
342 result = abfd->iovec->bstat (abfd, statbuf);
343 if (result < 0)
344 bfd_set_error (bfd_error_system_call);
345 return result;
346 }
347
348 /* Returns 0 for success, nonzero for failure (in which case bfd_get_error
349 can retrieve the error code). */
350
351 int
352 bfd_seek (bfd *abfd, file_ptr position, int direction)
353 {
354 int result;
355 ufile_ptr offset = 0;
356
357 while (abfd->my_archive != NULL
358 && !bfd_is_thin_archive (abfd->my_archive))
359 {
360 offset += abfd->origin;
361 abfd = abfd->my_archive;
362 }
363 offset += abfd->origin;
364
365 if (abfd->iovec == NULL)
366 {
367 bfd_set_error (bfd_error_invalid_operation);
368 return -1;
369 }
370
371 /* For the time being, a BFD may not seek to it's end. The problem
372 is that we don't easily have a way to recognize the end of an
373 element in an archive. */
374 BFD_ASSERT (direction == SEEK_SET || direction == SEEK_CUR);
375
376 if (direction != SEEK_CUR)
377 position += offset;
378
379 if ((direction == SEEK_CUR && position == 0)
380 || (direction == SEEK_SET && (ufile_ptr) position == abfd->where))
381 return 0;
382
383 result = abfd->iovec->bseek (abfd, position, direction);
384 if (result != 0)
385 {
386 /* An EINVAL error probably means that the file offset was
387 absurd. */
388 if (errno == EINVAL)
389 bfd_set_error (bfd_error_file_truncated);
390 else
391 bfd_set_error (bfd_error_system_call);
392 }
393 else
394 {
395 /* Adjust `where' field. */
396 if (direction == SEEK_CUR)
397 abfd->where += position;
398 else
399 abfd->where = position;
400 }
401
402 return result;
403 }
404
405 /*
406 FUNCTION
407 bfd_get_mtime
408
409 SYNOPSIS
410 long bfd_get_mtime (bfd *abfd);
411
412 DESCRIPTION
413 Return the file modification time (as read from the file system, or
414 from the archive header for archive members).
415
416 */
417
418 long
419 bfd_get_mtime (bfd *abfd)
420 {
421 struct stat buf;
422
423 if (abfd->mtime_set)
424 return abfd->mtime;
425
426 if (bfd_stat (abfd, &buf) != 0)
427 return 0;
428
429 abfd->mtime = buf.st_mtime; /* Save value in case anyone wants it */
430 return buf.st_mtime;
431 }
432
433 /*
434 FUNCTION
435 bfd_get_size
436
437 SYNOPSIS
438 ufile_ptr bfd_get_size (bfd *abfd);
439
440 DESCRIPTION
441 Return the file size (as read from file system) for the file
442 associated with BFD @var{abfd}.
443
444 The initial motivation for, and use of, this routine is not
445 so we can get the exact size of the object the BFD applies to, since
446 that might not be generally possible (archive members for example).
447 It would be ideal if someone could eventually modify
448 it so that such results were guaranteed.
449
450 Instead, we want to ask questions like "is this NNN byte sized
451 object I'm about to try read from file offset YYY reasonable?"
452 As as example of where we might do this, some object formats
453 use string tables for which the first <<sizeof (long)>> bytes of the
454 table contain the size of the table itself, including the size bytes.
455 If an application tries to read what it thinks is one of these
456 string tables, without some way to validate the size, and for
457 some reason the size is wrong (byte swapping error, wrong location
458 for the string table, etc.), the only clue is likely to be a read
459 error when it tries to read the table, or a "virtual memory
460 exhausted" error when it tries to allocate 15 bazillon bytes
461 of space for the 15 bazillon byte table it is about to read.
462 This function at least allows us to answer the question, "is the
463 size reasonable?".
464
465 A return value of zero indicates the file size is unknown.
466 */
467
468 ufile_ptr
469 bfd_get_size (bfd *abfd)
470 {
471 /* A size of 0 means we haven't yet called bfd_stat. A size of 1
472 means we have a cached value of 0, ie. unknown. */
473 if (abfd->size <= 1 || bfd_write_p (abfd))
474 {
475 struct stat buf;
476
477 if (abfd->size == 1 && !bfd_write_p (abfd))
478 return 0;
479
480 if (bfd_stat (abfd, &buf) != 0
481 || buf.st_size == 0
482 || buf.st_size - (ufile_ptr) buf.st_size != 0)
483 {
484 abfd->size = 1;
485 return 0;
486 }
487 abfd->size = buf.st_size;
488 }
489 return abfd->size;
490 }
491
492 /*
493 FUNCTION
494 bfd_get_file_size
495
496 SYNOPSIS
497 ufile_ptr bfd_get_file_size (bfd *abfd);
498
499 DESCRIPTION
500 Return the file size (as read from file system) for the file
501 associated with BFD @var{abfd}. It supports both normal files
502 and archive elements.
503
504 */
505
506 ufile_ptr
507 bfd_get_file_size (bfd *abfd)
508 {
509 ufile_ptr file_size, archive_size = (ufile_ptr) -1;
510
511 if (abfd->my_archive != NULL
512 && !bfd_is_thin_archive (abfd->my_archive))
513 {
514 struct areltdata *adata = (struct areltdata *) abfd->arelt_data;
515 if (adata != NULL)
516 {
517 archive_size = adata->parsed_size;
518 /* If the archive is compressed we can't compare against
519 file size. */
520 if (adata->arch_header != NULL
521 && memcmp (((struct ar_hdr *) adata->arch_header)->ar_fmag,
522 "Z\012", 2) == 0)
523 return archive_size;
524 abfd = abfd->my_archive;
525 }
526 }
527
528 file_size = bfd_get_size (abfd);
529 if (archive_size < file_size)
530 return archive_size;
531 return file_size;
532 }
533
534 /*
535 FUNCTION
536 bfd_mmap
537
538 SYNOPSIS
539 void *bfd_mmap (bfd *abfd, void *addr, bfd_size_type len,
540 int prot, int flags, file_ptr offset,
541 void **map_addr, bfd_size_type *map_len);
542
543 DESCRIPTION
544 Return mmap()ed region of the file, if possible and implemented.
545 LEN and OFFSET do not need to be page aligned. The page aligned
546 address and length are written to MAP_ADDR and MAP_LEN.
547
548 */
549
550 void *
551 bfd_mmap (bfd *abfd, void *addr, bfd_size_type len,
552 int prot, int flags, file_ptr offset,
553 void **map_addr, bfd_size_type *map_len)
554 {
555 while (abfd->my_archive != NULL
556 && !bfd_is_thin_archive (abfd->my_archive))
557 {
558 offset += abfd->origin;
559 abfd = abfd->my_archive;
560 }
561 offset += abfd->origin;
562
563 if (abfd->iovec == NULL)
564 {
565 bfd_set_error (bfd_error_invalid_operation);
566 return (void *) -1;
567 }
568
569 return abfd->iovec->bmmap (abfd, addr, len, prot, flags, offset,
570 map_addr, map_len);
571 }
572
573 /* Memory file I/O operations. */
574
575 static file_ptr
576 memory_bread (bfd *abfd, void *ptr, file_ptr size)
577 {
578 struct bfd_in_memory *bim;
579 bfd_size_type get;
580
581 bim = (struct bfd_in_memory *) abfd->iostream;
582 get = size;
583 if (abfd->where + get > bim->size)
584 {
585 if (bim->size < (bfd_size_type) abfd->where)
586 get = 0;
587 else
588 get = bim->size - abfd->where;
589 bfd_set_error (bfd_error_file_truncated);
590 }
591 memcpy (ptr, bim->buffer + abfd->where, (size_t) get);
592 return get;
593 }
594
595 static file_ptr
596 memory_bwrite (bfd *abfd, const void *ptr, file_ptr size)
597 {
598 struct bfd_in_memory *bim = (struct bfd_in_memory *) abfd->iostream;
599
600 if (abfd->where + size > bim->size)
601 {
602 bfd_size_type newsize, oldsize;
603
604 oldsize = (bim->size + 127) & ~(bfd_size_type) 127;
605 bim->size = abfd->where + size;
606 /* Round up to cut down on memory fragmentation */
607 newsize = (bim->size + 127) & ~(bfd_size_type) 127;
608 if (newsize > oldsize)
609 {
610 bim->buffer = (bfd_byte *) bfd_realloc_or_free (bim->buffer, newsize);
611 if (bim->buffer == NULL)
612 {
613 bim->size = 0;
614 return 0;
615 }
616 if (newsize > bim->size)
617 memset (bim->buffer + bim->size, 0, newsize - bim->size);
618 }
619 }
620 memcpy (bim->buffer + abfd->where, ptr, (size_t) size);
621 return size;
622 }
623
624 static file_ptr
625 memory_btell (bfd *abfd)
626 {
627 return abfd->where;
628 }
629
630 static int
631 memory_bseek (bfd *abfd, file_ptr position, int direction)
632 {
633 file_ptr nwhere;
634 struct bfd_in_memory *bim;
635
636 bim = (struct bfd_in_memory *) abfd->iostream;
637
638 if (direction == SEEK_SET)
639 nwhere = position;
640 else
641 nwhere = abfd->where + position;
642
643 if (nwhere < 0)
644 {
645 abfd->where = 0;
646 errno = EINVAL;
647 return -1;
648 }
649
650 if ((bfd_size_type)nwhere > bim->size)
651 {
652 if (abfd->direction == write_direction
653 || abfd->direction == both_direction)
654 {
655 bfd_size_type newsize, oldsize;
656
657 oldsize = (bim->size + 127) & ~(bfd_size_type) 127;
658 bim->size = nwhere;
659 /* Round up to cut down on memory fragmentation */
660 newsize = (bim->size + 127) & ~(bfd_size_type) 127;
661 if (newsize > oldsize)
662 {
663 bim->buffer = (bfd_byte *) bfd_realloc_or_free (bim->buffer, newsize);
664 if (bim->buffer == NULL)
665 {
666 errno = EINVAL;
667 bim->size = 0;
668 return -1;
669 }
670 memset (bim->buffer + oldsize, 0, newsize - oldsize);
671 }
672 }
673 else
674 {
675 abfd->where = bim->size;
676 errno = EINVAL;
677 bfd_set_error (bfd_error_file_truncated);
678 return -1;
679 }
680 }
681 return 0;
682 }
683
684 static int
685 memory_bclose (struct bfd *abfd)
686 {
687 struct bfd_in_memory *bim = (struct bfd_in_memory *) abfd->iostream;
688
689 free (bim->buffer);
690 free (bim);
691 abfd->iostream = NULL;
692
693 return 0;
694 }
695
696 static int
697 memory_bflush (bfd *abfd ATTRIBUTE_UNUSED)
698 {
699 return 0;
700 }
701
702 static int
703 memory_bstat (bfd *abfd, struct stat *statbuf)
704 {
705 struct bfd_in_memory *bim = (struct bfd_in_memory *) abfd->iostream;
706
707 memset (statbuf, 0, sizeof (*statbuf));
708 statbuf->st_size = bim->size;
709
710 return 0;
711 }
712
713 static void *
714 memory_bmmap (bfd *abfd ATTRIBUTE_UNUSED, void *addr ATTRIBUTE_UNUSED,
715 bfd_size_type len ATTRIBUTE_UNUSED, int prot ATTRIBUTE_UNUSED,
716 int flags ATTRIBUTE_UNUSED, file_ptr offset ATTRIBUTE_UNUSED,
717 void **map_addr ATTRIBUTE_UNUSED,
718 bfd_size_type *map_len ATTRIBUTE_UNUSED)
719 {
720 return (void *)-1;
721 }
722
723 const struct bfd_iovec _bfd_memory_iovec =
724 {
725 &memory_bread, &memory_bwrite, &memory_btell, &memory_bseek,
726 &memory_bclose, &memory_bflush, &memory_bstat, &memory_bmmap
727 };
This page took 0.043339 seconds and 4 git commands to generate.