diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt index 8fab02adb..56be12574 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -13,7 +13,8 @@ DFTypes.h DFVector.h integers.h stdint_win.h -LinuxMemAccess.h +LinuxMemAccess-memfiles.h +LinuxMemAccess-ptrace.h WindowsMemAccess.h md5/md5.h diff --git a/library/DFMemAccess.h b/library/DFMemAccess.h index 42fbba55e..f9c210454 100644 --- a/library/DFMemAccess.h +++ b/library/DFMemAccess.h @@ -25,8 +25,11 @@ distribution. #ifndef PROCESSUTIL_H_INCLUDED #define PROCESSUTIL_H_INCLUDED +// SLOW! +// #include "LinuxMemAccess-ptrace.h" + #ifdef LINUX_BUILD - #include "LinuxMemAccess.h" + #include "LinuxMemAccess-memfiles.h" #else #include "WindowsMemAccess.h" #endif diff --git a/library/LinuxMemAccess.h b/library/LinuxMemAccess-memfiles.h similarity index 68% rename from library/LinuxMemAccess.h rename to library/LinuxMemAccess-memfiles.h index 5753856b4..3b8066b33 100644 --- a/library/LinuxMemAccess.h +++ b/library/LinuxMemAccess-memfiles.h @@ -26,85 +26,71 @@ distribution. * DO NOT USE THIS FILE DIRECTLY! USE MemAccess.h INSTEAD! */ #include "integers.h" +#include +#include +#include +using namespace std; + +inline +void Mread (const uint32_t &offset, const uint32_t &size, uint8_t *target) +{ + int result; + result = pread(g_ProcessMemFile, target,size,offset); + if(result != size) + { + cerr << "pread failed: can't read " << size << " bytes at addres " << offset << endl; + if(result == -1) + { + cerr << "errno: " << errno << endl; + errno = 0; + } + } +} inline uint8_t MreadByte (const uint32_t &offset) { uint8_t val; - //fseek(g_ProcessMemFile, offset,SEEK_SET); - //fread ( &val, sizeof(uint8_t), 1, g_ProcessMemFile ); - pread(g_ProcessMemFile, &val,1,offset); + Mread(offset, 1, &val); return val; } inline void MreadByte (const uint32_t &offset, uint8_t &val ) { - //fseek(g_ProcessMemFile, offset,SEEK_SET); - //fread ( &val, sizeof(uint8_t), 1, g_ProcessMemFile ); - pread(g_ProcessMemFile, &val,1,offset); + Mread(offset, 1, &val); } inline uint16_t MreadWord (const uint32_t &offset) { uint16_t val; - //fseek(g_ProcessMemFile, offset,SEEK_SET); - //fread ( &val, sizeof(uint16_t), 1, g_ProcessMemFile ); - pread(g_ProcessMemFile, &val,2,offset); + Mread(offset, 2, (uint8_t *) &val); return val; } inline void MreadWord (const uint32_t &offset, uint16_t &val) { - //fseek(g_ProcessMemFile, offset,SEEK_SET); - //fread ( &val, sizeof(uint16_t), 1, g_ProcessMemFile ); - pread(g_ProcessMemFile, &val,2,offset); + Mread(offset, 2, (uint8_t *) &val); } inline uint32_t MreadDWord (const uint32_t &offset) { uint32_t val; - //fseek(g_ProcessMemFile, offset,SEEK_SET); - //fread ( &val, sizeof(uint32_t), 1, g_ProcessMemFile ); - pread(g_ProcessMemFile, &val,4,offset); + Mread(offset, 4, (uint8_t *) &val); return val; } inline void MreadDWord (const uint32_t &offset, uint32_t &val) { - //fseek(g_ProcessMemFile, offset,SEEK_SET); - //fread ( &val, sizeof(uint32_t), 1, g_ProcessMemFile ); - pread(g_ProcessMemFile, &val,4,offset); -} - -inline -uint64_t MreadQuad (const uint32_t &offset) -{ - uint64_t val; - //fseek(g_ProcessMemFile, offset,SEEK_SET); - //fread ( &val, sizeof(uint32_t), 1, g_ProcessMemFile ); - pread(g_ProcessMemFile, &val,8,offset); - return val; -} - -inline -void MreadQuad (const uint32_t &offset, uint64_t &val) -{ - //fseek(g_ProcessMemFile, offset,SEEK_SET); - //fread ( &val, sizeof(uint32_t), 1, g_ProcessMemFile ); - pread(g_ProcessMemFile, &val,8,offset); + Mread(offset, 4, (uint8_t *) &val); } -inline -void Mread (const uint32_t &offset, const uint32_t &size, uint8_t *target) -{ - //fseek(g_ProcessMemFile, offset,SEEK_SET); - //fread ( target, 1, size, g_ProcessMemFile ); - pread(g_ProcessMemFile, target,size,offset); -} +/* + * WRITING + */ inline void MwriteDWord (uint32_t offset, uint32_t data) diff --git a/library/LinuxMemAccess-ptrace.h b/library/LinuxMemAccess-ptrace.h new file mode 100644 index 000000000..c749d0daa --- /dev/null +++ b/library/LinuxMemAccess-ptrace.h @@ -0,0 +1,171 @@ +/* +www.sourceforge.net/projects/dfhack +Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any +damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and +must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. +*/ + +/** + * DO NOT USE THIS FILE DIRECTLY! USE MemAccess.h INSTEAD! + */ +#include "integers.h" + +inline +uint8_t MreadByte (const uint32_t &offset) +{ + return ptrace(PTRACE_PEEKDATA,g_ProcessHandle, offset, NULL); +} + +inline +void MreadByte (const uint32_t &offset, uint8_t &val ) +{ + val = ptrace(PTRACE_PEEKDATA,g_ProcessHandle, offset, NULL); +} + +inline +uint16_t MreadWord (const uint32_t &offset) +{ + return ptrace(PTRACE_PEEKDATA,g_ProcessHandle, offset, NULL); +} + +inline +void MreadWord (const uint32_t &offset, uint16_t &val) +{ + val = ptrace(PTRACE_PEEKDATA,g_ProcessHandle, offset, NULL); +} + +inline +uint32_t MreadDWord (const uint32_t &offset) +{ + return ptrace(PTRACE_PEEKDATA,g_ProcessHandle, offset, NULL); +} +inline +void MreadDWord (const uint32_t &offset, uint32_t &val) +{ + val = ptrace(PTRACE_PEEKDATA,g_ProcessHandle, offset, NULL); +} + +// extremely terrible braindamage +inline +bool Mread ( uint32_t offset, uint32_t size, uint8_t *target) +{ + uint8_t *mover = target; + while (size) + { + if(size >= 4) + { + * (uint32_t *)mover = MreadDWord(offset); + mover+=4; + offset +=4; + size -=4; + } + else if(size >= 2) + { + * (uint16_t *)mover = MreadWord(offset); + mover+=2; + offset +=2; + size -=2; + } + else if(size == 1) + { + * (uint8_t *)mover = MreadByte(offset); + mover+=1; + offset ++; + size --; + } + } + return true; +} + + +inline +void MwriteDWord (uint32_t offset, uint32_t data) +{ + ptrace(PTRACE_POKEDATA,g_ProcessHandle, offset, data); +} + +// using these is expensive. +inline +void MwriteWord (uint32_t offset, uint16_t data) +{ + uint32_t orig = MreadDWord(offset); + orig |= 0x0000FFFF; + orig &= data; + ptrace(PTRACE_POKEDATA,g_ProcessHandle, offset, orig); +} + +inline +void MwriteByte (uint32_t offset, uint8_t data) +{ + uint32_t orig = MreadDWord(offset); + orig |= 0x000000FF; + orig &= data; + ptrace(PTRACE_POKEDATA,g_ProcessHandle, offset, orig); +} + +// blah. I hate the kernel devs for crippling /proc/PID/mem. THIS IS RIDICULOUS +inline +bool Mwrite (uint32_t offset, uint32_t size, uint8_t *source) +{ + uint32_t indexptr = 0; + while (size > 0) + { + // default: we push 4 bytes + if(size >= 4) + { + MwriteDWord(offset, *(uint32_t *) (source + indexptr)); + offset +=4; + indexptr +=4; + size -=4; + } + // last is either three or 2 bytes + else if(size >= 2) + { + MwriteWord(offset, *(uint16_t *) (source + indexptr)); + offset +=2; + indexptr +=2; + size -=2; + } + // finishing move + else if(size == 1) + { + MwriteByte(offset, *(uint8_t *) (source + indexptr)); + return true; + } + } +} + +inline +const std::string MreadCString (uint32_t offset) +{ + std::string temp; + char temp_c[256]; + int counter = 0; + char r; + do + { + r = MreadByte(offset+counter); + temp_c[counter] = r; + counter++; + } while (r); + temp_c[counter] = 0; + temp = temp_c; + return temp; +} diff --git a/tools/expbench.cpp b/tools/expbench.cpp index 01bd17750..4ca080bc2 100644 --- a/tools/expbench.cpp +++ b/tools/expbench.cpp @@ -28,19 +28,26 @@ int main (void) DF.getSize(x_max,y_max,z_max); for(uint32_t i = 0; i< 1000;i++) - for(uint32_t x = 0; x< x_max;x++) { - for(uint32_t y = 0; y< y_max;y++) + if((i % 10) == 0) { - for(uint32_t z = 0; z< z_max;z++) + int percentage = i / 10; + cout << percentage << endl; + } + for(uint32_t x = 0; x< x_max;x++) + { + for(uint32_t y = 0; y< y_max;y++) { - if(DF.isValidBlock(x,y,z)) + for(uint32_t z = 0; z< z_max;z++) { - DF.ReadTileTypes(x,y,z, (uint16_t *) tiletypes); - DF.ReadDesignations(x,y,z, (uint32_t *) designations); - DF.ReadOccupancy(x,y,z, (uint32_t *) occupancies); - num_blocks ++; - bytes_read += 256 * (4 + 4 + 2); + if(DF.isValidBlock(x,y,z)) + { + DF.ReadTileTypes(x,y,z, (uint16_t *) tiletypes); + DF.ReadDesignations(x,y,z, (uint32_t *) designations); + DF.ReadOccupancy(x,y,z, (uint32_t *) occupancies); + num_blocks ++; + bytes_read += 256 * (4 + 4 + 2); + } } } }