Upgrade Pin for Ubuntu 22.04 and support of Clone3

196 views
Skip to first unread message

Jaime Roelandts

unread,
Aug 26, 2022, 4:27:49 AM8/26/22
to Sniper simulator
Dear all,

With the newest Ubuntu (and thus new linux kernel), the PIN version Sniper is using, has some issues, especially regarding multi-threading.

I managed to fix it with the following changes:
- Download the PIN version 3.23 from https://www.intel.com/content/www/us/en/developer/articles/tool/pin-a-binary-instrumentation-tool-downloads.html (Pin version 3.24 has a bug regarding Ifstream, preventing to use it properly on Sniper for now. See: https://groups.io/g/pinheads/topic/93223390#13509 )
- Extract, Rename and replace the downloaded directory to pin_kit inside Sniper.
- Apply the patch underneath.

I did not test this extensively, so I cannot guarantee that it will solve all issues. But hopefully this helps you out somehow.

Jaime Roelandts - Ugent
---------------------------------------------------------------
diff --git a/sift/recorder/emulation.cc b/sift/recorder/emulation.cc
index 4d55a19af..d5277c2f9 100644
--- a/sift/recorder/emulation.cc
+++ b/sift/recorder/emulation.cc
@@ -9,7 +9,7 @@
 
 static AFUNPTR ptr_exit = NULL;
 
-static void handleRdtsc(THREADID threadid, PIN_REGISTER * gax, PIN_REGISTER * gdx)
+static void handleRdtsc(THREADID threadid, ADDRINT * gax, ADDRINT * gdx)
 {
    if (!thread_data[threadid].output)
       return;
@@ -21,12 +21,12 @@ static void handleRdtsc(THREADID threadid, PIN_REGISTER * gax, PIN_REGISTER * gd
    if (emulated)
    {
       // Return in eax and edx
-      gdx->dword[0] = res.rdtsc.cycles >> 32;
-      gax->dword[0] = res.rdtsc.cycles & 0xffffffff;
+      *gdx = res.rdtsc.cycles >> 32;
+      *gax = res.rdtsc.cycles & 0xffffffff;
    }
 }
 
-static void handleCpuid(THREADID threadid, PIN_REGISTER * gax, PIN_REGISTER * gbx, PIN_REGISTER * gcx, PIN_REGISTER * gdx)
+static void handleCpuid(THREADID threadid, ADDRINT * gax, ADDRINT * gbx, ADDRINT * gcx, ADDRINT * gdx)
 {
    if (!thread_data[threadid].output)
       return;
@@ -34,15 +34,15 @@ static void handleCpuid(THREADID threadid, PIN_REGISTER * gax, PIN_REGISTER * gb
    Sift::EmuRequest req;
    Sift::EmuReply res;
 
-   req.cpuid.eax = gax->dword[0];
-   req.cpuid.ecx = gcx->dword[0];
+   req.cpuid.eax = *gax;
+   req.cpuid.ecx = *gcx;
    bool emulated = thread_data[threadid].output->Emulate(Sift::EmuTypeCpuid, req, res);
 
    sift_assert(emulated);
-   gax->dword[0] = res.cpuid.eax;
-   gbx->dword[0] = res.cpuid.ebx;
-   gcx->dword[0] = res.cpuid.ecx;
-   gdx->dword[0] = res.cpuid.edx;
+   *gax = res.cpuid.eax;
+   *gbx = res.cpuid.ebx;
+   *gcx = res.cpuid.ecx;
+   *gdx = res.cpuid.edx;
 }
 
 static ADDRINT emuGetNprocs(THREADID threadid)
diff --git a/sift/recorder/makefile.rules b/sift/recorder/makefile.rules
index a3b78eafc..9a3fbbdfc 100644
--- a/sift/recorder/makefile.rules
+++ b/sift/recorder/makefile.rules
@@ -115,7 +115,7 @@ else
 endif
 
 COMPILE_PIN_FLAGS := -g -std=c++0x $(PINPLAY_CXXFLAGS) $(TOOL_CXXFLAGS)
-LINK_FLAGS := -g $(TOOL_LDFLAGS)
+LINK_FLAGS := -g $(TOOL_LDFLAGS_NOOPT)
     
 LINK_LIBS = sift/libsift.a $(PINPLAY_LIBS)
 
diff --git a/sift/recorder/syscall_modeling.cc b/sift/recorder/syscall_modeling.cc
index 57a850b90..4b8b59549 100644
--- a/sift/recorder/syscall_modeling.cc
+++ b/sift/recorder/syscall_modeling.cc
@@ -103,6 +103,25 @@ VOID emulateSyscallFunc(THREADID threadid, CONTEXT *ctxt)
          // Handle SYS_clone child tid capture for proper pthread_join emulation.
          // When the CLONE_CHILD_CLEARTID option is enabled, remember its child_tidptr and
          // then when the thread ends, write 0 to the tid mutex and futex_wake it
+     case SYS_clone3:
+     {
+            if (args[0] && CLONE_THREAD) //TODO not sure if enough, but it works for now
+            {
+           struct clone_args* clone3_args = (struct clone_args*)args[0];
+           ADDRINT tidptr = clone3_args->parent_tid;
+               PIN_GetLock(&new_threadid_lock, threadid);
+               tidptrs.push_back(tidptr);
+               PIN_ReleaseLock(&new_threadid_lock);
+               /* New thread */
+               thread_data[threadid].output->NewThread();
+            }
+            else
+            {
+               /* New process */
+               // Nothing to do there, handled in fork() -> to check SYS_clone3 is new
+            }
+            break;
+         }
          case SYS_clone:
          {
             if (args[0] & CLONE_THREAD)
diff --git a/sift/sift_reader.cc b/sift/sift_reader.cc
index 479e5162c..e1d4e7620 100644
--- a/sift/sift_reader.cc
+++ b/sift/sift_reader.cc
@@ -154,7 +154,7 @@ bool Sift::Reader::initResponse()
          std::cerr << "[SIFT:" << m_id << "] Response filename not set\n";
          return false;
       }
-      response = new vofstream(m_response_filename, std::ios::out);
+      response = new vofstream(m_response_filename, std::ios::out | std::ios::binary | std::ios::trunc);
    }
 
    if ((!response->is_open()) || (response->fail()))
@@ -310,7 +310,7 @@ bool Sift::Reader::Read(Instruction &inst)
                hexdump((char*)bytes, size);
                #endif
                #if VERBOSE > 1
-               for (int i = 0 ; i < (size/8) ; i++)
+               for (uint32_t i = 0 ; i < (size/8) ; i++)
                {
                   std::cerr << __FUNCTION__ << ": syscall args[" << i << "] = " << ((uint64_t*)bytes)[i] << std::endl;
                }
diff --git a/sift/sift_writer.cc b/sift/sift_writer.cc
index 62d1beb75..b24a6b545 100644
--- a/sift/sift_writer.cc
+++ b/sift/sift_writer.cc
@@ -115,7 +115,7 @@ void Sift::Writer::initResponse()
    if (!response)
    {
      sift_assert(strcmp(m_response_filename, "") != 0);
-     response = new vifstream(m_response_filename, std::ios::in);
+     response = new vifstream(m_response_filename, std::ios::in | std::ios::binary);
      sift_assert(!response->fail());
    }
 }
@@ -813,7 +813,7 @@ bool Sift::Writer::Emulate(Sift::EmuType type, Sift::EmuRequest &req, Sift::EmuR
    output->write(reinterpret_cast<char*>(&_type), sizeof(uint16_t));
    output->write(reinterpret_cast<char*>(&req), sizeof(EmuRequest));
    output->flush();
-
+      
    initResponse();
 
    // wait for reply
-------------------------------------------------------------------------------
Reply all
Reply to author
Forward
0 new messages