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 ...........***Failed 2.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 ............. Passed 6.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=gammaray&arch=mips&ver=1.2.2-1&stamp=1356200075 https://buildd.debian.org/status/fetch.php?pkg=gammaray&arch=mipsel&ver=1.2.2-1&stamp=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) move t7,ra li t8,7 jalr t9 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 needs R_MIPS_JUMP_SLOT relocation - so that dynamic linker knows which symbol corresponds to this entry. (Note that on Mips, pointers to functions which are accessed though plt are placed in separate .got.plt section, not in .got like on Intel for example.) To summarize, the method 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. For the case that function is accessed through plt, the existing method that searches for relocations should also be tried, with the exception that on Mips the relocation to search for is R_MIPS_JUMP_SLOT. Regards, Dejan Latinović -- To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org