2011-05-27 3 views
33

Я создал скомпилированный исполнитель. Я хочу найти зависимость библиотеки от исполняемого файла. Я использую ubuntu natty и установил цепочку инструментов arm-linux-gnueabi, которая не содержит ldd. Есть ли доступный инструмент для просмотра зависимости библиотеки исполняемых файлов в linux.кросс-компилятор ldd

ответ

54

Это немного kluge, но это лучшее решение, которое я могу найти, и он действительно хорошо работает для базового использования - просто сохраните этот скрипт как «arm-none-linux-gnueabi-ldd» с другим перекрестные инструменты.

#!/bin/sh 
arm-none-linux-gnueabi-readelf -a $1 | grep "Shared library:" 
+0

Даже мой родной binutils 'readelf делает эту работу (родной objdump не делает). –

+1

Параметр -a немного перегружен, общие ссылки библиотек находятся в динамическом разделе, -d. Кроме того, такой инструмент или ответ objdump верны, так как кросс-компилятор ldd не будет работать из-за того, как работает ldd: он пытается выполнить половину загрузки загружаемой библиотеки трассировки, которая не будет работать на чужом двоичный файл. – Cheetah

+2

Извините, но readelf не может заменить ldd. См. Этот http://stackoverflow.com/questions/11524820/what-is-the-difference-between-ldd-and-objdump. readelf -d выдает похожие на objdump. Может ли кто-нибудь лучше ответить на это? – longbkit

14

Вы также можете использовать objdump и для того, чтобы просто сбросить и искать долю заголовка в двоичном виде. Это может сэкономить вам несколько миллисекунд ...

#!/bin/sh 
arm-none-linux-gnueabi-objdump -x $1 | grep NEEDED 
4

Вот еще один вариант, вы можете установить переменные окружения LD_TRACE_LOADED_OBJECTS любого значение, скажем, 1, а затем вы просто запустите исполняемый файл, вывод должен быть его динамическая зависимостью.

1

Как уже говорилось, по дизайну lddcan only been executed on target. Тем не менее, можно имитировать поведение ldd, используя readelf. Сценарий под названием xldd был разработан в проекте crosstool-ng. Независимая версия этого скрипта доступна здесь:

https://gist.github.com/jerome-pouiller/c403786c1394f53f44a3b61214489e6f

0

Я нашел это и надеюсь, что это может помочь много людей, которые до сих пор ищут истинное решение LDD. ldd - это просто скрипт с поддержкой библиотеки ld-linux. Так почему бы не создать собственный скрипт ldd? Сначала вам нужно найти библиотеку ld-linux в вашей системе, которая должна быть доступна. В моем случае это /lib/ld-linux-armhf.so.3, поэтому я помещаю это в RTLDLIST, как вы можете видеть в приведенном ниже скрипте.

И поместите этот скрипт на свое устройство или на плату, и у вас может быть ldd, который очень удобен для поиска библиотек зависимостей для исполняемого файла.

Удачи вам!

#! /bin/bash 
# Copyright (C) 1996-2011, 2012 Free Software Foundation, Inc. 
# This file is part of the GNU C Library. 

# The GNU C Library is free software; you can redistribute it and/or 
# modify it under the terms of the GNU Lesser General Public 
# License as published by the Free Software Foundation; either 
# version 2.1 of the License, or (at your option) any later version. 

# The GNU C Library is distributed in the hope that it will be useful, 
# but WITHOUT ANY WARRANTY; without even the implied warranty of 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 
# Lesser General Public License for more details. 

# You should have received a copy of the GNU Lesser General Public 
# License along with the GNU C Library; if not, write to the Free 
# Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 
# 02111-1307 USA. 


# This is the `ldd' command, which lists what shared libraries are 
# used by given dynamically-linked executables. It works by invoking the 
# run-time dynamic linker as a command and setting the environment 
# variable LD_TRACE_LOADED_OBJECTS to a non-empty value. 

# We should be able to find the translation right at the beginning. 
TEXTDOMAIN=libc 
TEXTDOMAINDIR=/usr/share/locale 

RTLDLIST="/lib/ld-linux.so.2 /lib64/ld-linux-x86-64.so.2 /lib/ld-linux-armhf.so.3" 
warn= 
bind_now= 
verbose= 

while test $# -gt 0; do 
    case "$1" in 
    --vers | --versi | --versio | --version) 
    echo 'ldd (Ubuntu EGLIBC 2.15-0ubuntu10.3) 2.15' 
    printf $"Copyright (C) %s Free Software Foundation, Inc. 
This is free software; see the source for copying conditions. There is NO 
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
" "2012" 
    printf $"Written by %s and %s. 
" "Roland McGrath" "Ulrich Drepper" 
    exit 0 
    ;; 
    --h | --he | --hel | --help) 
    printf $"Usage: ldd [OPTION]... FILE... 
     --help    print this help and exit 
     --version   print version information and exit 
    -d, --data-relocs  process data relocations 
    -r, --function-relocs process data and function relocations 
    -u, --unused   print unused direct dependencies 
    -v, --verbose   print all information 
" 
    printf $"For bug reporting instructions, please see: 
%s. 
" "<http://www.debian.org/Bugs/>" 
    exit 0 
    ;; 
    -d | --d | --da | --dat | --data | --data- | --data-r | --data-re | \ 
    --data-rel | --data-relo | --data-reloc | --data-relocs) 
    warn=yes 
    shift 
    ;; 
    -r | --f | --fu | --fun | --func | --funct | --functi | --functio | \ 
    --function | --function- | --function-r | --function-re | --function-rel | \ 
    --function-relo | --function-reloc | --function-relocs) 
    warn=yes 
    bind_now=yes 
    shift 
    ;; 
    -v | --verb | --verbo | --verbos | --verbose) 
    verbose=yes 
    shift 
    ;; 
    -u | --u | --un | --unu | --unus | --unuse | --unused) 
    unused=yes 
    shift 
    ;; 
    --v | --ve | --ver) 
    echo >&2 $"ldd: option \`$1' is ambiguous" 
    exit 1 
    ;; 
    --)  # Stop option processing. 
    shift; break 
    ;; 
    -*) 
    echo >&2 'ldd:' $"unrecognized option" "\`$1'" 
    echo >&2 $"Try \`ldd --help' for more information." 
    exit 1 
    ;; 
    *) 
    break 
    ;; 
    esac 
done 

nonelf() 
{ 
    # Maybe extra code for non-ELF binaries. 
    return 1; 
} 

add_env="LD_TRACE_LOADED_OBJECTS=1 LD_WARN=$warn LD_BIND_NOW=$bind_now" 
add_env="$add_env LD_LIBRARY_VERSION=\$verify_out" 
add_env="$add_env LD_VERBOSE=$verbose" 
if test "$unused" = yes; then 
    add_env="$add_env LD_DEBUG=\"$LD_DEBUG${LD_DEBUG:+,}unused\"" 
fi 

# The following use of cat is needed to make ldd work in SELinux 
# environments where the executed program might not have permissions 
# to write to the console/tty. But only bash 3.x supports the pipefail 
# option, and we don't bother to handle the case for older bash versions. 
if x=`set -o` && test "$x" != "${x#*pipefail}" && set -o pipefail ; then 
    try_trace() { 
    eval $add_env '"[email protected]"' | cat 
    } 
else 
    try_trace() { 
    eval $add_env '"[email protected]"' 
    } 
fi 

case $# in 
0) 
    echo >&2 'ldd:' $"missing file arguments" 
    echo >&2 $"Try \`ldd --help' for more information." 
    exit 1 
    ;; 
1) 
    single_file=t 
    ;; 
*) 
    single_file=f 
    ;; 
esac 

result=0 
for file do 
    # We don't list the file name when there is only one. 
    test $single_file = t || echo "${file}:" 
    case $file in 
    */*) : 
     ;; 
    *) file=./$file 
    ;; 
    esac 
    if test ! -e "$file"; then 
    echo "ldd: ${file}:" $"No such file or directory" >&2 
    result=1 
    elif test ! -f "$file"; then 
    echo "ldd: ${file}:" $"not regular file" >&2 
    result=1 
    elif test -r "$file"; then 
    RTLD= 
    ret=1 
    for rtld in ${RTLDLIST}; do 
     if test -x $rtld; then 
    verify_out=`${rtld} --verify "$file"` 
    ret=$? 
    case $ret in 
    [02]) RTLD=${rtld}; break;; 
    esac 
     fi 
    done 
    case $ret in 
    0|2) 
     try_trace "$RTLD" "$file" || result=1 
     ;; 
    1|126) 
     # This can be a non-ELF binary or no binary at all. 
     nonelf "$file" || { 
    echo $" not a dynamic executable" 
    result=1 
     } 
     ;; 
    *) 
     echo 'ldd:' ${RTLD} $"exited with unknown exit code" "($ret)" >&2 
     exit 1 
     ;; 
    esac 
    else 
    echo 'ldd:' $"error: you do not have read permission for" "\`$file'" >&2 
    result=1 
    fi 
done 

exit $result 
# Local Variables: 
# mode:ksh 
# End: 
Смежные вопросы