summaryrefslogtreecommitdiffstats
path: root/helper/binutil.inc
blob: 35e3501501e2510c48f85d53cca197cc40f4d3eb (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
#!/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=""

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

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

		pdebug "Processing $BINARY ..."
		
		local LDD_OUT="ldd_output"
		if ldd $BINARY > $LDD_OUT; then
			# Case 1: dynamic
			for LIB in $(cat $LDD_OUT | grep -v $(echo $BLACKLIST|sed 's/ /\\|/g') | 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
			rm $LDD_OUT
		else
			# Case 2: not a dynamic
			pdebug "$BINARY not a dynamic, skipping."
			continue
		fi	
	done
}

lib_search(){

	pdebug "\tSearching for ${liblink[0]}..."
	# 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 llib in ${LOCAL_MATCHES}; do
	        	        pdebug "\t\tFound locally, copying ${LOCALSEARCHDIR}/${llib}"
				get_link_chain "${LOCALSEARCHDIR}"/"${llib}" "${LOCALSEARCHDIR}"
				
	                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
		pdebug "\t\tNot found locally but in system, copying ${liblink[1]}"
		# get chain of symlink for that lib
                get_link_chain ${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=$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\tCHAIN: $CHAIN"
}