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;
};