Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

libbpf: Support symbol versioning for uprobe #5632

Closed

Commits on Sep 12, 2023

  1. libbpf: Resolve symbol conflicts at the same offset for uprobe

    Dynamic symbols in shared library may have the same name, for example:
    
        $ nm -D /lib/x86_64-linux-gnu/libc.so.6 | grep rwlock_wrlock
        000000000009b1a0 T __pthread_rwlock_wrlock@GLIBC_2.2.5
        000000000009b1a0 T pthread_rwlock_wrlock@@GLIBC_2.34
        000000000009b1a0 T pthread_rwlock_wrlock@GLIBC_2.2.5
    
        $ readelf -W --dyn-syms /lib/x86_64-linux-gnu/libc.so.6 | grep rwlock_wrlock
         706: 000000000009b1a0   878 FUNC    GLOBAL DEFAULT   15 __pthread_rwlock_wrlock@GLIBC_2.2.5
        2568: 000000000009b1a0   878 FUNC    GLOBAL DEFAULT   15 pthread_rwlock_wrlock@@GLIBC_2.34
        2571: 000000000009b1a0   878 FUNC    GLOBAL DEFAULT   15 pthread_rwlock_wrlock@GLIBC_2.2.5
    
    Currently, users can't attach a uprobe to pthread_rwlock_wrlock because
    there are two symbols named pthread_rwlock_wrlock and both are global
    bind. And libbpf considers it as a conflict.
    
    Since both of them are at the same offset we could accept one of them
    harmlessly. Note that we already does this in elf_resolve_syms_offsets.
    
    Reviewed-by: Alan Maguire <alan.maguire@oracle.com>
    Acked-by: Jiri Olsa <jolsa@kernel.org>
    Signed-off-by: Hengqi Chen <hengqi.chen@gmail.com>
    chenhengqi authored and Kernel Patches Daemon committed Sep 12, 2023
    Configuration menu
    Copy the full SHA
    1d10bac View commit details
    Browse the repository at this point in the history
  2. libbpf: Support symbol versioning for uprobe

    In current implementation, we assume that symbol found in .dynsym section
    would have a version suffix and use it to compare with symbol user supplied.
    According to the spec ([0]), this assumption is incorrect, the version info
    of dynamic symbols are stored in .gnu.version and .gnu.version_d sections
    of ELF objects. For example:
    
        $ nm -D /lib/x86_64-linux-gnu/libc.so.6 | grep rwlock_wrlock
        000000000009b1a0 T __pthread_rwlock_wrlock@GLIBC_2.2.5
        000000000009b1a0 T pthread_rwlock_wrlock@@GLIBC_2.34
        000000000009b1a0 T pthread_rwlock_wrlock@GLIBC_2.2.5
    
        $ readelf -W --dyn-syms /lib/x86_64-linux-gnu/libc.so.6 | grep rwlock_wrlock
          706: 000000000009b1a0   878 FUNC    GLOBAL DEFAULT   15 __pthread_rwlock_wrlock@GLIBC_2.2.5
          2568: 000000000009b1a0   878 FUNC    GLOBAL DEFAULT   15 pthread_rwlock_wrlock@@GLIBC_2.34
          2571: 000000000009b1a0   878 FUNC    GLOBAL DEFAULT   15 pthread_rwlock_wrlock@GLIBC_2.2.5
    
    In this case, specify pthread_rwlock_wrlock@@GLIBC_2.34 or
    pthread_rwlock_wrlock@GLIBC_2.2.5 in bpf_uprobe_opts::func_name won't work.
    Because the qualified name does NOT match `pthread_rwlock_wrlock` (without
    version suffix) in .dynsym sections.
    
    This commit implements the symbol versioning for dynsym and allows user to
    specify symbol in the following forms:
      - func
      - func@LIB_VERSION
      - func@@LIB_VERSION
    
    In case of symbol conflicts, error out and users should resolve it by
    specifying a qualified name.
    
      [0]: https://refspecs.linuxfoundation.org/LSB_5.0.0/LSB-Core-generic/LSB-Core-generic/symversion.html
    
    Reviewed-by: Alan Maguire <alan.maguire@oracle.com>
    Acked-by: Jiri Olsa <jolsa@kernel.org>
    Signed-off-by: Hengqi Chen <hengqi.chen@gmail.com>
    chenhengqi authored and Kernel Patches Daemon committed Sep 12, 2023
    Configuration menu
    Copy the full SHA
    6f81dea View commit details
    Browse the repository at this point in the history
  3. selftests/bpf: Add tests for symbol versioning for uprobe

    This exercises the newly added dynsym symbol versioning logics.
    Now we accept symbols in form of func, func@LIB_VERSION or
    func@@LIB_VERSION.
    
    The test rely on liburandom_read.so. For liburandom_read.so, we have:
    
        $ nm -D liburandom_read.so
                         w __cxa_finalize@GLIBC_2.17
                         w __gmon_start__
                         w _ITM_deregisterTMCloneTable
                         w _ITM_registerTMCloneTable
        0000000000000000 A LIBURANDOM_READ_1.0.0
        0000000000000000 A LIBURANDOM_READ_2.0.0
        000000000000081c T urandlib_api@@LIBURANDOM_READ_2.0.0
        0000000000000814 T urandlib_api@LIBURANDOM_READ_1.0.0
        0000000000000824 T urandlib_api_sameoffset@LIBURANDOM_READ_1.0.0
        0000000000000824 T urandlib_api_sameoffset@@LIBURANDOM_READ_2.0.0
        000000000000082c T urandlib_read_without_sema@@LIBURANDOM_READ_1.0.0
        00000000000007c4 T urandlib_read_with_sema@@LIBURANDOM_READ_1.0.0
        0000000000011018 D urandlib_read_with_sema_semaphore@@LIBURANDOM_READ_1.0.0
    
    For `urandlib_api`, specifying `urandlib_api` will cause a conflict because
    there are two symbols named urandlib_api and both are global bind.
    For `urandlib_api_sameoffset`, there are also two symbols in the .so, but
    both are at the same offset and essentially they refer to the same function
    so no conflict.
    
    Reviewed-by: Alan Maguire <alan.maguire@oracle.com>
    Acked-by: Jiri Olsa <jolsa@kernel.org>
    Signed-off-by: Hengqi Chen <hengqi.chen@gmail.com>
    chenhengqi authored and Kernel Patches Daemon committed Sep 12, 2023
    Configuration menu
    Copy the full SHA
    9464edb View commit details
    Browse the repository at this point in the history