scripts/xldd.in
author "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
Mon Aug 23 14:32:16 2010 +0200 (2010-08-23)
changeset 2100 f9fcfc002c8a
child 2183 dbecd99ecba5
permissions -rwxr-xr-x
debug/gdb: install dependable libs in a generic target static libs dir

For now, ncurses is the only dependable target library built for gdb.
But expat is coming, and there's no reason to install each library in
its own place.

So, install ncurses in a generic directory, where other dependable
libraries can be installed as well.

Signed-off-by: "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
yann@2034
     1
#!@@CT_bash@@
yann@2034
     2
yann@2034
     3
# NON-CONFIGURABLE STUFF!
yann@2034
     4
export LC_ALL=C
yann@2034
     5
sed="@@CT_sed@@"
yann@2034
     6
grep="@@CT_grep@@"
yann@2034
     7
my_name="$( basename "${0}" )"
yann@2034
     8
prefix="${0%-ldd}"
yann@2034
     9
gcc="${prefix}-gcc"
yann@2034
    10
readelf="${prefix}-readelf"
yann@2034
    11
fake_load_addr="$((0xdeadbeef))"
yann@2034
    12
fake_load_addr_sys="$((0x8badf00d))"
yann@2034
    13
ld_library_path="/lib:/usr/lib"
yann@2034
    14
yann@2034
    15
do_error() {
yann@2034
    16
    printf "%s: %s\n" "${my_name}" "$*" >&2
yann@2034
    17
}
yann@2034
    18
yann@2034
    19
do_opt_error() {
yann@2034
    20
    do_error "$@"
yann@2034
    21
    printf "Try \`%s --help' for more information\n >&2"
yann@2034
    22
}
yann@2034
    23
yann@2034
    24
show_version() {
yann@2034
    25
    # Fake a real ldd, just in case some dumb script would check
yann@2034
    26
    cat <<_EOF_
yann@2034
    27
ldd (crosstool-NG) 1.8.0
yann@2034
    28
Copyright (C) 2010 "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
yann@2034
    29
This is free software; see the source for copying conditions.  There is NO
yann@2034
    30
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
yann@2034
    31
Licensed under the GPLv2, see the file LICENSES in the top-directory of the
yann@2034
    32
sources for this package.
yann@2034
    33
_EOF_
yann@2034
    34
}
yann@2034
    35
yann@2034
    36
show_help() {
yann@2034
    37
    cat <<_EOF_
yann@2034
    38
Usage: ${my_name} [OPTION]... --root DIR FILE...
yann@2034
    39
      --help              print this help and exit
yann@2034
    40
      --version           print version information and exit
yann@2034
    41
      --root dir          treat dir as being the root of the target
yann@2034
    42
  -s, --show-system       mark libs from the sysroot with a trailing '[*]'
yann@2034
    43
yann@2034
    44
_EOF_
yann@2034
    45
    cat <<_EOF_ |fmt
yann@2034
    46
${my_name} tries to mimick the behavior of a real native ldd, but can be
yann@2034
    47
used in a cross-development environment. Here is how it differs from a
yann@2034
    48
real native ldd:
yann@2034
    49
yann@2034
    50
The LD_LIBRARY_PATH variable is not used, as it can not reliably be
yann@2034
    51
guessed except at runtime, and we can't run.
yann@2034
    52
yann@2034
    53
${my_name} does not scan /etc/ld.so.cache, but instead uses /etc/ld.so.conf
yann@2034
    54
(it understands the include directives therein for libces that have that).
yann@2034
    55
[Note: this is missing for now...]
yann@2034
    56
yann@2034
    57
${my_name} will search the directory specified with --root for libraries
yann@2034
    58
to resolve the NEEDED tags. If --root is not set, then ${my_name} will
yann@2034
    59
use the value in the environment variable \${CT_XLDD_ROOT}. If neither
yann@2034
    60
is set, then this is an error.
yann@2034
    61
yann@2034
    62
If NEEDED libraries can't be found in the specified root directory, then
yann@2034
    63
${my_name} will also look in the sysroot of the toolchain to see if it
yann@2034
    64
can find them.
yann@2034
    65
yann@2034
    66
For NEEDED libraries that were found, the output will look like:
yann@2034
    67
        libneeded.so => /path/to/libneeded.so (0xloadaddr)
yann@2034
    68
yann@2034
    69
and for those that were not found, the output will look like:
yann@2034
    70
        libneeded.so not found
yann@2034
    71
yann@2034
    72
The paths are relative to the specified root directory, or to the sysroot
yann@2034
    73
(eg. /lib/libneeded.so, /usr/lib/libneeded.so, and so on...).
yann@2034
    74
yann@2034
    75
The expected load address 'loadaddr' is a faked address to match the output
yann@2034
    76
of the real ldd, but has no actual meaning (set to some constants for now,
yann@2034
    77
0x8badf00d for libraries from the sysroot, 0xdeadbeff for others).
yann@2034
    78
_EOF_
yann@2034
    79
yann@2034
    80
# Unimplemeted yet:
yann@2034
    81
#  -d, --data-relocs       process data relocations
yann@2034
    82
#  -r, --function-relocs   process data and function relocations
yann@2034
    83
#  -u, --unused            print unused direct dependencies
yann@2034
    84
#  -v, --verbose           print all information
yann@2034
    85
yann@2034
    86
# See also this thread:
yann@2034
    87
#  http://sourceware.org/ml/crossgcc/2008-09/msg00057.html
yann@2034
    88
}
yann@2034
    89
yann@2034
    90
# Parse command line options
yann@2034
    91
root="${CT_XLDD_ROOT}"
yann@2034
    92
show_system=
yann@2034
    93
while true; do
yann@2034
    94
    case "${1}" in
yann@2034
    95
        --help)
yann@2034
    96
            show_help
yann@2034
    97
            exit 0
yann@2034
    98
            ;;
yann@2034
    99
        --version)
yann@2034
   100
            show_version
yann@2034
   101
            exit 0
yann@2034
   102
            ;;
yann@2034
   103
        --root)
yann@2034
   104
            root="$2"
yann@2034
   105
            shift
yann@2034
   106
            ;;
yann@2034
   107
        --root=*)
yann@2034
   108
            root="${1#--root=}"
yann@2034
   109
            ;;
yann@2034
   110
        --show-system|-s)
yann@2034
   111
            show_system=1
yann@2034
   112
            ;;
yann@2034
   113
        -*)
yann@2034
   114
            do_opt_error "unrecognized option \`${1}'"
yann@2034
   115
            exit 1
yann@2034
   116
            ;;
yann@2034
   117
        *)
yann@2034
   118
            break
yann@2034
   119
            ;;
yann@2034
   120
    esac
yann@2034
   121
    shift
yann@2034
   122
done
yann@2034
   123
yann@2034
   124
# Sanity checks
yann@2034
   125
if [ -z "${root}" ]; then
yann@2034
   126
    do_opt_error "no root given"
yann@2034
   127
    exit 1
yann@2034
   128
fi
yann@2034
   129
if [ ! -d "${root}" ]; then
yann@2034
   130
    do_error "\`${root}': no such file or directory"
yann@2034
   131
    exit 1
yann@2034
   132
fi
yann@2034
   133
yann@2034
   134
sysroot="$( "${gcc}" -print-sysroot )"
yann@2034
   135
yann@2034
   136
do_report_needed_found() {
yann@2034
   137
    local needed="${1}"
yann@2034
   138
    local path="${2}"
yann@2034
   139
    local system="${3}"
yann@2034
   140
    local loadaddr
yann@2034
   141
    local sys
yann@2034
   142
yann@2034
   143
    if [ -z "${system}" ]; then
yann@2034
   144
        loadaddr="${fake_load_addr}"
yann@2034
   145
    else
yann@2034
   146
        loadaddr="${fake_load_addr_sys}"
yann@2034
   147
        if [ -n "${show_system}" ]; then
yann@2034
   148
            sys=" [*]"
yann@2034
   149
        fi
yann@2034
   150
    fi
yann@2034
   151
yann@2034
   152
    # 8 to fake a 32-bit load address
yann@2034
   153
    printf "%8s%s => %s (0x%0*x)%s\n"   \
yann@2034
   154
           ""                           \
yann@2034
   155
           "${needed}"                  \
yann@2034
   156
           "${path}"                    \
yann@2034
   157
           8                            \
yann@2034
   158
           "${loadaddr}"                \
yann@2034
   159
           "${sys}"
yann@2034
   160
}
yann@2034
   161
yann@2034
   162
# Search a needed file, scanning ${lib_dir} in the root directory
yann@2034
   163
do_find_needed() {
yann@2034
   164
    local needed="${1}"
yann@2034
   165
    local found
yann@2034
   166
    local found_sysroot
yann@2034
   167
    local d
yann@2034
   168
yann@2034
   169
    for d in "${needed_search_path[@]}"; do
yann@2034
   170
        if [ -f "${root}${d}/${needed}" ]; then
yann@2034
   171
            found="${d}/${needed}"
yann@2034
   172
        fi
yann@2034
   173
    done
yann@2034
   174
    if [ -z "${found}" ]; then
yann@2034
   175
    for d in "${needed_search_path[@]}"; do
yann@2034
   176
        if [ -f "${sysroot}${d}/${needed}" ]; then
yann@2034
   177
            found_sysroot="${d}/${needed}"
yann@2034
   178
        fi
yann@2034
   179
    done
yann@2034
   180
    fi
yann@2034
   181
yann@2034
   182
    if [ -n "${found}" ]; then
yann@2034
   183
        do_report_needed_found "${needed}" "${found}"
yann@2034
   184
        do_process_file "${root}${found}"
yann@2034
   185
    elif [ -n "${found_sysroot}" ]; then
yann@2034
   186
        do_report_needed_found "${needed}" "${found_sysroot}" "sys"
yann@2034
   187
        do_process_file "${sysroot}${found_sysroot}"
yann@2034
   188
    else
yann@2034
   189
        printf "%8c%s not found\n" "" "${needed}"
yann@2034
   190
    fi
yann@2034
   191
}
yann@2034
   192
yann@2034
   193
# Scan a file for all NEEDED tags
yann@2034
   194
do_process_file() {
yann@2034
   195
    local file="${1}"
yann@2034
   196
yann@2034
   197
    "${readelf}" -d "${file}"                                           \
yann@2034
   198
    |"${grep}" -E '\(NEEDED\)'                                          \
yann@2034
   199
    |"${sed}" -r -e 's/^.*Shared library:[[:space:]]+\[(.*)\]$/\1/;'    \
yann@2034
   200
    |while read needed; do
yann@2034
   201
        do_find_needed "${needed}"
yann@2034
   202
     done
yann@2034
   203
}
yann@2034
   204
yann@2034
   205
# Build up the full list of search directories
yann@2034
   206
declare -a needed_search_path
yann@2034
   207
ld_library_path="${ld_library_path}:"
yann@2034
   208
while [ -n "${ld_library_path}" ]; do
yann@2034
   209
    d="${ld_library_path%%:*}"
yann@2034
   210
    [ -n "${d}" ] && needed_search_path+=( "${d}" )
yann@2034
   211
    ld_library_path="${ld_library_path#*:}"
yann@2034
   212
done
yann@2034
   213
yann@2034
   214
do_process_file "${1}"