bfd_get_size cache
We have calls to bfd_get_size when swapping in ELF section headers. Since object files can have a large number of sections, it's worth caching the file size rather than making lots of stat system calls. * bfd.c (struct bfd): Move format and direction to other bitfields. Add "size". * bfdio.c (bfd_get_size): Cache size when not writing file. * opncls.c (bfd_get_debug_link_info_1): Allow for bfd_get_size returning zero, ie. unknown. (bfd_get_alt_debug_link_info): Likewise. * bfd-in2.h: Regenerate.
This commit is contained in:
parent
7c5fa58ea9
commit
b03202e32c
5 changed files with 59 additions and 20 deletions
|
@ -1,3 +1,13 @@
|
|||
2020-02-19 Alan Modra <amodra@gmail.com>
|
||||
|
||||
* bfd.c (struct bfd): Move format and direction to other
|
||||
bitfields. Add "size".
|
||||
* bfdio.c (bfd_get_size): Cache size when not writing file.
|
||||
* opncls.c (bfd_get_debug_link_info_1): Allow for bfd_get_size
|
||||
returning zero, ie. unknown.
|
||||
(bfd_get_alt_debug_link_info): Likewise.
|
||||
* bfd-in2.h: Regenerate.
|
||||
|
||||
2020-02-19 Alan Modra <amodra@gmail.com>
|
||||
|
||||
* coffgen.c (_bfd_coff_get_external_symbols): Don't call
|
||||
|
|
|
@ -6497,12 +6497,6 @@ struct bfd
|
|||
/* A unique identifier of the BFD */
|
||||
unsigned int id;
|
||||
|
||||
/* The format which belongs to the BFD. (object, core, etc.) */
|
||||
ENUM_BITFIELD (bfd_format) format : 3;
|
||||
|
||||
/* The direction with which the BFD was opened. */
|
||||
ENUM_BITFIELD (bfd_direction) direction : 2;
|
||||
|
||||
/* Format_specific flags. */
|
||||
flagword flags;
|
||||
|
||||
|
@ -6606,6 +6600,12 @@ struct bfd
|
|||
| BFD_PLUGIN | BFD_TRADITIONAL_FORMAT | BFD_DETERMINISTIC_OUTPUT \
|
||||
| BFD_COMPRESS_GABI | BFD_CONVERT_ELF_COMMON | BFD_USE_ELF_STT_COMMON)
|
||||
|
||||
/* The format which belongs to the BFD. (object, core, etc.) */
|
||||
ENUM_BITFIELD (bfd_format) format : 3;
|
||||
|
||||
/* The direction with which the BFD was opened. */
|
||||
ENUM_BITFIELD (bfd_direction) direction : 2;
|
||||
|
||||
/* Is the file descriptor being cached? That is, can it be closed as
|
||||
needed, and re-opened when accessed later? */
|
||||
unsigned int cacheable : 1;
|
||||
|
@ -6706,6 +6706,11 @@ struct bfd
|
|||
/* Pointer to structure which contains architecture information. */
|
||||
const struct bfd_arch_info *arch_info;
|
||||
|
||||
/* Cached length of file for bfd_get_size. 0 until bfd_get_size is
|
||||
called, 1 if stat returns an error or the file size is too large to
|
||||
return in ufile_ptr. Both 0 and 1 should be treated as "unknown". */
|
||||
ufile_ptr size;
|
||||
|
||||
/* Stuff only useful for archives. */
|
||||
void *arelt_data;
|
||||
struct bfd *my_archive; /* The containing archive BFD. */
|
||||
|
|
17
bfd/bfd.c
17
bfd/bfd.c
|
@ -85,12 +85,6 @@ CODE_FRAGMENT
|
|||
. {* A unique identifier of the BFD *}
|
||||
. unsigned int id;
|
||||
.
|
||||
. {* The format which belongs to the BFD. (object, core, etc.) *}
|
||||
. ENUM_BITFIELD (bfd_format) format : 3;
|
||||
.
|
||||
. {* The direction with which the BFD was opened. *}
|
||||
. ENUM_BITFIELD (bfd_direction) direction : 2;
|
||||
.
|
||||
. {* Format_specific flags. *}
|
||||
. flagword flags;
|
||||
.
|
||||
|
@ -194,6 +188,12 @@ CODE_FRAGMENT
|
|||
. | BFD_PLUGIN | BFD_TRADITIONAL_FORMAT | BFD_DETERMINISTIC_OUTPUT \
|
||||
. | BFD_COMPRESS_GABI | BFD_CONVERT_ELF_COMMON | BFD_USE_ELF_STT_COMMON)
|
||||
.
|
||||
. {* The format which belongs to the BFD. (object, core, etc.) *}
|
||||
. ENUM_BITFIELD (bfd_format) format : 3;
|
||||
.
|
||||
. {* The direction with which the BFD was opened. *}
|
||||
. ENUM_BITFIELD (bfd_direction) direction : 2;
|
||||
.
|
||||
. {* Is the file descriptor being cached? That is, can it be closed as
|
||||
. needed, and re-opened when accessed later? *}
|
||||
. unsigned int cacheable : 1;
|
||||
|
@ -294,6 +294,11 @@ CODE_FRAGMENT
|
|||
. {* Pointer to structure which contains architecture information. *}
|
||||
. const struct bfd_arch_info *arch_info;
|
||||
.
|
||||
. {* Cached length of file for bfd_get_size. 0 until bfd_get_size is
|
||||
. called, 1 if stat returns an error or the file size is too large to
|
||||
. return in ufile_ptr. Both 0 and 1 should be treated as "unknown". *}
|
||||
. ufile_ptr size;
|
||||
.
|
||||
. {* Stuff only useful for archives. *}
|
||||
. void *arelt_data;
|
||||
. struct bfd *my_archive; {* The containing archive BFD. *}
|
||||
|
|
19
bfd/bfdio.c
19
bfd/bfdio.c
|
@ -415,17 +415,32 @@ DESCRIPTION
|
|||
of space for the 15 bazillon byte table it is about to read.
|
||||
This function at least allows us to answer the question, "is the
|
||||
size reasonable?".
|
||||
|
||||
A return value of zero indicates the file size is unknown.
|
||||
*/
|
||||
|
||||
ufile_ptr
|
||||
bfd_get_size (bfd *abfd)
|
||||
{
|
||||
/* A size of 0 means we haven't yet called bfd_stat. A size of 1
|
||||
means we have a cached value of 0, ie. unknown. */
|
||||
if (abfd->size <= 1 || bfd_write_p (abfd))
|
||||
{
|
||||
struct stat buf;
|
||||
|
||||
if (bfd_stat (abfd, &buf) != 0)
|
||||
if (abfd->size == 1 && !bfd_write_p (abfd))
|
||||
return 0;
|
||||
|
||||
return buf.st_size;
|
||||
if (bfd_stat (abfd, &buf) != 0
|
||||
|| buf.st_size == 0
|
||||
|| buf.st_size - (ufile_ptr) buf.st_size != 0)
|
||||
{
|
||||
abfd->size = 1;
|
||||
return 0;
|
||||
}
|
||||
abfd->size = buf.st_size;
|
||||
}
|
||||
return abfd->size;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -1209,6 +1209,7 @@ bfd_get_debug_link_info_1 (bfd *abfd, void *crc32_out)
|
|||
unsigned int crc_offset;
|
||||
char *name;
|
||||
bfd_size_type size;
|
||||
ufile_ptr file_size;
|
||||
|
||||
BFD_ASSERT (abfd);
|
||||
BFD_ASSERT (crc32_out);
|
||||
|
@ -1219,9 +1220,10 @@ bfd_get_debug_link_info_1 (bfd *abfd, void *crc32_out)
|
|||
return NULL;
|
||||
|
||||
size = bfd_section_size (sect);
|
||||
file_size = bfd_get_size (abfd);
|
||||
|
||||
/* PR 22794: Make sure that the section has a reasonable size. */
|
||||
if (size < 8 || size >= bfd_get_size (abfd))
|
||||
if (size < 8 || (file_size != 0 && size >= file_size))
|
||||
return NULL;
|
||||
|
||||
if (!bfd_malloc_and_get_section (abfd, sect, &contents))
|
||||
|
@ -1298,6 +1300,7 @@ bfd_get_alt_debug_link_info (bfd * abfd, bfd_size_type *buildid_len,
|
|||
unsigned int buildid_offset;
|
||||
char *name;
|
||||
bfd_size_type size;
|
||||
ufile_ptr file_size;
|
||||
|
||||
BFD_ASSERT (abfd);
|
||||
BFD_ASSERT (buildid_len);
|
||||
|
@ -1309,7 +1312,8 @@ bfd_get_alt_debug_link_info (bfd * abfd, bfd_size_type *buildid_len,
|
|||
return NULL;
|
||||
|
||||
size = bfd_section_size (sect);
|
||||
if (size < 8 || size >= bfd_get_size (abfd))
|
||||
file_size = bfd_get_size (abfd);
|
||||
if (size < 8 || (file_size != 0 && size >= file_size))
|
||||
return NULL;
|
||||
|
||||
if (!bfd_malloc_and_get_section (abfd, sect, & contents))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue