Tags: jessie sid
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
< 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:
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)
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
>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
(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
- 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.
pkg-kde-extras mailing list