bool ElfReader::Load() { return ReadElfHeader() && VerifyElfHeader() && ReadProgramHeader() && ReserveAddressSpace() && LoadSegments() && FindPhdr(); }
bool ElfLoader::LoadAt(const char* lib_path, off_t file_offset, uintptr_t wanted_address, Error* error) { LOG("%s: lib_path='%s', file_offset=%p, load_address=%p\n", __FUNCTION__, lib_path, file_offset, wanted_address); // Check that the load address is properly page-aligned. if (wanted_address != PAGE_START(wanted_address)) { error->Format("Load address is not page aligned (%08x)", wanted_address); return false; } wanted_load_address_ = reinterpret_cast<void*>(wanted_address); // Check that the file offset is also properly page-aligned. // PAGE_START() can't be used here due to the compiler complaining about // comparing signed (off_t) and unsigned (size_t) values. if ((file_offset & static_cast<off_t>(PAGE_SIZE - 1)) != 0) { error->Format("File offset is not page aligned (%08x)", file_offset); return false; } file_offset_ = file_offset; // Open the file. if (!fd_.OpenReadOnly(lib_path)) { error->Format("Can't open file: %s", strerror(errno)); return false; } if (file_offset && fd_.SeekTo(file_offset) < 0) { error->Format( "Can't seek to file offset %08x: %s", file_offset, strerror(errno)); return false; } path_ = lib_path; if (!ReadElfHeader(error) || !ReadProgramHeader(error) || !ReserveAddressSpace(error)) { return false; } if (!LoadSegments(error) || !FindPhdr(error)) { // An error occured, cleanup the address space by un-mapping the // range that was reserved by ReserveAddressSpace(). if (load_start_ && load_size_) munmap(load_start_, load_size_); return false; } return true; }