Bug#728869: gammaray FTBFS: build failed on post-compile-test on mips/mipsel
Hi, The bug is fixed upstream. Can you consider getting the latest source from upstream? https://github.com/KDAB/GammaRay 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.0 + +++ patch.gammaray-1.2.2/launcher/injector/preloadcheck.cpp 2013-11-27 16:31:07.0 + @@ -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 FUNCGLOBAL DEFAULT 11 qt_startup_hook + QRegExp rxSym(^(\\d+):\\s+(?:[^ ]+\\s+){6}([^ ]+)(?:.*)$); + + //Example line of dynamic tag on mips: + //0x7013 (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.0 + +++ patch.gammaray-1.2.2/launcher/injector/preloadcheck.h 2013-11-27 16:31:07.0 + @@ -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; };
Bug#728869: gammaray FTBFS: build failed on post-compile-test on mips/mipsel
Hi, I have created fix for this issue for mips/mipsel, and I have sent it upstream. https://github.com/KDAB/GammaRay/pull/64 While we are waiting next gammaray release, can you consider including this fix in current version of gammaray (1.2.2-1)? This version is also successfully build and tested. A patch fixing this issue is attached. 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.0 + +++ patch.gammaray-1.2.2/launcher/injector/preloadcheck.cpp 2013-11-27 16:31:07.0 + @@ -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 FUNCGLOBAL DEFAULT 11 qt_startup_hook + QRegExp rxSym(^(\\d+):\\s+(?:[^ ]+\\s+){6}([^ ]+)(?:.*)$); + + //Example line of dynamic tag on mips: + //0x7013 (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.0 + +++ patch.gammaray-1.2.2/launcher/injector/preloadcheck.h 2013-11-27 16:31:07.0 + @@ -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; };
Bug#728869: gammaray FTBFS: build failed on post-compile-test on mips/mipsel
Control: forwarded -1 https://github.com/KDAB/GammaRay/issues/63 Control: severity -1 important I see you've already forwarded it upstream, so hopefully it will be fixed soon. I'm downgrading the severity as gammaray never built on mips*. Cheers, Felix -- To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org with a subject of unsubscribe. Trouble? Contact listmas...@lists.debian.org
Bug#728869: gammaray FTBFS: build failed on post-compile-test on mips/mipsel
Package: gammaray Version: 1.2.2-1 Severity: serious Tags: jessie sid Justification: FTBFS In an attempt to rebuild the package on mips/mipsel, build failed on testing: Running tests... /usr/bin/ctest --force-new-ctest-process -j6 Test project /build/buildd2-gammaray_1.2.2-1-mips-r9OCsw/gammaray-1.2.2/obj-mips-linux-gnu Start 1: connectiontest-preload Start 2: connectiontest-style Start 3: connectiontest-gdb Start 4: attachtest-gdb 1/4 Test #1: connectiontest-preload ...***Failed2.43 sec Failed to launch injector preload Exit code: 1 Error: Symbol is not marked as relocatable: qt_startup_hook 2/4 Test #2: connectiontest-style . Passed6.98 sec 3/4 Test #3: connectiontest-gdb ... Passed 13.83 sec 4/4 Test #4: attachtest-gdb ... Passed 33.19 sec 75% tests passed, 1 tests failed out of 4 Total Test time (real) = 33.30 sec The following tests FAILED: 1 - connectiontest-preload (Failed) The full build logs are available from: https://buildd.debian.org/status/fetch.php?pkg=gammarayarch=mipsver=1.2.2-1stamp=1356200075 https://buildd.debian.org/status/fetch.php?pkg=gammarayarch=mipselver=1.2.2-1stamp=1356200317 GammaRay uses preloading to overwrite specific function calls in QtCore to hook into its target application. To be sure that the overwriting for qt_startup_hook will work, test connectiontest-preload with readelf --relocs --wide checks if sybmbol qt_startup_hook is marked as relocatable with JUMP_SLOT relocation, which means that symbol will be resolved by dynamic linker and called at run time through the plt. The problem for Mips is that it has, besides the plt, 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. For example, if we call printf function, the typical code is (gp register here points at the .got section): lw t9, offset(gp) // load in t9 function pointer from the address gp + offset jalr t9 // call the function in t9 Initially, the memory at gp + offset will contain the address of the lazy binding stub for printf. Lazy binding stubs look like: lw t9, 0(gp) movet7,ra li t8,7 jalrt9 First instruction loads in t9 the address of the function _dl_runtime_resolve from the predefined place in .got (it is located in first .got entry). _dl_runtime_resolve is dynamic linker's function which resolves calls to functions from .so files (printf in this case). Second and third instructions load registers t7 and t8 with arguments that _dl_runtime_resolve needs. The key argument here is 7 - it is dynamic symbol table index of printf, so that dynamic linker knows which function to search for. Last instruction calls _dl_runtime_resolve. After _dl_runtime_resolve finds printf in some .so file, it will overwrite the .got entry for printf with found printf address, so that next calls to printf will not go through lazy binding stub, but directly call printf. All this doesn't need any relocations (below will be explained why). There is a method how it can be determined whether a call to function will go through .got and lazy binding stub. First, Mips ABI specifies that .got is divided in two parts - local and global. Dynamic linker only resolves symbols from the global part of the .got (that is, only symbols from global part of the .got have lazy binding stubs. Entries from the local part of the .got are filled with final values during static linking). Mips ABI also specifies that the order of symbols in global part of the .got must match the order of symbols in dynamic symbol table. In the .dynamic section (obtained with readelf -d command), there is a Mips-specific dynamic tag DT_MIPS_GOTSYM which gives the dynamic symbol index of the first symbol that has entry in global part of the .got. So, the symbol with dynamic symbol index of DT_MIPS_GOTSYM will be placed in the first entry in the global part of the .got. The symbol with dynamic symbol index of DT_MIPS_GOTSYM+1 will be placed in the second entry in the global part of the .got and so on. For the previous example, lets suppose that DT_MIPS_GOTSYM is 6. Since the dynamic symbol index of printf is 7, printf will be placed in the global part of the .got (in the second entry of the global part of the got), and call to printf will go through .got and lazy binding stub, and will be resolved by dynamic linker. From the previous explanation, it should be clear why calling functions through .got on Mips doesn't need any relocations. Dynamic linker knows which .got entry corresponds to which symbol, based on matching between .got and dynamic symbol table. For the plt, on the other hand, there is no matching between the .got.plt entry and the dynamic symbol table - function addresses in .got.plt can come in arbitrary order. This is why every .got.plt entry