Hi,

The bug is fixed upstream.
Can you consider getting the latest source from
upstream?

https://github.com/ClusterLabs/libqb


Regards,
Dejan Latinović
Author: "Dejan Latinovic" <dejan.latino...@rt-rk.com>
Description: Check if call of function will go through lazy binding stub for mips.
Index: patch.gammaray-1.2.2/launcher/injector/preloadcheck.cpp
===================================================================
--- patch.gammaray-1.2.2.orig/launcher/injector/preloadcheck.cpp	2012-12-21 21:38:15.000000000 +0000
+++ patch.gammaray-1.2.2/launcher/injector/preloadcheck.cpp	2013-11-27 16:31:07.000000000 +0000
@@ -99,10 +99,99 @@
     }
   }
 
+//Mips, besides the plt, has another method of
+//calling functions from .so files, and this method doesn't need JUMP_SLOT
+//relocations (in fact, it doesn't need any relocations). This method uses .got
+//entries and lazy binding stubs.
+#ifdef __mips__
+  if (testMips(symbol, fileName)){
+    qDebug() << "Call of function " << symbol << " will go through lazy binding stub";
+    setErrorString(QString());
+    return true;
+  }
+#endif
+
   setErrorString(QObject::tr("Symbol is not marked as relocatable: %1").arg(symbol));
   return false;
 }
 
+
+//The way to determine whether the call to function will go
+//through .got and lazy binding stub is:
+//- find the value of dynamic symbol index of the function with the command
+//  "readelf --dyn-syms"
+//- find the value of dynamic tag MIPS_GOTSYM with the command "readelf -d"
+//- if (dyn_sym_index >= MIPS_GOTSYM) then the function has entry in the global
+//  part of the .got, and the call will go through lazy binding stub and be
+//  resolved by dynamic linker.
+
+#ifdef __mips__
+bool PreloadCheck::testMips(const QString &symbol, const QString &fileName)
+{
+  QProcess proc;
+  proc.setProcessChannelMode(QProcess::MergedChannels);
+  proc.start("readelf", QStringList() << "--dyn-syms" << "-d" << fileName, QIODevice::ReadOnly);
+
+  if (!proc.waitForFinished()) {
+    setErrorString(QObject::tr("Failed to run 'readelf' (binutils) binary: %1").
+                   arg(QString(proc.errorString())));
+    return false;
+  }
+
+  if (proc.exitCode() != 0) {
+    setErrorString(QObject::tr("Cannot read shared object: %1").arg(QString(proc.readAll())));
+    return false;
+  }
+
+  //Example line of dynamic symbol table on mips:
+  //3851: 001e66f4     8 FUNC    GLOBAL DEFAULT   11 qt_startup_hook
+  QRegExp rxSym("^(\\d+):\\s+(?:[^ ]+\\s+){6}([^ ]+)(?:.*)$");
+
+  //Example line of dynamic tag on mips:
+  //0x70000013 (MIPS_GOTSYM)                0xec3
+  QRegExp rxGot("^0x[0-9a-fA-F]+\\s+\\((.+)\\)\\s+(0x[0-9a-fA-F]+)(?:.*)$");
+
+  int dyn_sym_index = 0;
+  int mips_gotsym = 0;
+  bool foundDynSymbol = false;
+  bool foundGotTag = false;
+
+  while (proc.canReadLine()) {
+    const QString line = proc.readLine().trimmed();
+    QString currentMatch;
+    const QString tag = "MIPS_GOTSYM";
+
+    if (rxGot.exactMatch(line)) {
+      currentMatch = rxGot.cap(1);
+
+      if (currentMatch == tag) {
+        bool conversionOk = false;
+        int value = rxGot.cap(2).toInt(&conversionOk, 16);
+        if (conversionOk){
+          mips_gotsym = value;
+          foundGotTag = true;
+        }
+      }
+    }
+    else if (rxSym.exactMatch(line)) {
+      currentMatch = rxSym.cap(2);
+      if (currentMatch == symbol) {
+        dyn_sym_index = rxSym.cap(1).toInt();
+        foundDynSymbol = true;
+      }
+    }
+    if (foundGotTag && foundDynSymbol)
+      break;
+  }
+  if (foundGotTag && foundDynSymbol && (dyn_sym_index >= mips_gotsym)) {
+    return true;
+  }
+
+  return false;
+}
+#endif
+
+
 void PreloadCheck::setErrorString(const QString &err)
 {
   m_errorString = err;
Index: patch.gammaray-1.2.2/launcher/injector/preloadcheck.h
===================================================================
--- patch.gammaray-1.2.2.orig/launcher/injector/preloadcheck.h	2012-12-21 21:38:15.000000000 +0000
+++ patch.gammaray-1.2.2/launcher/injector/preloadcheck.h	2013-11-27 16:31:07.000000000 +0000
@@ -44,6 +44,10 @@
   private:
     static QString findSharedObjectFile(const QString &symbol);
 
+#ifdef __mips__
+    bool testMips(const QString &symbol, const QString &fileName);
+#endif
+
     QString m_errorString;
 };
 

Reply via email to