2014年7月29日 星期二

indirect function (IFUNC)

function attribute:
This allows the resolution of the symbol value to be determined dynamically at load time, and an optimized version of the routine can be selected for the particular processor or other system characteristics determined then.

NOTE:  require a recent binutils (at least version 2.20.1), and GNU C library (at least version 2.11.1).
ps. building arm static binary with using ld.gold linker has bug
https://sourceware.org/bugzilla/show_bug.cgi?id=17081


https://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
https://gcc.gnu.org/ml/gcc-help/2012-03/msg00209.html



Real example:

glibc for armv7 has 3 type memcpy implementation.
  1. __memcpy_neon
  2. __memcpy_vfp
  3. memcpy_arm

memcpy (IFUNC):
  if (neon supported)
     return &__memcpy_neon
  if (vfp supported)
     return &__memcpy_vfp
  return &__memcpy_arm

memcpy will choose memcpy implementation at load time
memcpy use HWCP info (include CPU info) to got cpu capability

HWCAP(hardware capabilities)
#require executable file for system info
$LD_SHOW_AUXV=1 /lib/ld-linux-armhf.so.3

.got
ld-linux0 --> a.out's struct link map in ld-linux.so
ld-linux1 --> _dl_runtime_reolve in ld-linux.so

dynamic link的lazy binding
WHY? 呼叫.so function
HOW? GOT + PLT

第一次呼叫foo時, got內foo的address會指到ld-linux.so的dl_runtime_resolve
dl_runtime_resolve會把foo的address填到got內foo的address,然後跳到foo

第二次呼叫foo時, got內的foo的address就是指到foo, 就直接跳過去執行foo

Q: softfp的memcpy_vfp 跟 hardfp的memcpy_vfp的實做會一樣嗎?
A: libc有分不同版本, 所以沒問題

ifunc is indriect call

在static build的情況下
在main之前必須執行glibc apply_iplt去initialize ifunc

apply_iplt:
  for each R_ARM_IRELATIVE
     val = * GOT[i](hwcap);
     GOT[i] = val;




ifunc .s file:
memcpy:
   .type memcpy, %gnu_indirect_function

沒有留言:

張貼留言