delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin/2002/09/17/19:03:45

Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm
List-Subscribe: <mailto:cygwin-subscribe AT cygwin DOT com>
List-Archive: <http://sources.redhat.com/ml/cygwin/>
List-Post: <mailto:cygwin AT cygwin DOT com>
List-Help: <mailto:cygwin-help AT cygwin DOT com>, <http://sources.redhat.com/ml/#faqs>
Sender: cygwin-owner AT cygwin DOT com
Mail-Followup-To: cygwin AT cygwin DOT com
Delivered-To: mailing list cygwin AT cygwin DOT com
From: "Matt Swift" <swift AT alum DOT mit DOT edu>
To: <cygwin AT cygwin DOT com>
Subject: Script to emulate ldd
Date: Tue, 17 Sep 2002 19:05:14 -0400
Message-ID: <000b01c25e9e$b1e60240$0700a8c0@swift.xxx>
MIME-Version: 1.0
X-Priority: 3 (Normal)
X-MSMail-Priority: Normal
Importance: Normal
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1106
Note-from-DJ: This may be spam

------=_NextPart_000_000C_01C25E7D.2AD46240
Content-Type: text/plain;
	charset="US-ASCII"
Content-Transfer-Encoding: 7bit

Attached is a bash script that emulates the ldd(1) utility.  Enjoy.


------=_NextPart_000_000C_01C25E7D.2AD46240
Content-Type: application/octet-stream;
	name="ldd"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
	filename="ldd"

#!/bin/bash

# ldd emulation for Cygwin

# Written by Matthew Swift on 9/17/02.  Public Domain.
# version 1.0

function usage () {
    decho "
Usage: $(basename $0) <file>

    Return list of all dependencies of binary file <file>.

    Uses objdump(1).

    If <file> is not an absolute filename, then it is searched for in =
$PATH with \"type -p\".

    $PROGRESS set means show some progress messages.
    $DEBUG set means show some additional messages."
}

# list of extensions to try in order if $(type -p $objectfile) fails
trylist=3D"exe dll"

# FIX: what other things can objdump grok? =20

# if file(1) returns anything that matches $oklist, then we expect =
objdump to
# be able to process it
oklist=3D"
    MS Windows PE Intel 80386 console executable not relocatable
"

# FIX: levels of debugging/progress; make into std options
# FIX: will this barf on filenames with spaces in them?  I've tried to =
be careful.
# FIX: non-recursive option
# FIX: multiple .obj files: simply pass multiple to recurse as single =
argument?

# FIX: objdump needs the file extension (e.g., .exe, .dll) but I can't =
seem to
# get Cygwin to ensure that it is giving me an extension when I locate =
the file
# in the path.  Objdump is the only thing (besides Windows programs) =
that I
# know that distinguishes between the two names, so I test by looking at =
the
# return status of "objdump -f", which seems to be one of the fastest =
options
# to objdump.  If it fails, I try the extensions in $trylist.


function decho () { # args are passed to echo if $DEBUG is set
    [ $DEBUG ] && echo "$@" >&2
}

[ $DEBUG ] && PROGRESS=3Dtrue

# progress meter
function pecho () { # args are passed to echo if $PROGRESS is set
    [ $PROGRESS ] && echo -e "$margin$@" >&2
}

# echo a list of the direct dependencies of objectfile
function deps () { # arg: objectfile
    # don't simply print $3 in case the file has a space in it
    objdump -p "$1" | fgrep 'DLL Name:' | awk '{$1=3D"";$2=3D"";print}'
}

margin=3D""
function recurse () { # arg: objectfile
    local f

    recursor "$1" "$margin"
    # filter out the file itself
    done=3D$(echo $done | sort | sed 's|'$obj'||')
    pecho
    pecho "Library dependencies of $obj are:"
    for f in $done; do echo $f; done
}

# echo list of the recursively-calculated dependencies of objectfile
function recursor () { # arg: objectfile margin
    local file=3D"$1"
    local label=3D$(basename "$file")
    local margin=3D"$2\t"
    local lib

    # skip if $file is already in $gdone
    if echo $done | fgrep -q "$file"; then
	decho "[skip $label]"
    else
	pecho "[begin $label]"
        decho "done: $done"
	done=3D"$done $file"
	local deps=3D$(deps "$file")
        # add 'echo' to collapse $deps to one line=20
	pecho "--deps. to process: $(echo $deps)]"
        # 'for' is not executed when $d is empty
	for lib in $deps; do
	    lib=3D$(realname "$lib")
	    recursor "$lib" "$margin"
	done
	pecho "[end $label]"
    fi
}

# echo absolute filename with appropriate extension if needed
# echo empty string if the file cannot be found
function realname () { # arg: filename
    local r=3D"$1"
    local f t

    decho
    # decho "rn in: [$1]"

    # type -p succeeds when it finds something
    # the status of the assignment is the status of $(type -p "$r")
    if t=3D$(type -p "$r"); then
	r=3D"$t"
    else
        # FIX probably shouldn't bother to try an extension
	#     if the file already has that extension, e.g., "foo.exe.exe"
	for f in $trylist; do
	    t=3D$(type -p "$r.$f") && break
	done
        # if nothing in $trylist worked, this is the empty string
	r=3D"$t"
    fi
    # decho "rn type: [$r]"

    # ensure extension (see notes above)
    # we have more work if $r is nonempty and objdump -f fails on it
    if [ -n "$r" ] && ! objdump -f "$r" &>/dev/null; then
	decho "$r doesn't work..."
	decho "...trying extensions: $trylist"
	t=3D""
	# if we find a valid filename with $trylist, $t will be our new result
	for f in $trylist; do
	    decho "......$r.$f..."
	    if objdump -f "$r.$f" &>/dev/null; then
		t=3D"$r.$f"
		decho "...OK got it"
		break
	    fi
	done
	if [ -z "$t" ]; then
	    decho "...running file(1) to see if it is an executable"
	    if echo $oklist | fgrep -q "$(file \"$r\")"; then
		decho "......I think \"objdump -p\" should accept this file but it =
does not!"
		decho "oklist=3D $oklist"
		decho -n -e "output of file(1):  "; [ $DEBUG ] && file "$r" >&2
		exit 1
	    fi
	    decho -n -e "......objdump cannot process this kind of file:  "; [ =
$DEBUG ] && file "$r" >&2
	    if [ -L "$r" ]; then
                # if it's a symlink, we need to run realpath(1) and =
start over
		decho ".........$r is a symlink: recursing..."
                realname $(realpath "$r")
                # don't echo anything more
		return
	    else
                # OK, can't find it, give up.
		decho ".........$r is not a symlink: giving up!"
	    fi
	fi
	r=3D"$t"
    fi
    # decho "rn result: [$r]"
    echo $r
}

obj=3D$(realname "$1")
if [ -n "$obj" ]; then
    decho "Input: $1"
    decho "Found object file: $obj"
else
    decho
    echo "Could not find object file \"$1\"!"
    echo
    echo "Search path:"
    echo
    echo -e "\t$PATH"
    echo
    exit 1
fi

# the file we have found is:
# echo $obj
=09
recurse "$obj"


------=_NextPart_000_000C_01C25E7D.2AD46240
Content-Type: text/plain; charset=us-ascii

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Bug reporting:         http://cygwin.com/bugs.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/
------=_NextPart_000_000C_01C25E7D.2AD46240--


- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019