mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-22 02:32:36 +01:00
ELF.h: Avoid using seek operations
This commit is contained in:
parent
4aee44b1c0
commit
88ba3c47c2
@ -1941,9 +1941,9 @@ bool fs::dir::open(const std::string& path)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool fs::file::strict_read_check(u64 _size, u64 type_size) const
|
bool fs::file::strict_read_check(u64 offset, u64 _size, u64 type_size) const
|
||||||
{
|
{
|
||||||
if (usz pos0 = pos(), size0 = size(); (pos0 >= size0 ? 0 : (size0 - pos0)) / type_size < _size)
|
if (usz pos0 = offset, size0 = size(); (pos0 >= size0 ? 0 : (size0 - pos0)) / type_size < _size)
|
||||||
{
|
{
|
||||||
fs::g_tls_error = fs::error::inval;
|
fs::g_tls_error = fs::error::inval;
|
||||||
return false;
|
return false;
|
||||||
|
@ -314,7 +314,7 @@ namespace fs
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check if the handle is capable of reading (size * type_size) of bytes at the time of calling
|
// Check if the handle is capable of reading (size * type_size) of bytes at the time of calling
|
||||||
bool strict_read_check(u64 size, u64 type_size = 1) const;
|
bool strict_read_check(u64 offset, u64 size, u64 type_size) const;
|
||||||
|
|
||||||
// Read the data from the file and return the amount of data written in buffer
|
// Read the data from the file and return the amount of data written in buffer
|
||||||
u64 read(void* buffer, u64 count,
|
u64 read(void* buffer, u64 count,
|
||||||
@ -432,7 +432,7 @@ namespace fs
|
|||||||
if (_size != umax)
|
if (_size != umax)
|
||||||
{
|
{
|
||||||
// If _size arg is too high std::bad_alloc may happen during resize and then we cannot error check
|
// If _size arg is too high std::bad_alloc may happen during resize and then we cannot error check
|
||||||
if ((_size >= 0x10'0000 / sizeof(T)) && !strict_read_check(_size, sizeof(T)))
|
if ((_size >= 0x10'0000 / sizeof(T)) && !strict_read_check(pos(), _size, sizeof(T)))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -457,7 +457,7 @@ namespace fs
|
|||||||
|
|
||||||
// Read POD std::vector
|
// Read POD std::vector
|
||||||
template <typename T> requires (std::is_trivially_copyable_v<T> && !std::is_pointer_v<T>)
|
template <typename T> requires (std::is_trivially_copyable_v<T> && !std::is_pointer_v<T>)
|
||||||
bool read(std::vector<T>& vec, usz _size = umax,
|
bool read(std::vector<T>& vec, usz _size = umax, bool use_offs = false, usz offset = umax,
|
||||||
const char* file = __builtin_FILE(),
|
const char* file = __builtin_FILE(),
|
||||||
const char* func = __builtin_FUNCTION(),
|
const char* func = __builtin_FUNCTION(),
|
||||||
u32 line = __builtin_LINE(),
|
u32 line = __builtin_LINE(),
|
||||||
@ -468,7 +468,7 @@ namespace fs
|
|||||||
if (_size != umax)
|
if (_size != umax)
|
||||||
{
|
{
|
||||||
// If _size arg is too high std::bad_alloc may happen during resize and then we cannot error check
|
// If _size arg is too high std::bad_alloc may happen during resize and then we cannot error check
|
||||||
if ((_size >= 0x10'0000 / sizeof(T)) && !strict_read_check(_size, sizeof(T)))
|
if ((_size >= 0x10'0000 / sizeof(T)) && !strict_read_check(use_offs ? offset : pos(), _size, sizeof(T)))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -476,6 +476,11 @@ namespace fs
|
|||||||
vec.resize(_size);
|
vec.resize(_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (use_offs)
|
||||||
|
{
|
||||||
|
return read_at(offset, vec.data(), sizeof(T) * vec.size(), line, col, file, func) == sizeof(T) * vec.size();
|
||||||
|
}
|
||||||
|
|
||||||
return read(vec.data(), sizeof(T) * vec.size(), line, col, file, func) == sizeof(T) * vec.size();
|
return read(vec.data(), sizeof(T) * vec.size(), line, col, file, func) == sizeof(T) * vec.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -518,8 +523,7 @@ namespace fs
|
|||||||
{
|
{
|
||||||
std::vector<T> result;
|
std::vector<T> result;
|
||||||
result.resize(size() / sizeof(T));
|
result.resize(size() / sizeof(T));
|
||||||
seek(0);
|
if (!read(result, result.size(), true, 0, file, func, line, col)) xfail({line, col, file, func});
|
||||||
if (!read(result, result.size(), file, func, line, col)) xfail({line, col, file, func});
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -279,8 +279,8 @@ public:
|
|||||||
return set_error(elf_error::stream);
|
return set_error(elf_error::stream);
|
||||||
|
|
||||||
// Read ELF header
|
// Read ELF header
|
||||||
stream.seek(offset);
|
highest_offset = sizeof(header);
|
||||||
if (!stream.read(header))
|
if (sizeof(header) != stream.read_at(offset, &header, sizeof(header)))
|
||||||
return set_error(elf_error::stream_header);
|
return set_error(elf_error::stream_header);
|
||||||
|
|
||||||
// Check magic
|
// Check magic
|
||||||
@ -321,20 +321,24 @@ public:
|
|||||||
std::vector<phdr_t> _phdrs;
|
std::vector<phdr_t> _phdrs;
|
||||||
std::vector<shdr_t> _shdrs;
|
std::vector<shdr_t> _shdrs;
|
||||||
|
|
||||||
|
u64 seek_pos = 0;
|
||||||
|
|
||||||
if (!(opts & elf_opt::no_programs))
|
if (!(opts & elf_opt::no_programs))
|
||||||
{
|
{
|
||||||
stream.seek(offset + header.e_phoff);
|
seek_pos = offset + header.e_phoff;
|
||||||
if (!stream.read(_phdrs, header.e_phnum))
|
highest_offset = std::max<usz>(highest_offset, seek_pos);
|
||||||
|
|
||||||
|
if (!stream.read(_phdrs, header.e_phnum, true, seek_pos))
|
||||||
return set_error(elf_error::stream_phdrs);
|
return set_error(elf_error::stream_phdrs);
|
||||||
highest_offset = std::max<usz>(highest_offset, stream.pos());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(opts & elf_opt::no_sections))
|
if (!(opts & elf_opt::no_sections))
|
||||||
{
|
{
|
||||||
stream.seek(offset + header.e_shoff);
|
seek_pos = offset + header.e_shoff;
|
||||||
if (!stream.read(_shdrs, header.e_shnum))
|
highest_offset = std::max<usz>(highest_offset, seek_pos);
|
||||||
|
|
||||||
|
if (!stream.read(_shdrs, header.e_shnum, true, seek_pos))
|
||||||
return set_error(elf_error::stream_shdrs);
|
return set_error(elf_error::stream_shdrs);
|
||||||
highest_offset = std::max<usz>(highest_offset, stream.pos());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
progs.clear();
|
progs.clear();
|
||||||
@ -345,10 +349,11 @@ public:
|
|||||||
|
|
||||||
if (!(opts & elf_opt::no_data))
|
if (!(opts & elf_opt::no_data))
|
||||||
{
|
{
|
||||||
stream.seek(offset + hdr.p_offset);
|
seek_pos = offset + hdr.p_offset;
|
||||||
if (!stream.read(progs.back().bin, hdr.p_filesz))
|
highest_offset = std::max<usz>(highest_offset, seek_pos);
|
||||||
|
|
||||||
|
if (!stream.read(progs.back().bin, hdr.p_filesz, true, seek_pos))
|
||||||
return set_error(elf_error::stream_data);
|
return set_error(elf_error::stream_data);
|
||||||
highest_offset = std::max<usz>(highest_offset, stream.pos());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -380,8 +385,10 @@ public:
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
stream.seek(offset + shdr.sh_offset);
|
seek_pos = offset + shdr.sh_offset;
|
||||||
if (!stream.read(shdrs.back().bin, shdr.sh_size))
|
highest_offset = std::max<usz>(highest_offset, seek_pos);
|
||||||
|
|
||||||
|
if (!stream.read(shdrs.back().bin, shdr.sh_size, true, seek_pos))
|
||||||
return set_error(elf_error::stream_data);
|
return set_error(elf_error::stream_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user