[PATCH] readelf: use fseeko for elf files >= 2 GiB on x86_64-mingw32
Brett Werling
bwerl.dev@gmail.com
Mon Nov 14 15:03:48 GMT 2022
Switch all fseek calls to fseeko and cast the given offset as an off_t
accordingly. When building readelf for x86_64-mingw32, a long will only
be 32 bits wide. If the elf file in question is >= 2 GiB, that is
greater than the max long value, and therefore fseek will fail
indicating that the offset is negative.
To work around this and support up to 4 GiB, we switch to using fseeko
and cast the unsigned long offsets as off_t values because the size of
off_t is 64 bits on x86_64-mingw32.
---
binutils/readelf.c | 34 +++++++++++++++++-----------------
1 file changed, 17 insertions(+), 17 deletions(-)
diff --git a/binutils/readelf.c b/binutils/readelf.c
index 6b5bebe743f..a705850af35 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -424,7 +424,7 @@ get_data (void * var,
return NULL;
}
- if (fseek (filedata->handle, archive_file_offset + offset, SEEK_SET))
+ if (fseeko (filedata->handle, (off_t)archive_file_offset + offset, SEEK_SET))
{
if (reason)
error (_("Unable to seek to 0x%lx for %s\n"),
@@ -5343,7 +5343,7 @@ process_program_headers (Filedata * filedata)
break;
case PT_INTERP:
- if (fseek (filedata->handle, archive_file_offset + (long) segment->p_offset,
+ if (fseeko (filedata->handle, (off_t)archive_file_offset + (long) segment->p_offset,
SEEK_SET))
error (_("Unable to find program interpreter name\n"));
else
@@ -11720,8 +11720,8 @@ process_symbol_table (Filedata * filedata)
&& filedata->file_header.e_ident[EI_CLASS] == ELFCLASS64)
hash_ent_size = 8;
- if (fseek (filedata->handle,
- (archive_file_offset
+ if (fseeko (filedata->handle,
+ ((off_t)archive_file_offset
+ offset_from_vma (filedata, dynamic_info[DT_HASH],
sizeof nb + sizeof nc)),
SEEK_SET))
@@ -11772,8 +11772,8 @@ process_symbol_table (Filedata * filedata)
bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
bfd_vma buckets_vma;
- if (fseek (filedata->handle,
- (archive_file_offset
+ if (fseeko (filedata->handle,
+ ((off_t)archive_file_offset
+ offset_from_vma (filedata, dynamic_info_DT_GNU_HASH,
sizeof nb)),
SEEK_SET))
@@ -11797,8 +11797,8 @@ process_symbol_table (Filedata * filedata)
else
buckets_vma += bitmaskwords * 8;
- if (fseek (filedata->handle,
- (archive_file_offset
+ if (fseeko (filedata->handle,
+ ((off_t)archive_file_offset
+ offset_from_vma (filedata, buckets_vma, 4)),
SEEK_SET))
{
@@ -11826,8 +11826,8 @@ process_symbol_table (Filedata * filedata)
maxchain -= gnusymidx;
- if (fseek (filedata->handle,
- (archive_file_offset
+ if (fseeko (filedata->handle,
+ ((off_t)archive_file_offset
+ offset_from_vma (filedata, buckets_vma
+ 4 * (ngnubuckets + maxchain), 4)),
SEEK_SET))
@@ -11851,8 +11851,8 @@ process_symbol_table (Filedata * filedata)
}
while ((byte_get (nb, 4) & 1) == 0);
- if (fseek (filedata->handle,
- (archive_file_offset
+ if (fseeko (filedata->handle,
+ ((off_t)archive_file_offset
+ offset_from_vma (filedata, buckets_vma + 4 * ngnubuckets, 4)),
SEEK_SET))
{
@@ -11868,8 +11868,8 @@ process_symbol_table (Filedata * filedata)
if (dynamic_info_DT_MIPS_XHASH)
{
- if (fseek (filedata->handle,
- (archive_file_offset
+ if (fseeko (filedata->handle,
+ ((off_t)archive_file_offset
+ offset_from_vma (filedata, (buckets_vma
+ 4 * (ngnubuckets
+ maxchain)), 4)),
@@ -20185,7 +20185,7 @@ process_archive (Filedata * filedata, bfd_boolean is_thin_archive)
ret = FALSE;
}
- if (fseek (filedata->handle, current_pos, SEEK_SET) != 0)
+ if (fseeko (filedata->handle, (off_t)current_pos, SEEK_SET) != 0)
{
error (_("%s: failed to seek back to start of object files in the archive\n"),
filedata->file_name);
@@ -20211,7 +20211,7 @@ process_archive (Filedata * filedata, bfd_boolean is_thin_archive)
char * qualified_name;
/* Read the next archive header. */
- if (fseek (filedata->handle, arch.next_arhdr_offset, SEEK_SET) != 0)
+ if (fseeko (filedata->handle, (off_t)arch.next_arhdr_offset, SEEK_SET) != 0)
{
error (_("%s: failed to seek to next archive header\n"), arch.file_name);
return FALSE;
@@ -20309,7 +20309,7 @@ process_archive (Filedata * filedata, bfd_boolean is_thin_archive)
/* The nested archive file will have been opened and setup by
get_archive_member_name. */
- if (fseek (nested_arch.file, archive_file_offset, SEEK_SET) != 0)
+ if (fseeko (nested_arch.file, (off_t)archive_file_offset, SEEK_SET) != 0)
{
error (_("%s: failed to seek to archive member.\n"), nested_arch.file_name);
ret = FALSE;
--
2.38.1
More information about the Binutils
mailing list