summaryrefslogtreecommitdiffstats
path: root/helper/binutil.inc
blob: 261ccf16128c69e102b6da77975fed20c4be5d1d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
#!/bin/bash
# 
# Common functions to copy binaries and their dependancies.
#
############################################################
#
# Usage: get_dynamic_dependencies [-l <searchdir>] <binary_list>
# 	  * the list must be seperated by spaces
#	  * the search for lib needed by a binary can be done locally,
#	    using the -l <searchdir> option
#
# Ouput: 
#	 Will simply echo list of required libraries

# List of libraries to exclude from
BLACKLIST="ld-linux linux-gate linux-vdso libc.so"
LOCALSEARCH=0
LOCALSEARCHDIR=""

CURRENT_BLACKLIST=$(echo ${BLACKLIST} | sed 's/ /\\|/g')

get_dynamic_dependencies() {
	
	if [ "x$1" == "x-l" ]; then
		LOCALSEARCH=1
		shift
		[ ! -d $1 ] && perror "Directory given does not exist, exiting."
		LOCALSEARCHDIR=$1
		shift
	fi	

	while [ $# != 0 ]; do
		local BINARY=$1
		shift

		local LDD_OUT="ldd_output"
		if ldd $BINARY > $LDD_OUT; then
			# Case 1: dynamic
			for LIB in $(cat $LDD_OUT | grep -v "${CURRENT_BLACKLIST}" | awk '{print $1 $2 $3}'); do
				# split the entry into an array, ex:
				# libm.so.6 => /lib/libm.so.6 would be split into:
				# LIBLINK[0]   LIBLINK[1]
				local LIBLINK=(${LIB//=>/ })
				lib_search
			done
		else
			# Case 2: not a dynamic
			pdebug "\t\t\t(Not a dynamic.)"
			rm -f $LDD_OUT
			continue
		fi	
		rm -f $LDD_OUT
	done

}

lib_search(){

	# if activated, start by searching the lib locally
	if [ "x$LOCALSEARCH" == "x1" ]; then
		cd $LOCALSEARCHDIR
        	local LOCAL_MATCHES=$(find . -name "${LIBLINK[0]}") # | awk -F '.' '{print $1}')".so\*)
		cd - &>/dev/null
	        if [ "x${LOCAL_MATCHES}" != "x" ]; then
        		for LOCALLIB in ${LOCAL_MATCHES}; do
				get_link_chain "${LOCALSEARCHDIR}"/"${LOCALLIB}" "${LOCALSEARCHDIR}"
				get_dynamic_dependencies -l "${LOCALSEARCHDIR}" "${LOCALLIB}"
				CURRENT_BLACKLIST+="\|${LIBLINK[0]}"
	                done
			# found the libs, we are done
			return
	        fi
		# mark local search as done
	fi

	# search the lib on the system since it was not found earlier
	if [ ! -z ${LIBLINK[1]} ] && [ "x${LIBLINK[1]}" != "xnot" ]; then
		# get chain of symlink for that lib
                get_link_chain "${LIBLINK[1]}"
		CURRENT_BLACKLIST+="\|${LIBLINK[1]}"
        else
                pwarning "\t\tLib '${LIBLINK[0]}' from required dir '$ENTRY' neither found in build directory nor on this system."
                pwarning "\t\tIf this lib is not supplied by another module, this module will probably fail in your final system"
        fi
}
############################################################
#
# Usage: get_link_chain <link> [prefix] 
#
#	<link> must be in absolute form-
#	[prefix] is the prefix to strip from the ouput.
#
# Output:
#	 Lists the symlink chain until a hardlink is found.
get_link_chain() {

	# sanity checks
	if [[ "$1" == /* ]]; then
		[ -e $1 ] || perror "get_link_chain: no such file: $1"
	else
		perror "get_link_chain() requires absolute paths, given: $1"
	fi
	if [ $# == 2 ] ; then
		[ ! -d $2 ] && perror "get_link_chain: $2 is not a directory."
		# got a prefix
		local PREFIX=$(readlink -f $2)
	else
		# mark prefix as not set
		local PREFIX="notset"
	fi

	# canonalize
	local LINK=$(canonicalize $1)

	local CHAIN="$LINK"

	# write the first link in the chain
	if [ "x$PREFIX" != "x" -a "x$PREFIX" != "xnotset" ]; then
		if [ "x${LINK#$PREFIX}" == "x${LINK}" ]; then
			# prefix was not in the link
			echo "$LINK"
		else
			# prefix was in the link
			echo ./"${LINK#$PREFIX}"
		fi 
	else
		# no prefix, copy like it is
		echo "$LINK"
	fi

	# now we check for symlinks
	local TRY=0
	while [ -L "$LINK" ] && [ $TRY -lt 10 ]; do
		let TRY=TRY+1

		# save the directory prefix
		CURRENTDIR=$(dirname "${LINK}")
		# first follow the link
		LINK=$(readlink "$LINK")
		CHAIN+=" -> $LINK"
		# $LINK can be absolute or relative, check cases
		[[ "$LINK" == /* ]] || LINK=$(canonicalize "$CURRENTDIR"/"${LINK}")
		# write the first link in the chain
	        if [ "x$PREFIX" != "x" -a "x$PREFIX" != "xnotset" ]; then
	                if [ "x${LINK#$PREFIX}" == "x${LINK}" ]; then
        	        	# prefix was not in the link
                	        echo "$LINK"
	                else
        	                # prefix was in the link
                	        echo ./"${LINK#$PREFIX}"
	                fi
        	else
                	# no prefix, copy like it is
	                echo "$LINK"
        	fi
	done
	pdebug "\t\t$CHAIN"
}

# Function to get libc and ld-linux
list_basic_libs() {
        for i in $(ldd ${SHELL})
        do
                [ $(echo $i | grep '^/' | grep -c ld) -eq 1 -o  $(echo $i | grep '^/' | grep -c libc.so) -eq 1 ] && get_link_chain $i
        done
}