1.1 --- a/config/libc.in Thu Jul 22 20:06:27 2010 +0200
1.2 +++ b/config/libc.in Thu Jul 22 23:26:08 2010 +0200
1.3 @@ -81,6 +81,20 @@
1.4
1.5 endchoice
1.6
1.7 +config LIBC_XLDD
1.8 + bool
1.9 + prompt "Install a cross ldd-like helper"
1.10 + default y
1.11 + help
1.12 + Say 'Y' here if you want to have a ldd-like helper that
1.13 + you can run on your build system, and that will (try to)
1.14 + resolve shared libraries dependencies as if run on the
1.15 + target.
1.16 +
1.17 + Note that the cross-ldd helper is not a full replacement
1.18 + for the native ldd. Please see the help, by running it
1.19 + with '--help' for more explanations.
1.20 +
1.21 source "config.gen/libc.in.2"
1.22
1.23 endif # ! LIBC_none
2.1 --- a/scripts/build/internals.sh Thu Jul 22 20:06:27 2010 +0200
2.2 +++ b/scripts/build/internals.sh Thu Jul 22 23:26:08 2010 +0200
2.3 @@ -21,6 +21,19 @@
2.4 CT_DoExecLog ALL chmod 755 "${CT_PREFIX_DIR}/bin/${CT_TARGET}-populate"
2.5 fi
2.6
2.7 + if [ "${CT_LIBC_XLDD}" = "y" ]; then
2.8 + CT_DoLog EXTRA "Installing a cross-ldd helper"
2.9 + sed -r -e 's|@@CT_TARGET@@|'"${CT_TARGET}"'|g;' \
2.10 + -e 's|@@CT_install@@|'"${install}"'|g;' \
2.11 + -e 's|@@CT_bash@@|'"${bash}"'|g;' \
2.12 + -e 's|@@CT_grep@@|'"${grep}"'|g;' \
2.13 + -e 's|@@CT_make@@|'"${make}"'|g;' \
2.14 + -e 's|@@CT_sed@@|'"${sed}"'|g;' \
2.15 + "${CT_LIB_DIR}/scripts/xldd.in" \
2.16 + >"${CT_PREFIX_DIR}/bin/${CT_TARGET}-ldd"
2.17 + CT_DoExecLog ALL chmod 755 "${CT_PREFIX_DIR}/bin/${CT_TARGET}-ldd"
2.18 + fi
2.19 +
2.20 # Create the aliases to the target tools
2.21 CT_DoLog EXTRA "Creating toolchain aliases"
2.22 CT_Pushd "${CT_PREFIX_DIR}/bin"
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/scripts/xldd.in Thu Jul 22 23:26:08 2010 +0200
3.3 @@ -0,0 +1,214 @@
3.4 +#!@@CT_bash@@
3.5 +
3.6 +# NON-CONFIGURABLE STUFF!
3.7 +export LC_ALL=C
3.8 +sed="@@CT_sed@@"
3.9 +grep="@@CT_grep@@"
3.10 +my_name="$( basename "${0}" )"
3.11 +prefix="${0%-ldd}"
3.12 +gcc="${prefix}-gcc"
3.13 +readelf="${prefix}-readelf"
3.14 +fake_load_addr="$((0xdeadbeef))"
3.15 +fake_load_addr_sys="$((0x8badf00d))"
3.16 +ld_library_path="/lib:/usr/lib"
3.17 +
3.18 +do_error() {
3.19 + printf "%s: %s\n" "${my_name}" "$*" >&2
3.20 +}
3.21 +
3.22 +do_opt_error() {
3.23 + do_error "$@"
3.24 + printf "Try \`%s --help' for more information\n >&2"
3.25 +}
3.26 +
3.27 +show_version() {
3.28 + # Fake a real ldd, just in case some dumb script would check
3.29 + cat <<_EOF_
3.30 +ldd (crosstool-NG) 1.8.0
3.31 +Copyright (C) 2010 "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
3.32 +This is free software; see the source for copying conditions. There is NO
3.33 +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
3.34 +Licensed under the GPLv2, see the file LICENSES in the top-directory of the
3.35 +sources for this package.
3.36 +_EOF_
3.37 +}
3.38 +
3.39 +show_help() {
3.40 + cat <<_EOF_
3.41 +Usage: ${my_name} [OPTION]... --root DIR FILE...
3.42 + --help print this help and exit
3.43 + --version print version information and exit
3.44 + --root dir treat dir as being the root of the target
3.45 + -s, --show-system mark libs from the sysroot with a trailing '[*]'
3.46 +
3.47 +_EOF_
3.48 + cat <<_EOF_ |fmt
3.49 +${my_name} tries to mimick the behavior of a real native ldd, but can be
3.50 +used in a cross-development environment. Here is how it differs from a
3.51 +real native ldd:
3.52 +
3.53 +The LD_LIBRARY_PATH variable is not used, as it can not reliably be
3.54 +guessed except at runtime, and we can't run.
3.55 +
3.56 +${my_name} does not scan /etc/ld.so.cache, but instead uses /etc/ld.so.conf
3.57 +(it understands the include directives therein for libces that have that).
3.58 +[Note: this is missing for now...]
3.59 +
3.60 +${my_name} will search the directory specified with --root for libraries
3.61 +to resolve the NEEDED tags. If --root is not set, then ${my_name} will
3.62 +use the value in the environment variable \${CT_XLDD_ROOT}. If neither
3.63 +is set, then this is an error.
3.64 +
3.65 +If NEEDED libraries can't be found in the specified root directory, then
3.66 +${my_name} will also look in the sysroot of the toolchain to see if it
3.67 +can find them.
3.68 +
3.69 +For NEEDED libraries that were found, the output will look like:
3.70 + libneeded.so => /path/to/libneeded.so (0xloadaddr)
3.71 +
3.72 +and for those that were not found, the output will look like:
3.73 + libneeded.so not found
3.74 +
3.75 +The paths are relative to the specified root directory, or to the sysroot
3.76 +(eg. /lib/libneeded.so, /usr/lib/libneeded.so, and so on...).
3.77 +
3.78 +The expected load address 'loadaddr' is a faked address to match the output
3.79 +of the real ldd, but has no actual meaning (set to some constants for now,
3.80 +0x8badf00d for libraries from the sysroot, 0xdeadbeff for others).
3.81 +_EOF_
3.82 +
3.83 +# Unimplemeted yet:
3.84 +# -d, --data-relocs process data relocations
3.85 +# -r, --function-relocs process data and function relocations
3.86 +# -u, --unused print unused direct dependencies
3.87 +# -v, --verbose print all information
3.88 +
3.89 +# See also this thread:
3.90 +# http://sourceware.org/ml/crossgcc/2008-09/msg00057.html
3.91 +}
3.92 +
3.93 +# Parse command line options
3.94 +root="${CT_XLDD_ROOT}"
3.95 +show_system=
3.96 +while true; do
3.97 + case "${1}" in
3.98 + --help)
3.99 + show_help
3.100 + exit 0
3.101 + ;;
3.102 + --version)
3.103 + show_version
3.104 + exit 0
3.105 + ;;
3.106 + --root)
3.107 + root="$2"
3.108 + shift
3.109 + ;;
3.110 + --root=*)
3.111 + root="${1#--root=}"
3.112 + ;;
3.113 + --show-system|-s)
3.114 + show_system=1
3.115 + ;;
3.116 + -*)
3.117 + do_opt_error "unrecognized option \`${1}'"
3.118 + exit 1
3.119 + ;;
3.120 + *)
3.121 + break
3.122 + ;;
3.123 + esac
3.124 + shift
3.125 +done
3.126 +
3.127 +# Sanity checks
3.128 +if [ -z "${root}" ]; then
3.129 + do_opt_error "no root given"
3.130 + exit 1
3.131 +fi
3.132 +if [ ! -d "${root}" ]; then
3.133 + do_error "\`${root}': no such file or directory"
3.134 + exit 1
3.135 +fi
3.136 +
3.137 +sysroot="$( "${gcc}" -print-sysroot )"
3.138 +
3.139 +do_report_needed_found() {
3.140 + local needed="${1}"
3.141 + local path="${2}"
3.142 + local system="${3}"
3.143 + local loadaddr
3.144 + local sys
3.145 +
3.146 + if [ -z "${system}" ]; then
3.147 + loadaddr="${fake_load_addr}"
3.148 + else
3.149 + loadaddr="${fake_load_addr_sys}"
3.150 + if [ -n "${show_system}" ]; then
3.151 + sys=" [*]"
3.152 + fi
3.153 + fi
3.154 +
3.155 + # 8 to fake a 32-bit load address
3.156 + printf "%8s%s => %s (0x%0*x)%s\n" \
3.157 + "" \
3.158 + "${needed}" \
3.159 + "${path}" \
3.160 + 8 \
3.161 + "${loadaddr}" \
3.162 + "${sys}"
3.163 +}
3.164 +
3.165 +# Search a needed file, scanning ${lib_dir} in the root directory
3.166 +do_find_needed() {
3.167 + local needed="${1}"
3.168 + local found
3.169 + local found_sysroot
3.170 + local d
3.171 +
3.172 + for d in "${needed_search_path[@]}"; do
3.173 + if [ -f "${root}${d}/${needed}" ]; then
3.174 + found="${d}/${needed}"
3.175 + fi
3.176 + done
3.177 + if [ -z "${found}" ]; then
3.178 + for d in "${needed_search_path[@]}"; do
3.179 + if [ -f "${sysroot}${d}/${needed}" ]; then
3.180 + found_sysroot="${d}/${needed}"
3.181 + fi
3.182 + done
3.183 + fi
3.184 +
3.185 + if [ -n "${found}" ]; then
3.186 + do_report_needed_found "${needed}" "${found}"
3.187 + do_process_file "${root}${found}"
3.188 + elif [ -n "${found_sysroot}" ]; then
3.189 + do_report_needed_found "${needed}" "${found_sysroot}" "sys"
3.190 + do_process_file "${sysroot}${found_sysroot}"
3.191 + else
3.192 + printf "%8c%s not found\n" "" "${needed}"
3.193 + fi
3.194 +}
3.195 +
3.196 +# Scan a file for all NEEDED tags
3.197 +do_process_file() {
3.198 + local file="${1}"
3.199 +
3.200 + "${readelf}" -d "${file}" \
3.201 + |"${grep}" -E '\(NEEDED\)' \
3.202 + |"${sed}" -r -e 's/^.*Shared library:[[:space:]]+\[(.*)\]$/\1/;' \
3.203 + |while read needed; do
3.204 + do_find_needed "${needed}"
3.205 + done
3.206 +}
3.207 +
3.208 +# Build up the full list of search directories
3.209 +declare -a needed_search_path
3.210 +ld_library_path="${ld_library_path}:"
3.211 +while [ -n "${ld_library_path}" ]; do
3.212 + d="${ld_library_path%%:*}"
3.213 + [ -n "${d}" ] && needed_search_path+=( "${d}" )
3.214 + ld_library_path="${ld_library_path#*:}"
3.215 +done
3.216 +
3.217 +do_process_file "${1}"