1 /* Low-level I/O routines for BFDs.
3 Copyright (C) 1990-2021 Free Software Foundation, Inc.
5 Written by Cygnus Support.
7 This file is part of BFD, the Binary File Descriptor library.
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.
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.
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. */
34 #define S_IXUSR 0100 /* Execute by owner. */
37 #define S_IXGRP 0010 /* Execute by group. */
40 #define S_IXOTH 0001 /* Execute by others. */
48 _bfd_real_ftell (FILE *file
)
50 #if defined (HAVE_FTELLO64)
51 return ftello64 (file
);
52 #elif defined (HAVE_FTELLO)
60 _bfd_real_fseek (FILE *file
, file_ptr offset
, int whence
)
62 #if defined (HAVE_FSEEKO64)
63 return fseeko64 (file
, offset
, whence
);
64 #elif defined (HAVE_FSEEKO)
65 return fseeko (file
, offset
, whence
);
67 return fseek (file
, offset
, whence
);
71 /* Mark FILE as close-on-exec. Return FILE. FILE may be NULL, in
72 which case nothing is done. */
74 close_on_exec (FILE *file
)
76 #if defined (HAVE_FILENO) && defined (F_GETFD)
79 int fd
= fileno (file
);
80 int old
= fcntl (fd
, F_GETFD
, 0);
82 fcntl (fd
, F_SETFD
, old
| FD_CLOEXEC
);
89 _bfd_real_fopen (const char *filename
, const char *modes
)
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.
98 vms_attr
= strchr (modes
, ',');
101 /* Attributes found. Split. */
102 size_t modes_len
= strlen (modes
) + 1;
103 char attrs
[modes_len
+ 1];
107 memcpy (attrs
, modes
, modes_len
);
109 for (i
= 0; i
< 2; i
++)
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. */
115 return close_on_exec (fopen (filename
, at
[0], at
[1], at
[2]));
118 #elif defined (_WIN32)
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
))
127 getcwd (cwd
, sizeof (cwd
));
128 filelen
= strlen (cwd
) + 1;
129 strncat (cwd
, "\\", sizeof (cwd
) - filelen
);
131 strncat (cwd
, filename
, sizeof (cwd
) - filelen
);
136 filelen
= strlen (filename
) + 1;
138 if (filelen
> MAX_PATH
- 1)
144 fullpath
= (char *) malloc (filelen
+ 8);
146 /* Add a Microsoft recommended prefix that
147 will allow the extra-long path to work. */
148 strcpy (fullpath
, "\\\\?\\");
149 strcat (fullpath
, filename
);
151 /* Convert any UNIX style path separators into the DOS form. */
152 for (i
= 0; fullpath
[i
]; i
++)
154 if (IS_UNIX_DIR_SEPARATOR (fullpath
[i
]))
158 file
= close_on_exec (fopen (fullpath
, modes
));
163 #elif defined (HAVE_FOPEN64)
164 return close_on_exec (fopen64 (filename
, modes
));
167 return close_on_exec (fopen (filename
, modes
));
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).
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,
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);
212 .extern const struct bfd_iovec _bfd_memory_iovec;
217 /* Return value is amount read. */
220 bfd_bread (void *ptr
, bfd_size_type size
, bfd
*abfd
)
223 bfd
*element_bfd
= abfd
;
224 ufile_ptr offset
= 0;
226 while (abfd
->my_archive
!= NULL
227 && !bfd_is_thin_archive (abfd
->my_archive
))
229 offset
+= abfd
->origin
;
230 abfd
= abfd
->my_archive
;
232 offset
+= abfd
->origin
;
234 /* If this is an archive element, don't read past the end of
236 if (element_bfd
->arelt_data
!= NULL
)
238 bfd_size_type maxbytes
= arelt_size (element_bfd
);
240 if (abfd
->where
< offset
|| abfd
->where
- offset
>= maxbytes
)
242 bfd_set_error (bfd_error_invalid_operation
);
245 if (abfd
->where
- offset
+ size
> maxbytes
)
246 size
= maxbytes
- (abfd
->where
- offset
);
249 if (abfd
->iovec
== NULL
)
251 bfd_set_error (bfd_error_invalid_operation
);
255 nread
= abfd
->iovec
->bread (abfd
, ptr
, size
);
257 abfd
->where
+= nread
;
263 bfd_bwrite (const void *ptr
, bfd_size_type size
, bfd
*abfd
)
267 while (abfd
->my_archive
!= NULL
268 && !bfd_is_thin_archive (abfd
->my_archive
))
269 abfd
= abfd
->my_archive
;
271 if (abfd
->iovec
== NULL
)
273 bfd_set_error (bfd_error_invalid_operation
);
277 nwrote
= abfd
->iovec
->bwrite (abfd
, ptr
, size
);
279 abfd
->where
+= nwrote
;
280 if ((bfd_size_type
) nwrote
!= size
)
285 bfd_set_error (bfd_error_system_call
);
293 ufile_ptr offset
= 0;
296 while (abfd
->my_archive
!= NULL
297 && !bfd_is_thin_archive (abfd
->my_archive
))
299 offset
+= abfd
->origin
;
300 abfd
= abfd
->my_archive
;
302 offset
+= abfd
->origin
;
304 if (abfd
->iovec
== NULL
)
307 ptr
= abfd
->iovec
->btell (abfd
);
313 bfd_flush (bfd
*abfd
)
315 while (abfd
->my_archive
!= NULL
316 && !bfd_is_thin_archive (abfd
->my_archive
))
317 abfd
= abfd
->my_archive
;
319 if (abfd
->iovec
== NULL
)
322 return abfd
->iovec
->bflush (abfd
);
325 /* Returns 0 for success, negative value for failure (in which case
326 bfd_get_error can retrieve the error code). */
328 bfd_stat (bfd
*abfd
, struct stat
*statbuf
)
332 while (abfd
->my_archive
!= NULL
333 && !bfd_is_thin_archive (abfd
->my_archive
))
334 abfd
= abfd
->my_archive
;
336 if (abfd
->iovec
== NULL
)
338 bfd_set_error (bfd_error_invalid_operation
);
342 result
= abfd
->iovec
->bstat (abfd
, statbuf
);
344 bfd_set_error (bfd_error_system_call
);
348 /* Returns 0 for success, nonzero for failure (in which case bfd_get_error
349 can retrieve the error code). */
352 bfd_seek (bfd
*abfd
, file_ptr position
, int direction
)
355 ufile_ptr offset
= 0;
357 while (abfd
->my_archive
!= NULL
358 && !bfd_is_thin_archive (abfd
->my_archive
))
360 offset
+= abfd
->origin
;
361 abfd
= abfd
->my_archive
;
363 offset
+= abfd
->origin
;
365 if (abfd
->iovec
== NULL
)
367 bfd_set_error (bfd_error_invalid_operation
);
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
);
376 if (direction
!= SEEK_CUR
)
379 if ((direction
== SEEK_CUR
&& position
== 0)
380 || (direction
== SEEK_SET
&& (ufile_ptr
) position
== abfd
->where
))
383 result
= abfd
->iovec
->bseek (abfd
, position
, direction
);
386 /* An EINVAL error probably means that the file offset was
389 bfd_set_error (bfd_error_file_truncated
);
391 bfd_set_error (bfd_error_system_call
);
395 /* Adjust `where' field. */
396 if (direction
== SEEK_CUR
)
397 abfd
->where
+= position
;
399 abfd
->where
= position
;
410 long bfd_get_mtime (bfd *abfd);
413 Return the file modification time (as read from the file system, or
414 from the archive header for archive members).
419 bfd_get_mtime (bfd
*abfd
)
426 if (bfd_stat (abfd
, &buf
) != 0)
429 abfd
->mtime
= buf
.st_mtime
; /* Save value in case anyone wants it */
438 ufile_ptr bfd_get_size (bfd *abfd);
441 Return the file size (as read from file system) for the file
442 associated with BFD @var{abfd}.
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.
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
465 A return value of zero indicates the file size is unknown.
469 bfd_get_size (bfd
*abfd
)
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
))
477 if (abfd
->size
== 1 && !bfd_write_p (abfd
))
480 if (bfd_stat (abfd
, &buf
) != 0
482 || buf
.st_size
- (ufile_ptr
) buf
.st_size
!= 0)
487 abfd
->size
= buf
.st_size
;
497 ufile_ptr bfd_get_file_size (bfd *abfd);
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.
507 bfd_get_file_size (bfd
*abfd
)
509 ufile_ptr file_size
, archive_size
= (ufile_ptr
) -1;
511 if (abfd
->my_archive
!= NULL
512 && !bfd_is_thin_archive (abfd
->my_archive
))
514 struct areltdata
*adata
= (struct areltdata
*) abfd
->arelt_data
;
517 archive_size
= adata
->parsed_size
;
518 /* If the archive is compressed we can't compare against
520 if (adata
->arch_header
!= NULL
521 && memcmp (((struct ar_hdr
*) adata
->arch_header
)->ar_fmag
,
524 abfd
= abfd
->my_archive
;
528 file_size
= bfd_get_size (abfd
);
529 if (archive_size
< file_size
)
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);
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.
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
)
555 while (abfd
->my_archive
!= NULL
556 && !bfd_is_thin_archive (abfd
->my_archive
))
558 offset
+= abfd
->origin
;
559 abfd
= abfd
->my_archive
;
561 offset
+= abfd
->origin
;
563 if (abfd
->iovec
== NULL
)
565 bfd_set_error (bfd_error_invalid_operation
);
569 return abfd
->iovec
->bmmap (abfd
, addr
, len
, prot
, flags
, offset
,
573 /* Memory file I/O operations. */
576 memory_bread (bfd
*abfd
, void *ptr
, file_ptr size
)
578 struct bfd_in_memory
*bim
;
581 bim
= (struct bfd_in_memory
*) abfd
->iostream
;
583 if (abfd
->where
+ get
> bim
->size
)
585 if (bim
->size
< (bfd_size_type
) abfd
->where
)
588 get
= bim
->size
- abfd
->where
;
589 bfd_set_error (bfd_error_file_truncated
);
591 memcpy (ptr
, bim
->buffer
+ abfd
->where
, (size_t) get
);
596 memory_bwrite (bfd
*abfd
, const void *ptr
, file_ptr size
)
598 struct bfd_in_memory
*bim
= (struct bfd_in_memory
*) abfd
->iostream
;
600 if (abfd
->where
+ size
> bim
->size
)
602 bfd_size_type newsize
, oldsize
;
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
)
610 bim
->buffer
= (bfd_byte
*) bfd_realloc_or_free (bim
->buffer
, newsize
);
611 if (bim
->buffer
== NULL
)
616 if (newsize
> bim
->size
)
617 memset (bim
->buffer
+ bim
->size
, 0, newsize
- bim
->size
);
620 memcpy (bim
->buffer
+ abfd
->where
, ptr
, (size_t) size
);
625 memory_btell (bfd
*abfd
)
631 memory_bseek (bfd
*abfd
, file_ptr position
, int direction
)
634 struct bfd_in_memory
*bim
;
636 bim
= (struct bfd_in_memory
*) abfd
->iostream
;
638 if (direction
== SEEK_SET
)
641 nwhere
= abfd
->where
+ position
;
650 if ((bfd_size_type
)nwhere
> bim
->size
)
652 if (abfd
->direction
== write_direction
653 || abfd
->direction
== both_direction
)
655 bfd_size_type newsize
, oldsize
;
657 oldsize
= (bim
->size
+ 127) & ~(bfd_size_type
) 127;
659 /* Round up to cut down on memory fragmentation */
660 newsize
= (bim
->size
+ 127) & ~(bfd_size_type
) 127;
661 if (newsize
> oldsize
)
663 bim
->buffer
= (bfd_byte
*) bfd_realloc_or_free (bim
->buffer
, newsize
);
664 if (bim
->buffer
== NULL
)
670 memset (bim
->buffer
+ oldsize
, 0, newsize
- oldsize
);
675 abfd
->where
= bim
->size
;
677 bfd_set_error (bfd_error_file_truncated
);
685 memory_bclose (struct bfd
*abfd
)
687 struct bfd_in_memory
*bim
= (struct bfd_in_memory
*) abfd
->iostream
;
691 abfd
->iostream
= NULL
;
697 memory_bflush (bfd
*abfd ATTRIBUTE_UNUSED
)
703 memory_bstat (bfd
*abfd
, struct stat
*statbuf
)
705 struct bfd_in_memory
*bim
= (struct bfd_in_memory
*) abfd
->iostream
;
707 memset (statbuf
, 0, sizeof (*statbuf
));
708 statbuf
->st_size
= bim
->size
;
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
)
723 const struct bfd_iovec _bfd_memory_iovec
=
725 &memory_bread
, &memory_bwrite
, &memory_btell
, &memory_bseek
,
726 &memory_bclose
, &memory_bflush
, &memory_bstat
, &memory_bmmap