Gentoo Archives: gentoo-commits

From: "Michael Haubenwallner (haubi)" <haubi@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] gentoo-alt r1628 - in trunk/aix-miscutils: . aixdll ldd
Date: Tue, 06 May 2008 13:57:39
Message-Id: E1JtNfd-0004F2-Vw@stork.gentoo.org
1 Author: haubi
2 Date: 2008-05-06 13:57:29 +0000 (Tue, 06 May 2008)
3 New Revision: 1628
4
5 Added:
6 trunk/aix-miscutils/aixdll/aixdll.in
7 trunk/aix-miscutils/aixdll/aixdll.sh
8 trunk/aix-miscutils/ldd/Dependency.h
9 trunk/aix-miscutils/ldd/Executable.h
10 trunk/aix-miscutils/ldd/Object.h
11 trunk/aix-miscutils/ldd/ObjectKey.h
12 trunk/aix-miscutils/ldd/ObjectReader.cc
13 trunk/aix-miscutils/ldd/ObjectReader.h
14 trunk/aix-miscutils/ldd/SearchPath.h
15 trunk/aix-miscutils/ldd/SharedObject.h
16 trunk/aix-miscutils/ldd/StaticObject.h
17 trunk/aix-miscutils/ldd/aixdll-query.cc
18 trunk/aix-miscutils/ldd/ldd.cc
19 trunk/aix-miscutils/ldd/smartptr.h
20 Removed:
21 trunk/aix-miscutils/aixdll/aixdll
22 trunk/aix-miscutils/ldd/ldd
23 Modified:
24 trunk/aix-miscutils/aixdll/Makefile.am
25 trunk/aix-miscutils/configure.ac
26 trunk/aix-miscutils/ldd/Makefile.am
27 Log:
28 reimplemented 'ldd for aix with GNU-like output' in c++.
29 additionally, 'aixdll-query' is another c++-binary now reusing the same aix-dll-reader.
30
31 Modified: trunk/aix-miscutils/aixdll/Makefile.am
32 ===================================================================
33 --- trunk/aix-miscutils/aixdll/Makefile.am 2008-04-21 18:37:05 UTC (rev 1627)
34 +++ trunk/aix-miscutils/aixdll/Makefile.am 2008-05-06 13:57:29 UTC (rev 1628)
35 @@ -2,8 +2,8 @@
36 # Distributed under the terms of the GNU General Public License v2
37 # Author: Michael Haubenwallner <haubi@g.o>
38
39 -sbin_SCRIPTS = aixdll
40 +sbin_SCRIPTS = aixdll.sh aixdll
41
42 -EXTRA_DIST = aixdll
43 +EXTRA_DIST = aixdll.sh aixdll.in
44
45 MAINTAINERCLEANFILES = Makefile.in
46
47 Deleted: trunk/aix-miscutils/aixdll/aixdll
48 ===================================================================
49 --- trunk/aix-miscutils/aixdll/aixdll 2008-04-21 18:37:05 UTC (rev 1627)
50 +++ trunk/aix-miscutils/aixdll/aixdll 2008-05-06 13:57:29 UTC (rev 1628)
51 @@ -1,494 +0,0 @@
52 -#! /usr/bin/env bash
53 -# Copyright 2008 Gentoo Foundation
54 -# Distributed under the terms of the GNU General Public License v2
55 -# Author: Michael Haubenwallner <haubi@g.o>
56 -#
57 -# Utilities for dynamic link libraries (aka. shared objects) on AIX.
58 -#
59 -
60 -PS4='(${LINENO})+ '
61 -
62 -ACTION=${0##*/}
63 -[[ ${ACTION} == 'aixdll-'* ]] && ACTION=${ACTION#aixdll-} || ACTION=
64 -
65 -die() {
66 - [[ $# -gt 0 ]] && echo "${ACTION}: $@" >&2
67 - exit 1
68 -}
69 -
70 -_aixdll_cutoff() {
71 - local line=$1
72 - local minlen=$2
73 - local maxcol=$((${#line}-${minlen}))
74 - local tmpline value
75 - if [[ ${line:$((maxcol-1)):1} != ' ' ]]; then
76 - tmpline=${line:0:${maxcol}}
77 - tmpline=${tmpline% *}
78 - maxcol=$((${#tmpline}+1))
79 - fi
80 - value=${line:${maxcol}}
81 - echo ${value}
82 - echo "${line%${value}}"
83 -}
84 -
85 -_aixdll_read_RUNPATH_DEPLIBS() {
86 - # Reads stdin up to the first empty line.
87 - # The first line on stdin must be:
88 - # "INDEX PATH BASE MEMBER "
89 - # The blank-counts in this line are used to parse the data.
90 - #
91 - # Output:
92 - # Two lines going to stdout:
93 - # "/path1:/path2"
94 - # "'lib1.a(shr1.o)' '/path/lib2.a(shr2.o)' 'lib3.so'"
95 - local line
96 - local runpath= deplibs=
97 - local haveHeader=false
98 - local dynMEMBER dynBASE dynPATH
99 -
100 - # global constants to calculate once only
101 - declare -i PATHlen=0 BASElen=0 MEMBERlen=0
102 - declare -i PATHmin=0 BASEmin=0 MEMBERmin=0
103 -
104 - while IFS= read line
105 - do
106 - # empty line marks end of ImportFileStrings section
107 - [[ ${line} ]] || break
108 - if [[ ${line} == "INDEX "* ]]; then
109 - haveHeader=true
110 - if [[ ${PATHmin} -eq 0 ]]; then
111 - MEMBERlen=${#line}
112 - line=${line%MEMBER *}
113 - MEMBERmin=${#line}
114 - MEMBERlen=$((MEMBERlen-MEMBERmin))
115 - BASElen=${MEMBERmin}
116 - line=${line%BASE *}
117 - BASEmin=${#line}
118 - BASElen=$((BASElen-BASEmin))
119 - PATHlen=${BASEmin}
120 - line=${line%PATH *}
121 - PATHmin=${#line}
122 - PATHlen=$((PATHlen-PATHmin))
123 - fi
124 - continue
125 - fi
126 - ${haveHeader} || continue
127 -
128 - { IFS= read dynMEMBER; IFS= read line; } <<-EOC
129 - $(_aixdll_cutoff "${line}" ${MEMBERlen})
130 - EOC
131 - { IFS= read dynBASE; IFS= read line; } <<-EOC
132 - $(_aixdll_cutoff "${line}" ${BASElen})
133 - EOC
134 - { IFS= read dynPATH; IFS= read line; } <<-EOC
135 - $(_aixdll_cutoff "${line}" ${PATHlen})
136 - EOC
137 -
138 - if [[ ! ${dynBASE} && ${dynPATH} ]]; then
139 - runpath=${dynPATH}
140 - continue
141 - fi
142 -
143 - [[ ${dynBASE} && ${dynBASE} != .. && ${dynBASE} != . ]] || continue
144 -
145 - deplibs="${deplibs} '${dynPATH%/}${dynPATH:+/}${dynBASE}${dynMEMBER:+(}${dynMEMBER}${dynMEMBER:+)}'"
146 - done
147 -
148 - echo "${runpath}"
149 - echo "${deplibs}"
150 -}
151 -
152 -aixdll_query() {
153 - # Uses /usr/bin/dump to extract information from object files
154 - # or archive libraries.
155 - #
156 - # First argument:
157 - # either
158 - # "/bin/true"
159 - # queries binary information from file.
160 - # or
161 - # "/lib/libc.a"
162 - # queries binary information for each archive member.
163 - # or
164 - # "/lib/libc.a(shr.o)"
165 - # queries binary information for specified archive members,
166 - # archive-members can contain shell-wildcards (*?).
167 - # Further arguments:
168 - # any combination of
169 - # FILE MEMBER SHROBJ FLAGS FORMAT RUNPATH DEPLIBS
170 - #
171 - # Output on stdout:
172 - # One line for each file or archive member, to be evaluated in
173 - # another shell environment, setting at least these variables:
174 - # FILE='...';MEMBER='...';SHROBJ=[true|false]
175 - # The format for each variable is
176 - # either (for '/bin/true')
177 - # FILE='/bin/true'
178 - # MEMBER=''
179 - # FLAGS=
180 - # FORMAT=
181 - # RUNPATH=
182 - # DEPLIBS=
183 - # SHROBJ=false
184 - # FLAGS=' RELFLG EXEC LNNO DYNLOAD DEP__SYSTEM '
185 - # FORMAT='32-bit XCOFF'
186 - # RUNPATH='/usr/lib:/lib:/usr/lpp/xlC/lib'
187 - # DEPLIBS=" 'libc.a(shr.o)'"
188 - # or (for '/lib/libc.a')
189 - # FILE='/lib/libc.a'
190 - # MEMBER='ptrgl_64_64.o'
191 - # FLAGS=
192 - # FORMAT=
193 - # RUNPATH=
194 - # DEPLIBS=
195 - # SHROBJ=false
196 - # FLAGS=' DEP_SYSTEM '
197 - # FORMAT='64-bit XCOFF'
198 - # <newline for each archive member>
199 - # FILE='/lib/libc.a'
200 - # MEMBER='shr.o'
201 - # FLAGS=
202 - # FORMAT=
203 - # RUNPATH=
204 - # DEPLIBS=
205 - # SHROBJ=true
206 - # FLAGS=' EXEC DYNLOAD SHROBJ DEP__SYSTEM '
207 - # FORMAT='32-bit XCOFF'
208 - # RUNPATH='/usr/lib:/lib'
209 - # DEPLIBS=" '/unix' 'libcrypt.a(shr.o)'"
210 - # <newline>
211 - # or (for '/lib/libc.a(shr*)')
212 - # FILE='/lib/libc.a'
213 - # MEMBER='shr.o'
214 - # FLAGS=
215 - # FORMAT=
216 - # RUNPATH=
217 - # DEPLIBS=
218 - # SHROBJ=true
219 - # FLAGS=' EXEC DYNLOAD SHROBJ DEP__SYSTEM '
220 - # FORMAT='32-bit XCOFF'
221 - # RUNPATH='/usr/lib:/lib'
222 - # DEPLIBS=" '/unix' 'libcrypt.a(shr.o)'"
223 - # <newline>
224 - # FILE='/lib/libc.a'
225 - # MEMBER='shr_64.o'
226 - # FLAGS=
227 - # FORMAT=
228 - # RUNPATH=
229 - # DEPLIBS=
230 - # SHROBJ=true
231 - # FLAGS=' EXEC DYNLOAD SHROBJ DEP__SYSTEM '
232 - # FORMAT='64-bit XCOFF'
233 - # RUNPATH='/usr/lib:/lib'
234 - # DEPLIBS=" '/unix' 'libcrypt.a(shr_64.o)'"
235 - # <newline>
236 -
237 - local dll=$1 shrobj=
238 - shift
239 - local what="$*"
240 - local dumpopts='vo' line section
241 -
242 - : ${what:="FILE MEMBER SHROBJ FLAGS FORMAT RUNPATH DEPLIBS"}
243 - what=" ${what} "
244 -
245 - if [[ ${dll} == *'('*')'* ]]; then
246 - shrobj=${dll#*(}
247 - shrobj="${shrobj%)}"
248 - dll=${dll%(${shrobj})}
249 - fi
250 -
251 - [[ ${what} == *" RUNPATH "* \
252 - || ${what} == *" DEPLIBS "* \
253 - ]] && dumpopts="${dumpopts}H"
254 -
255 - # sections from 'dump -Hov'
256 - # ***Object Module Header***
257 - # ***Optional Header***
258 - # ***Import File Strings***
259 - # ***Loader Section***
260 - local usethis=false linebreak=: thisshrobj= x
261 - while IFS= read line
262 - do
263 - if [[ ${line} == *: ]]; then
264 - # new archive member
265 - # line="/lib/libc.a[shr.o]:"
266 - usethis=false
267 - if [[ ${line} == "${dll}${shrobj:+[}${shrobj}${shrobj:+]}:" ]] \
268 - || [[ ${line} == "${dll}["${shrobj:-*}"]:" ]] \
269 - ; then
270 - thisshrobj=${line#${dll}}
271 - thisshrobj=${thisshrobj%:}
272 - thisshrobj=${thisshrobj#[}
273 - thisshrobj=${thisshrobj%]}
274 - usethis=true
275 - ${linebreak}
276 - linebreak=echo
277 - for x in ${what}; do
278 - echo -n "${x}=;"
279 - done
280 - [[ ${what} == *" FILE "* ]] &&
281 - echo -n "FILE='${dll}';"
282 - # "FILE='/lib/libc.a'
283 - [[ ${what} == *" MEMBER "* ]] &&
284 - echo -n "MEMBER='${thisshrobj}';"
285 - # "MEMBER='shr.o';"
286 - fi
287 - continue
288 - fi
289 -
290 - ${usethis} || continue
291 -
292 - case "${section},${line}" in
293 - *,) # empty line: end of section
294 - section=
295 - continue
296 - ;;
297 - *,*'***Import File Strings***')
298 - # parse complete section separately using
299 - # _aixdll_read_RUNPATH_DEPLIBS()
300 - { IFS= read line
301 - [[ ${what} == *" RUNPATH "* ]] &&
302 - echo -n "RUNPATH='${line}';"
303 - IFS= read line
304 - [[ ${what} == *" DEPLIBS "* ]] &&
305 - echo -n "DEPLIBS=\"${line}\";"
306 - } <<-EOC
307 - $(_aixdll_read_RUNPATH_DEPLIBS)
308 - EOC
309 - continue
310 - ;;
311 - *,*'***')
312 - # new section
313 - section=${line//\*} # stars
314 - section=${section// } # tabs
315 - section=${section// } # blanks
316 - continue
317 - ;;
318 - "ObjectModuleHeader,Flags="*)
319 - # line="Flags=( EXEC DYNLOAD SHROBJ DEP__SYSTEM )"
320 - if [[ ${what} == *" SHROBJ "* ]]; then
321 - echo -n "SHROBJ="
322 - [[ ${line} == *" SHROBJ "* ]] &&
323 - echo -n "true;" ||
324 - echo -n "false;"
325 - fi
326 - [[ ${what} == *" FLAGS "* ]] || continue
327 - line=${line#Flags=(}
328 - line=${line%)}
329 - echo -n "FLAGS='${line}';"
330 - # "FLAGS=' EXEC DYNLOAD SHROBJ DEP__SYSTEM ';"
331 - continue
332 - ;;
333 - "ObjectModuleHeader,Magic = "*)
334 - # line="Magic = 0x1df (32-bit XCOFF)"
335 - # line="Magic = 0x1f7 (64-bit XCOFF)"
336 - [[ ${what} == *" FORMAT "* ]] || continue
337 - line=${line#Magic = *(}
338 - line=${line%)}
339 - echo -n "FORMAT='${line}';"
340 - # "FORMAT='32-bit XCOFF';"
341 - # "FORMAT='64-bit XCOFF';"
342 - continue
343 - ;;
344 - "ImportFileStrings,INDEX"*)
345 - esac
346 - done <<-EOF
347 - $(/usr/bin/dump -X32_64 -${dumpopts} "${dll}" 2>/dev/null)
348 - EOF
349 - ${linebreak}
350 -}
351 -
352 -aixdll_find_unprepared() {
353 - find "$1" -type f -name 'lib*.a' -print
354 -}
355 -
356 -aixdll_find_prepared() {
357 - find "$1" -type d -name 'lib*.a.d' -print
358 -}
359 -
360 -aixdll_is_prepared() {
361 - local what=$1
362 - [[ ${what##*/} == lib*.a.d ]]
363 -}
364 -
365 -aixdll_get_preparedir_for_lib() {
366 - echo "${1%.d}.d"
367 -}
368 -
369 -aixdll_get_lib_for_preparedir() {
370 - echo "${1%.d}"
371 -}
372 -
373 -aixdll_prepare_for_merge() {
374 - # $0 target-library [source-library]
375 - local libsrc=${2-${1}}
376 - local libad=$(aixdll_get_preparedir_for_lib "${1}")
377 - mkdir -p "${libad}" || die "Cannot create ${libad}"
378 - pushd "${libad}" >/dev/null || die "Cannot cd to ${libad}"
379 - local status
380 - /usr/ccs/bin/ar -X32_64 -x "${libsrc}"
381 - status=$?
382 - popd >/dev/null || die "Cannot cd back from ${libad}"
383 - if [[ ${status} -ne 0 ]]; then
384 - rmdir "${libad}" >&/dev/null
385 - die "Cannot un-ar ${libsrc}"
386 - fi
387 - true
388 -}
389 -
390 -aixdll_finish_merge_single() {
391 - local arg keepdir
392 - local libad
393 - for arg
394 - do
395 - case ${arg} in
396 - --keepdir=*)
397 - keepdir=${arg#*=}
398 - continue
399 - ;;
400 - *)
401 - libad=$(aixdll_get_preparedir_for_lib "${arg}")
402 - ;;
403 - esac
404 - done
405 -
406 - : ${keepdir:=true}
407 -
408 - aixdll_is_prepared "${libad}" || return 0
409 - local liba=$(aixdll_get_lib_for_preparedir "${libad}")
410 - local f
411 -
412 - if [[ -d ${libad} && $(ls -A "${libad}/") ]]; then
413 - pushd "${libad}" >/dev/null || die "Cannot cd to ${libad}"
414 - rm -f "./${liba##*/}.new" || die "Cannot remove ${liba##*/}.new"
415 - /usr/ccs/bin/ar -coqszvl -X 32_64 "./${liba##*/}.new" ./* || die "Cannot recreate ${liba}"
416 - mv -f "./${liba##*/}.new" "${liba}" || die "Cannot move ${liba##*/}.new to ${liba}"
417 - popd >/dev/null || die "Cannot cd back from ${libad}"
418 - elif [[ -f ${liba} ]]; then
419 - rm -f "${liba}" || die "Cannot prune '${liba}'"
420 - keepdir=false
421 - fi
422 -
423 - if [[ -d ${libad} ]] && ! ${keepdir}; then
424 - pushd "${libad}" >/dev/null || die "Cannot cd to ${libad}"
425 - rm -f ./* || die "Cannot prune '${libad}/*'"
426 - popd >/dev/null || die "Cannot cd back from ${libad}"
427 - rmdir "${libad}" || die "Cannot prune '${libad}'"
428 - fi
429 - true
430 -}
431 -
432 -aixdll_finish_merge() {
433 - local arg status keepdir
434 - for arg
435 - do
436 - [[ ${arg} == --keepdir=* ]] && keepdir=${arg#*=}
437 - done
438 -
439 - for arg
440 - do
441 - [[ ${arg} != --* ]] || continue
442 - ( aixdll_finish_merge_single --keepdir=${keepdir} "${arg}" ) || status=$?
443 - done
444 - return ${status}
445 -}
446 -
447 -aixdll_merge_runtime() {
448 - [[ $# -gt 0 ]] || return 0
449 - local arg target current curdir libad finish keepdir
450 - local curdir=$(pwd)
451 - for arg
452 - do
453 - case "${arg}" in
454 - --target=*) target=${arg#*=} ;;
455 - --current=*) current=${arg#*=} ;;
456 - --finish=*) finish=${arg#*=} ;;
457 - --keepdir=*) keepdir=${arg#*=} ;;
458 - --*) die "Invalid argument ${arg}" ;;
459 - esac
460 - done
461 - : ${finish:=true}
462 - [[ ${target} ]] || die "Missing --target"
463 - [[ ${target} == /* ]] || target=${curdir}/${target}
464 - [[ ${current} && ${current} != /* ]] && current=${curdir}/${current}
465 - libad=$(aixdll_get_preparedir_for_lib "${target}")
466 - local line status
467 - local FILE MEMBER SHROBJ FLAGS
468 - for arg
469 - do
470 - [[ ${arg} == '--'* ]] && continue
471 - [[ ${arg} == /* ]] || arg=${curdir}/${arg}
472 -
473 - while IFS= read line
474 - do
475 - [[ ${line} == *SHROBJ=* ]] || continue
476 - eval "${line}"
477 - ${SHROBJ} || continue
478 - mkdir -p "${libad}" || die "Cannot create '${libad}'"
479 - pushd "${libad}" >/dev/null || die "Cannot cd to ${libad}"
480 - /usr/ccs/bin/ar -X32_64 -x "${FILE}" "${MEMBER}"
481 - status=$?
482 - if [[ ${status} -ne 0 ]]; then
483 - popd >/dev/null || die "Cannot cd back from ${libad}"
484 - rmdir "${libad}" >&/dev/null
485 - die "Cannot extract '${MEMBER}' of '${FILE}'"
486 - fi
487 - if [[ ${arg} != "${current}" ]]; then
488 - [[ ${FLAGS} == *" LOADONLY "* ]] ||
489 - /usr/ccs/bin/strip -e "./${MEMBER}" ||
490 - die "Cannot set flag LOADONLY for ${MEMBER}"
491 - else
492 - [[ ${FLAGS} != *" LOADONLY "* ]] ||
493 - /usr/ccs/bin/strip -E "./${MEMBER}" ||
494 - die "Cannot drop flag LOADONLY from ${MEMBER}"
495 - fi
496 - popd >/dev/null || die "Cannot cd back from ${libad}"
497 - done <<-EOF
498 - $(aixdll_query "${arg}" FILE MEMBER SHROBJ FLAGS)
499 - EOF
500 - :
501 - done
502 - ${finish} || return 0
503 - aixdll_finish_merge --keepdir=${keepdir} "${libad}"
504 -}
505 -
506 -aixdll_help() {
507 - cat <<EOF
508 -Known actions:
509 - --query
510 - --find-unprepared
511 - --find-prepared
512 - --is-prepared
513 - --prepare-for-merge
514 - --finish-merge
515 - --merge-runtime
516 -EOF
517 -}
518 -
519 -aixdll_main() {
520 - : ${ACTION:=help}
521 - while [[ ${1:+set} ]]
522 - do
523 - case ${1} in
524 - --help | \
525 - --query | \
526 - --find-unprepared | \
527 - --find-prepared | \
528 - --is-prepared | \
529 - --prepare-for-merge | \
530 - --finish-merge | \
531 - --merge-runtime )
532 - ACTION=${1#--}
533 - ;;
534 - --debug) set -x ;;
535 - *) break ;;
536 - esac
537 - shift
538 - done
539 -
540 - aixdll_${ACTION//-/_} "$@"
541 -}
542 -
543 -aixdll_main "$@"
544 -
545 -exit $?
546
547 Added: trunk/aix-miscutils/aixdll/aixdll.in
548 ===================================================================
549 --- trunk/aix-miscutils/aixdll/aixdll.in (rev 0)
550 +++ trunk/aix-miscutils/aixdll/aixdll.in 2008-05-06 13:57:29 UTC (rev 1628)
551 @@ -0,0 +1,22 @@
552 +#! /usr/bin/env bash
553 +# Copyright 2008 Gentoo Foundation
554 +# Distributed under the terms of the GNU General Public License v2
555 +# Author: Michael Haubenwallner <haubi@g.o>
556 +
557 +prefix="@prefix@"
558 +exec_prefix="@exec_prefix@"
559 +
560 +if [[ -f "@sbindir@"/functions.sh ]]; then
561 + . "@sbindir@"/functions.sh
562 +else
563 + die() {
564 + [[ $# -gt 0 ]] && echo "${ACTION}: $@" >&2
565 + exit 1
566 + }
567 +fi
568 +
569 +. "@sbindir@"/aixdll.sh
570 +
571 +aixdll_main "$@"
572 +
573 +exit $?
574
575 Copied: trunk/aix-miscutils/aixdll/aixdll.sh (from rev 1626, trunk/aix-miscutils/aixdll/aixdll)
576 ===================================================================
577 --- trunk/aix-miscutils/aixdll/aixdll.sh (rev 0)
578 +++ trunk/aix-miscutils/aixdll/aixdll.sh 2008-05-06 13:57:29 UTC (rev 1628)
579 @@ -0,0 +1,382 @@
580 +# Copyright 2008 Gentoo Foundation
581 +# Distributed under the terms of the GNU General Public License v2
582 +# Author: Michael Haubenwallner <haubi@g.o>
583 +#
584 +# Utilities for dynamic link libraries (aka. shared objects) on AIX.
585 +#
586 +
587 +PS4='(${LINENO})+ '
588 +
589 +AIXDLL_ACTION=${0##*/}
590 +[[ ${AIXDLL_ACTION} == 'aixdll-'* ]] && AIXDLL_ACTION=${AIXDLL_ACTION#aixdll-} || AIXDLL_ACTION=
591 +
592 +_aixdll_die() {
593 + if type die >&/dev/null; then
594 + [[ $# -gt 0 ]] && die "${AIXDLL_ACTION}: $@"
595 + die
596 + else
597 + [[ $# -gt 0 ]] && echo "${AIXDLL_ACTION}: $@" >&2
598 + exit 1
599 + fi
600 +}
601 +
602 +_aixdll_cutoff() {
603 + local line=$1
604 + local minlen=$2
605 + local maxcol=$((${#line}-${minlen}))
606 + local tmpline value
607 + if [[ ${line:$((maxcol-1)):1} != ' ' ]]; then
608 + tmpline=${line:0:${maxcol}}
609 + tmpline=${tmpline% *}
610 + maxcol=$((${#tmpline}+1))
611 + fi
612 + value=${line:${maxcol}}
613 + echo ${value}
614 + echo "${line%${value}}"
615 +}
616 +
617 +_aixdll_read_RUNPATH_DEPLIBS() {
618 + # Reads stdin up to the first empty line.
619 + # The first line on stdin must be:
620 + # "INDEX PATH BASE MEMBER "
621 + # The blank-counts in this line are used to parse the data.
622 + #
623 + # Output:
624 + # Two lines going to stdout:
625 + # "/path1:/path2"
626 + # "'lib1.a(shr1.o)' '/path/lib2.a(shr2.o)' 'lib3.so'"
627 + local line
628 + local runpath= deplibs=
629 + local haveHeader=false
630 + local dynMEMBER dynBASE dynPATH
631 +
632 + # global constants to calculate once only
633 + declare -i PATHlen=0 BASElen=0 MEMBERlen=0
634 + declare -i PATHmin=0 BASEmin=0 MEMBERmin=0
635 +
636 + while IFS= read line
637 + do
638 + # empty line marks end of ImportFileStrings section
639 + [[ ${line} ]] || break
640 + if [[ ${line} == "INDEX "* ]]; then
641 + haveHeader=true
642 + if [[ ${PATHmin} -eq 0 ]]; then
643 + MEMBERlen=${#line}
644 + line=${line%MEMBER *}
645 + MEMBERmin=${#line}
646 + MEMBERlen=$((MEMBERlen-MEMBERmin))
647 + BASElen=${MEMBERmin}
648 + line=${line%BASE *}
649 + BASEmin=${#line}
650 + BASElen=$((BASElen-BASEmin))
651 + PATHlen=${BASEmin}
652 + line=${line%PATH *}
653 + PATHmin=${#line}
654 + PATHlen=$((PATHlen-PATHmin))
655 + fi
656 + continue
657 + fi
658 + ${haveHeader} || continue
659 +
660 + { IFS= read dynMEMBER; IFS= read line; } <<-EOC
661 + $(_aixdll_cutoff "${line}" ${MEMBERlen})
662 + EOC
663 + { IFS= read dynBASE; IFS= read line; } <<-EOC
664 + $(_aixdll_cutoff "${line}" ${BASElen})
665 + EOC
666 + { IFS= read dynPATH; IFS= read line; } <<-EOC
667 + $(_aixdll_cutoff "${line}" ${PATHlen})
668 + EOC
669 +
670 + if [[ ! ${dynBASE} && ${dynPATH} ]]; then
671 + runpath=${dynPATH}
672 + continue
673 + fi
674 +
675 + [[ ${dynBASE} && ${dynBASE} != .. && ${dynBASE} != . ]] || continue
676 +
677 + deplibs="${deplibs} '${dynPATH%/}${dynPATH:+/}${dynBASE}${dynMEMBER:+(}${dynMEMBER}${dynMEMBER:+)}'"
678 + done
679 +
680 + echo "${runpath}"
681 + echo "${deplibs}"
682 +}
683 +
684 +aixdll_query() {
685 + # Uses /usr/bin/dump to extract information from object files
686 + # or archive libraries.
687 + #
688 + # First argument:
689 + # either
690 + # "/bin/true"
691 + # queries binary information from file.
692 + # or
693 + # "/lib/libc.a"
694 + # queries binary information for each archive member.
695 + # or
696 + # "/lib/libc.a(shr.o)"
697 + # queries binary information for specified archive members,
698 + # archive-members can contain shell-wildcards (*?).
699 + # Further arguments:
700 + # any combination of
701 + # FILE MEMBER SHROBJ FLAGS FORMAT RUNPATH DEPLIBS
702 + #
703 + # Output on stdout:
704 + # One line for each file or archive member, to be evaluated in
705 + # another shell environment, setting at least these variables:
706 + # FILE='...';MEMBER='...';SHROBJ=[true|false]
707 + # The format for each variable is
708 + # either (for '/bin/true')
709 + # FILE='/bin/true'
710 + # MEMBER=''
711 + # FLAGS=
712 + # FORMAT=
713 + # RUNPATH=
714 + # DEPLIBS=
715 + # SHROBJ=false
716 + # FLAGS=' EXEC DYNLOAD SHROBJ DEP__SYSTEM '
717 + # FORMAT='32-bit XCOFF'
718 + # RUNPATH='/usr/lib:/lib:/usr/lpp/xlC/lib'
719 + # DEPLIBS=" 'libc.a(shr.o)'"
720 + # or (for '/lib/libc.a')
721 + # FILE='/lib/libc.a'
722 + # MEMBER='ptrgl_64_64.o'
723 + # FLAGS=
724 + # FORMAT=
725 + # RUNPATH=
726 + # DEPLIBS=
727 + # SHROBJ=false
728 + # FLAGS=' DEP_SYSTEM '
729 + # FORMAT='64-bit XCOFF'
730 + # <newline for each archive member>
731 + # FILE='/lib/libc.a'
732 + # MEMBER='shr.o'
733 + # FLAGS=
734 + # FORMAT=
735 + # RUNPATH=
736 + # DEPLIBS=
737 + # SHROBJ=true
738 + # FLAGS=' EXEC DYNLOAD SHROBJ DEP__SYSTEM '
739 + # FORMAT='32-bit XCOFF'
740 + # RUNPATH='/usr/lib:/lib'
741 + # DEPLIBS=" '/unix' 'libcrypt.a(shr.o)'"
742 + # <newline>
743 + # or (for '/lib/libc.a(shr*)')
744 + # FILE='/lib/libc.a'
745 + # MEMBER='shr.o'
746 + # FLAGS=
747 + # FORMAT=
748 + # RUNPATH=
749 + # DEPLIBS=
750 + # SHROBJ=true
751 + # FLAGS=' EXEC DYNLOAD SHROBJ DEP__SYSTEM '
752 + # FORMAT='32-bit XCOFF'
753 + # RUNPATH='/usr/lib:/lib'
754 + # DEPLIBS=" '/unix' 'libcrypt.a(shr.o)'"
755 + # <newline>
756 + # FILE='/lib/libc.a'
757 + # MEMBER='shr_64.o'
758 + # FLAGS=
759 + # FORMAT=
760 + # RUNPATH=
761 + # DEPLIBS=
762 + # SHROBJ=true
763 + # FLAGS=' EXEC DYNLOAD SHROBJ DEP__SYSTEM '
764 + # FORMAT='64-bit XCOFF'
765 + # RUNPATH='/usr/lib:/lib'
766 + # DEPLIBS=" '/unix' 'libcrypt.a(shr_64.o)'"
767 + # <newline>
768 +
769 + aixdll-query "$@"
770 +}
771 +
772 +aixdll_find_unprepared() {
773 + find "$1" -type f -name 'lib*.a' -print
774 +}
775 +
776 +aixdll_find_prepared() {
777 + find "$1" -type d -name 'lib*.a.d' -print
778 +}
779 +
780 +aixdll_is_prepared() {
781 + local what=$1
782 + [[ ${what##*/} == lib*.a.d ]]
783 +}
784 +
785 +aixdll_get_preparedir_for_lib() {
786 + echo "${1%.d}.d"
787 +}
788 +
789 +aixdll_get_lib_for_preparedir() {
790 + echo "${1%.d}"
791 +}
792 +
793 +aixdll_prepare_for_merge() {
794 + # $0 target-library [source-library]
795 + local libsrc=${2-${1}}
796 + local libad=$(aixdll_get_preparedir_for_lib "${1}")
797 + mkdir -p "${libad}" || _aixdll_die "Cannot create ${libad}"
798 + pushd "${libad}" >/dev/null || _aixdll_die "Cannot cd to ${libad}"
799 + local status
800 + /usr/ccs/bin/ar -X32_64 -x "${libsrc}"
801 + status=$?
802 + popd >/dev/null || _aixdll_die "Cannot cd back from ${libad}"
803 + if [[ ${status} -ne 0 ]]; then
804 + rmdir "${libad}" >&/dev/null
805 + _aixdll_die "Cannot un-ar ${libsrc}"
806 + fi
807 + true
808 +}
809 +
810 +aixdll_finish_merge_single() {
811 + local arg keepdir
812 + local libad
813 + for arg
814 + do
815 + case ${arg} in
816 + --keepdir=*)
817 + keepdir=${arg#*=}
818 + continue
819 + ;;
820 + *)
821 + libad=$(aixdll_get_preparedir_for_lib "${arg}")
822 + ;;
823 + esac
824 + done
825 +
826 + : ${keepdir:=true}
827 +
828 + aixdll_is_prepared "${libad}" || return 0
829 + local liba=$(aixdll_get_lib_for_preparedir "${libad}")
830 + local f
831 +
832 + if [[ -d ${libad} && $(ls -A "${libad}/") ]]; then
833 + pushd "${libad}" >/dev/null || _aixdll_die "Cannot cd to ${libad}"
834 + rm -f "./${liba##*/}.new" || _aixdll_die "Cannot remove ${liba##*/}.new"
835 + /usr/ccs/bin/ar -coqszvl -X 32_64 "./${liba##*/}.new" ./* || _aixdll_die "Cannot recreate ${liba}"
836 + mv -f "./${liba##*/}.new" "${liba}" || _aixdll_die "Cannot move ${liba##*/}.new to ${liba}"
837 + popd >/dev/null || _aixdll_die "Cannot cd back from ${libad}"
838 + elif [[ -f ${liba} ]]; then
839 + rm -f "${liba}" || _aixdll_die "Cannot prune '${liba}'"
840 + keepdir=false
841 + fi
842 +
843 + if [[ -d ${libad} ]] && ! ${keepdir}; then
844 + pushd "${libad}" >/dev/null || _aixdll_die "Cannot cd to ${libad}"
845 + rm -f ./* || _aixdll_die "Cannot prune '${libad}/*'"
846 + popd >/dev/null || _aixdll_die "Cannot cd back from ${libad}"
847 + rmdir "${libad}" || _aixdll_die "Cannot prune '${libad}'"
848 + fi
849 + true
850 +}
851 +
852 +aixdll_finish_merge() {
853 + local arg status keepdir
854 + for arg
855 + do
856 + [[ ${arg} == --keepdir=* ]] && keepdir=${arg#*=}
857 + done
858 +
859 + for arg
860 + do
861 + [[ ${arg} != --* ]] || continue
862 + ( aixdll_finish_merge_single --keepdir=${keepdir} "${arg}" ) || status=$?
863 + done
864 + return ${status}
865 +}
866 +
867 +aixdll_merge_runtime() {
868 + [[ $# -gt 0 ]] || return 0
869 + local arg target current curdir libad finish keepdir
870 + local curdir=$(pwd)
871 + for arg
872 + do
873 + case "${arg}" in
874 + --target=*) target=${arg#*=} ;;
875 + --current=*) current=${arg#*=} ;;
876 + --finish=*) finish=${arg#*=} ;;
877 + --keepdir=*) keepdir=${arg#*=} ;;
878 + --*) _aixdll_die "Invalid argument ${arg}" ;;
879 + esac
880 + done
881 + : ${finish:=true}
882 + [[ ${target} ]] || _aixdll_die "Missing --target"
883 + [[ ${target} == /* ]] || target=${curdir}/${target}
884 + [[ ${current} && ${current} != /* ]] && current=${curdir}/${current}
885 + libad=$(aixdll_get_preparedir_for_lib "${target}")
886 + local line status
887 + local FILE MEMBER SHROBJ FLAGS
888 + for arg
889 + do
890 + [[ ${arg} == '--'* ]] && continue
891 + [[ ${arg} == /* ]] || arg=${curdir}/${arg}
892 +
893 + while IFS= read line
894 + do
895 + [[ ${line} == *SHROBJ=* ]] || continue
896 + eval "${line}"
897 + ${SHROBJ} || continue
898 + mkdir -p "${libad}" || _aixdll_die "Cannot create '${libad}'"
899 + pushd "${libad}" >/dev/null || _aixdll_die "Cannot cd to ${libad}"
900 + /usr/ccs/bin/ar -X32_64 -x "${FILE}" "${MEMBER}"
901 + status=$?
902 + if [[ ${status} -ne 0 ]]; then
903 + popd >/dev/null || _aixdll_die "Cannot cd back from ${libad}"
904 + rmdir "${libad}" >&/dev/null
905 + _aixdll_die "Cannot extract '${MEMBER}' of '${FILE}'"
906 + fi
907 + if [[ ${arg} != "${current}" ]]; then
908 + [[ ${FLAGS} == *" LOADONLY "* ]] ||
909 + /usr/ccs/bin/strip -e "./${MEMBER}" ||
910 + _aixdll_die "Cannot set flag LOADONLY for ${MEMBER}"
911 + else
912 + [[ ${FLAGS} != *" LOADONLY "* ]] ||
913 + /usr/ccs/bin/strip -E "./${MEMBER}" ||
914 + _aixdll_die "Cannot drop flag LOADONLY from ${MEMBER}"
915 + fi
916 + popd >/dev/null || _aixdll_die "Cannot cd back from ${libad}"
917 + done <<-EOF
918 + $(aixdll_query "${arg}" FILE MEMBER SHROBJ FLAGS)
919 + EOF
920 + :
921 + done
922 + ${finish} || return 0
923 + aixdll_finish_merge --keepdir=${keepdir} "${libad}"
924 +}
925 +
926 +aixdll_help() {
927 + cat <<EOF
928 +Known actions:
929 + --query
930 + --find-unprepared
931 + --find-prepared
932 + --is-prepared
933 + --prepare-for-merge
934 + --finish-merge
935 + --merge-runtime
936 +EOF
937 +}
938 +
939 +aixdll_main() {
940 + : ${AIXDLL_ACTION:=help}
941 + while [[ ${1:+set} ]]
942 + do
943 + case ${1} in
944 + --help | \
945 + --query | \
946 + --find-unprepared | \
947 + --find-prepared | \
948 + --is-prepared | \
949 + --prepare-for-merge | \
950 + --finish-merge | \
951 + --merge-runtime )
952 + AIXDLL_ACTION=${1#--}
953 + ;;
954 + --debug) set -x ;;
955 + *) break ;;
956 + esac
957 + shift
958 + done
959 +
960 + aixdll_${AIXDLL_ACTION//-/_} "$@"
961 +}
962
963 Modified: trunk/aix-miscutils/configure.ac
964 ===================================================================
965 --- trunk/aix-miscutils/configure.ac 2008-04-21 18:37:05 UTC (rev 1627)
966 +++ trunk/aix-miscutils/configure.ac 2008-05-06 13:57:29 UTC (rev 1628)
967 @@ -5,9 +5,15 @@
968 AC_INIT(aix-miscutils,0.1.svnversion)
969 AC_CONFIG_AUX_DIR([build-aux])
970 AC_PROG_INSTALL
971 -AC_CONFIG_SRCDIR(ldd/ldd)
972 +AC_CONFIG_SRCDIR(aixdll/aixdll.sh)
973 AC_PREREQ(2.52)
974 AC_CANONICAL_HOST
975 AM_INIT_AUTOMAKE
976 -AC_CONFIG_FILES(./Makefile ldd/Makefile aixdll/Makefile)
977 +AC_PROG_CXX
978 +AC_CONFIG_FILES(
979 + Makefile
980 + ldd/Makefile
981 + aixdll/Makefile
982 + aixdll/aixdll
983 +)
984 AC_OUTPUT
985
986 Added: trunk/aix-miscutils/ldd/Dependency.h
987 ===================================================================
988 --- trunk/aix-miscutils/ldd/Dependency.h (rev 0)
989 +++ trunk/aix-miscutils/ldd/Dependency.h 2008-05-06 13:57:29 UTC (rev 1628)
990 @@ -0,0 +1,54 @@
991 +/* Copyright 2008 Gentoo Foundation
992 + * Distributed under the terms of the GNU General Public License v2
993 + * Author: Michael Haubenwallner <haubi@g.o>
994 + */
995 +
996 +#ifndef _aixdll_Dependency_h
997 +#define _aixdll_Dependency_h
998 +
999 +#include <string>
1000 +
1001 +#include "SearchPath.h"
1002 +
1003 +namespace aixdll {
1004 +
1005 +class Dependency : virtual public RefCounted
1006 +{
1007 +public:
1008 + ~Dependency() {}
1009 +
1010 + Dependency()
1011 + : name_(0)
1012 + , key_(0)
1013 + , provider_(0)
1014 + {}
1015 +
1016 + Dependency(ObjectNamePtr name)
1017 + : name_(name)
1018 + , key_(0)
1019 + , provider_(0)
1020 + {}
1021 +
1022 + Dependency(ObjectKeyPtr key)
1023 + : name_(0)
1024 + , key_(key)
1025 + , provider_(0)
1026 + {}
1027 +
1028 + ObjectNamePtr const& name() const { return name_; }
1029 + ObjectKeyPtr const& key() const { return key_; }
1030 +
1031 + ObjectPtr provider() const { return provider_; }
1032 + void setProvider(ObjectPtr provider) { provider_ = provider; }
1033 +
1034 +private:
1035 + ObjectNamePtr name_;
1036 + ObjectKeyPtr key_;
1037 + ObjectPtr provider_;
1038 +};
1039 +
1040 +typedef SmartPtr<Dependency> DependencyPtr;
1041 +
1042 +}
1043 +
1044 +#endif /* _aixdll_Dependency_h */
1045
1046 Added: trunk/aix-miscutils/ldd/Executable.h
1047 ===================================================================
1048 --- trunk/aix-miscutils/ldd/Executable.h (rev 0)
1049 +++ trunk/aix-miscutils/ldd/Executable.h 2008-05-06 13:57:29 UTC (rev 1628)
1050 @@ -0,0 +1,24 @@
1051 +/* Copyright 2008 Gentoo Foundation
1052 + * Distributed under the terms of the GNU General Public License v2
1053 + * Author: Michael Haubenwallner <haubi@g.o>
1054 + */
1055 +
1056 +#ifndef _aixdll_Executable_h
1057 +#define _aixdll_Executable_h
1058 +
1059 +#include "SharedObject.h"
1060 +
1061 +namespace aixdll {
1062 +
1063 +class Executable : public SharedObject
1064 +{
1065 +public:
1066 + ~Executable() {}
1067 + Executable(ObjectKeyPtr const& key, std::string const& flags, std::string const& format)
1068 + : SharedObject(key, flags, format)
1069 + {}
1070 +};
1071 +
1072 +}
1073 +
1074 +#endif /* _aixdll_Executable_h */
1075
1076 Modified: trunk/aix-miscutils/ldd/Makefile.am
1077 ===================================================================
1078 --- trunk/aix-miscutils/ldd/Makefile.am 2008-04-21 18:37:05 UTC (rev 1627)
1079 +++ trunk/aix-miscutils/ldd/Makefile.am 2008-05-06 13:57:29 UTC (rev 1628)
1080 @@ -2,8 +2,33 @@
1081 # Distributed under the terms of the GNU General Public License v2
1082 # Author: Michael Haubenwallner <haubi@g.o>
1083
1084 -bin_SCRIPTS = ldd
1085 +bin_PROGRAMS = ldd aixdll-query
1086
1087 -EXTRA_DIST = ldd
1088 +ldd_SOURCES = \
1089 + Dependency.h \
1090 + Executable.h \
1091 + Object.h \
1092 + ObjectKey.h \
1093 + ObjectReader.cc \
1094 + ObjectReader.h \
1095 + SearchPath.h \
1096 + SharedObject.h \
1097 + StaticObject.h \
1098 + smartptr.h \
1099 + ldd.cc
1100
1101 +aixdll_query_SOURCES = \
1102 + Dependency.h \
1103 + Executable.h \
1104 + Object.h \
1105 + Object.h \
1106 + ObjectKey.h \
1107 + ObjectReader.cc \
1108 + ObjectReader.h \
1109 + SearchPath.h \
1110 + SharedObject.h \
1111 + StaticObject.h \
1112 + smartptr.h \
1113 + aixdll-query.cc
1114 +
1115 MAINTAINERCLEANFILES = Makefile.in
1116
1117 Added: trunk/aix-miscutils/ldd/Object.h
1118 ===================================================================
1119 --- trunk/aix-miscutils/ldd/Object.h (rev 0)
1120 +++ trunk/aix-miscutils/ldd/Object.h 2008-05-06 13:57:29 UTC (rev 1628)
1121 @@ -0,0 +1,121 @@
1122 +/* Copyright 2008 Gentoo Foundation
1123 + * Distributed under the terms of the GNU General Public License v2
1124 + * Author: Michael Haubenwallner <haubi@g.o>
1125 + */
1126 +
1127 +#ifndef _aixdll_Object_h
1128 +#define _aixdll_Object_h
1129 +
1130 +#include <string>
1131 +#include <vector>
1132 +
1133 +#include "smartptr.h"
1134 +
1135 +#include "ObjectKey.h"
1136 +
1137 +namespace aixdll {
1138 +
1139 +class Object : virtual public RefCounted
1140 +{
1141 +public:
1142 + class Flags {
1143 +#undef FLAGS
1144 +#define FLAGS \
1145 + FLAG(SHROBJ) \
1146 + FLAG(EXEC) \
1147 + FLAG(DYNLOAD) \
1148 + FLAG(DEP_SYSTEM) \
1149 + FLAG(DEP__SYSTEM) \
1150 + FLAG(RELFLG) \
1151 + FLAG(LNNO) \
1152 +/* EOF */
1153 +
1154 + public:
1155 +
1156 + enum type {
1157 +#undef FLAG
1158 +#define FLAG(flag) flag,
1159 + FLAGS
1160 + Unknown
1161 + };
1162 +
1163 + static type getFlag(std::string const& name)
1164 + {
1165 +#undef FLAG
1166 +#define FLAG(flag) if (name == #flag) return flag;
1167 + FLAGS
1168 + return Unknown;
1169 + }
1170 +
1171 + static std::string getName(type that)
1172 + {
1173 +#undef FLAG
1174 +#define FLAG(flag) if (flag == that) return std::string(#flag);
1175 + FLAGS
1176 + return std::string("Unknown");
1177 + }
1178 + };
1179 +
1180 + virtual ~Object() {}
1181 +
1182 + Object(ObjectKeyPtr const& key
1183 + , std::string const& flags
1184 + , std::string const& format
1185 + ) : key_(key)
1186 + , flags_()
1187 + , format_(format)
1188 + , resolved_("not found")
1189 + {
1190 + std::string::const_iterator start = flags.begin();
1191 + std::string::const_iterator end = start;
1192 + std::string::const_iterator current = end;
1193 + while(end != flags.end()) {
1194 + current = end++;
1195 + if (*current == ' ') {
1196 + if (current > start) {
1197 + flags_.push_back(Flags::getFlag(std::string(start, current)));
1198 + }
1199 + start = end;
1200 + }
1201 + }
1202 + }
1203 +
1204 + ObjectKeyPtr const& key() const
1205 + { return key_; }
1206 +
1207 + void setResolved(std::string const& resolved)
1208 + { resolved_ = resolved; }
1209 +
1210 + std::string const& getResolved() const
1211 + { return resolved_; }
1212 +
1213 + std::string flags() const
1214 + {
1215 + std::string out;
1216 + for(std::vector<Flags::type>::const_iterator f = flags_.begin()
1217 + ; f != flags_.end()
1218 + ; f++
1219 + ) {
1220 + out += " ";
1221 + out += Flags::getName(*f);
1222 + }
1223 + return out;
1224 + }
1225 +
1226 + std::string const& format() const
1227 + { return format_; }
1228 +
1229 +protected:
1230 + ObjectKeyPtr key_;
1231 +
1232 +private:
1233 + std::vector<Flags::type> flags_;
1234 + std::string format_;
1235 + std::string resolved_;
1236 +};
1237 +
1238 +typedef SmartPtr<Object> ObjectPtr;
1239 +
1240 +}
1241 +
1242 +#endif /* _aixdll_Object_h */
1243
1244 Added: trunk/aix-miscutils/ldd/ObjectKey.h
1245 ===================================================================
1246 --- trunk/aix-miscutils/ldd/ObjectKey.h (rev 0)
1247 +++ trunk/aix-miscutils/ldd/ObjectKey.h 2008-05-06 13:57:29 UTC (rev 1628)
1248 @@ -0,0 +1,151 @@
1249 +/* Copyright 2008 Gentoo Foundation
1250 + * Distributed under the terms of the GNU General Public License v2
1251 + * Author: Michael Haubenwallner <haubi@g.o>
1252 + */
1253 +
1254 +#ifndef _aixdll_ObjectKey_h
1255 +#define _aixdll_ObjectKey_h
1256 +
1257 +#include <string>
1258 +
1259 +#include "smartptr.h"
1260 +
1261 +namespace aixdll {
1262 +
1263 +class ObjectPath : public std::string, virtual public RefCounted
1264 +{
1265 +public:
1266 + ~ObjectPath() {}
1267 +
1268 + ObjectPath(std::string const& path) : std::string(path) {}
1269 +
1270 + std::string const& asIdentifier() const { return *this; }
1271 + std::string const& string() const { return *this; }
1272 +};
1273 +
1274 +typedef SmartPtr<ObjectPath> ObjectPathPtr;
1275 +
1276 +class ObjectName : virtual public RefCounted {
1277 +public:
1278 + ~ObjectName() {}
1279 +
1280 + ObjectName(std::string const& base, std::string const& member)
1281 + : base_(base)
1282 + , member_(member)
1283 + {}
1284 +
1285 + std::string const& base() const { return base_; }
1286 + std::string const& member() const { return member_; }
1287 +
1288 + bool operator< (ObjectName const& that) const
1289 + {
1290 + if (base_ < that.base_) return true;
1291 + if (member_ < that.member_) return true;
1292 + return false;
1293 + }
1294 +
1295 + std::string asIdentifier() const
1296 + {
1297 + std::string identifier = base_;
1298 + if (member_.length() > 0) {
1299 + identifier += "[";
1300 + identifier += member_;
1301 + identifier += "]";
1302 + }
1303 + return identifier;
1304 + }
1305 +
1306 +private:
1307 + std::string base_;
1308 + std::string member_;
1309 +};
1310 +
1311 +typedef SmartPtr<ObjectName> ObjectNamePtr;
1312 +
1313 +static void splitIdentifier(std::string const& identifier,
1314 + ObjectPathPtr &objPath, ObjectNamePtr &objName)
1315 +{
1316 + objPath.forget();
1317 + objName.forget();
1318 +
1319 + std::string::const_iterator end = identifier.end();
1320 + if (end == identifier.begin()) {
1321 + return;
1322 + }
1323 +
1324 + std::string path, base, member;
1325 +
1326 + std::string::const_iterator start = end;
1327 + --start;
1328 + if (*start == ')' || *start == ']') {
1329 + std::string::value_type starter = (*start == ')') ? '(' : '[';
1330 + end = start;
1331 + while(start > identifier.begin()) {
1332 + if (*start == starter) {
1333 + member.assign(start+1, end);
1334 + end = start;
1335 + start--;
1336 + break;
1337 + }
1338 + start--;
1339 + }
1340 + }
1341 + while(start > identifier.begin() && *start != '/') {
1342 + start--;
1343 + }
1344 +
1345 + if (*start == '/') {
1346 + start++;
1347 + }
1348 + base.assign(start, end);
1349 +
1350 + if (start > identifier.begin()) {
1351 + path.assign(identifier.begin(), start);
1352 + }
1353 +
1354 + if (path.length() > 0) {
1355 + objPath.eat(new ObjectPath(path));
1356 + }
1357 + objName.eat(new ObjectName(base, member));
1358 +}
1359 +
1360 +class ObjectKey : virtual public RefCounted {
1361 +public:
1362 + ~ObjectKey() {}
1363 +
1364 + ObjectKey(std::string const& identifier)
1365 + : path_()
1366 + , name_()
1367 + {
1368 + splitIdentifier(identifier, path_, name_);
1369 + }
1370 +
1371 + ObjectKey(ObjectPathPtr const& path, ObjectNamePtr const& name)
1372 + : path_(path)
1373 + , name_(name)
1374 + {}
1375 +
1376 + ObjectPathPtr const& path() const { return path_; }
1377 + ObjectNamePtr const& name() const { return name_; }
1378 +
1379 + std::string asIdentifier() const
1380 + {
1381 + return path_ ? path_->asIdentifier() + name_->asIdentifier() : name_->asIdentifier();
1382 + }
1383 +
1384 + bool operator<(ObjectKey const& that) const
1385 + {
1386 + if (path_ < that.path_) return true;
1387 + if (name_ < that.name_) return true;
1388 + return false;
1389 + }
1390 +private:
1391 + ObjectPathPtr path_;
1392 + ObjectNamePtr name_;
1393 +};
1394 +
1395 +typedef SmartPtr<ObjectKey> ObjectKeyPtr;
1396 +
1397 +}
1398 +
1399 +#endif /* _aixdll_ObjectKey_h */
1400
1401 Added: trunk/aix-miscutils/ldd/ObjectReader.cc
1402 ===================================================================
1403 --- trunk/aix-miscutils/ldd/ObjectReader.cc (rev 0)
1404 +++ trunk/aix-miscutils/ldd/ObjectReader.cc 2008-05-06 13:57:29 UTC (rev 1628)
1405 @@ -0,0 +1,328 @@
1406 +/* Copyright 2008 Gentoo Foundation
1407 + * Distributed under the terms of the GNU General Public License v2
1408 + * Author: Michael Haubenwallner <haubi@g.o>
1409 + */
1410 +
1411 +#include <errno.h>
1412 +#include <string.h>
1413 +#include <stdexcept>
1414 +
1415 +#include "StaticObject.h"
1416 +#include "Executable.h"
1417 +
1418 +#include "ObjectReader.h"
1419 +
1420 +namespace aixdll {
1421 +
1422 +static bool readLine(FILE *file, std::string& line)
1423 +{
1424 + char linebuf[1024];
1425 +
1426 + line = "";
1427 +
1428 + do {
1429 + linebuf[sizeof(linebuf)-1] = '\0';
1430 + char *read = fgets(linebuf, sizeof(linebuf), file);
1431 + if (read == NULL) {
1432 + if (feof(file)) {
1433 + return false;
1434 + }
1435 + throw std::runtime_error(strerror(errno));
1436 + }
1437 + line += read;
1438 + } while(linebuf[sizeof(linebuf)-1] != '\0');
1439 +
1440 + while(line.length() > 0
1441 + && (line[line.length()-1] == '\n' || line[line.length()-1] == '\r')
1442 + ) {
1443 + line.erase(line.length()-1);
1444 + }
1445 + return true;
1446 +}
1447 +
1448 +static void cutoff(std::string& line, std::string::size_type minlen, std::string& out)
1449 +{
1450 + if (line.length() < 1 || line.length() <= minlen) {
1451 + return;
1452 + }
1453 + std::string::size_type blank = line.rfind(" ", line.length() - minlen - 1);
1454 + if (blank == line.npos) {
1455 + return;
1456 + }
1457 + blank++;
1458 + out.assign(line, blank, line.length() - blank);
1459 + line.erase(blank, line.length() - blank);
1460 + std::string::iterator end = out.end();
1461 + while(--end >= out.begin()) {
1462 + if (*end != ' ') {
1463 + break;
1464 + }
1465 + end = out.erase(end);
1466 + }
1467 +}
1468 +
1469 +class ObjectReader::Dumper {
1470 +public:
1471 + Dumper(FILE* file)
1472 + : file_(file)
1473 + {}
1474 +
1475 + ~Dumper()
1476 + {
1477 + if (file_) {
1478 + pclose(file_);
1479 + }
1480 + }
1481 +
1482 + FILE* file() { return file_; }
1483 +private:
1484 + FILE *file_;
1485 +};
1486 +
1487 +void ObjectReader::parseRunpathDeplibs(Dumper *dumper, SharedObjectPtr &object) const
1488 +{
1489 + std::string line;
1490 + bool haveHeader = false;
1491 +
1492 + std::string::size_type MEMBERlen = 0, MEMBERmin = 0;
1493 + std::string::size_type BASElen = 0, BASEmin = 0;
1494 + std::string::size_type PATHlen = 0, PATHmin = 0;
1495 +
1496 + std::string path, base, member;
1497 +
1498 + while(readLine(dumper->file(), line)) {
1499 + if (line.empty()) {
1500 + break;
1501 + }
1502 + if (line.find("INDEX ") == 0) {
1503 + haveHeader = true;
1504 + MEMBERmin = line.rfind("MEMBER ");
1505 + MEMBERlen = line.length() - MEMBERmin;
1506 + BASEmin = line.rfind("BASE ", MEMBERmin);
1507 + BASElen = MEMBERmin - BASEmin;
1508 + PATHmin = line.rfind("PATH ", BASEmin);
1509 + PATHlen = BASEmin - PATHmin;
1510 + continue;
1511 + }
1512 + if (! haveHeader) continue;
1513 +
1514 + cutoff(line, MEMBERlen, member);
1515 + cutoff(line, BASElen, base);
1516 + cutoff(line, PATHlen, path);
1517 +
1518 + if (base == "." || base == "..") {
1519 + continue;
1520 + }
1521 +
1522 + if (base.length() == 0) {
1523 + object->setRunpath(SearchPathPtr(new SearchPath(path)));
1524 + } else
1525 + if (path.length() > 0) {
1526 + object->addDependency
1527 + ( DependencyPtr(new Dependency
1528 + ( ObjectKeyPtr(
1529 + new ObjectKey
1530 + ( ObjectPathPtr(new ObjectPath(path))
1531 + , ObjectNamePtr(new ObjectName(base, member))
1532 + )
1533 + ))
1534 + ));
1535 + } else {
1536 + object->addDependency
1537 + ( DependencyPtr(new Dependency
1538 + ( ObjectNamePtr(new ObjectName(base, member)))
1539 + ));
1540 + }
1541 + }
1542 +}
1543 +
1544 +int ObjectReader::readObjects(std::string const& filename
1545 + , std::string const& identifier
1546 + , ObjectContainer& out
1547 +)
1548 +{
1549 + int rv = 0;
1550 + /* filename-based */
1551 + ObjectPathPtr fileObjPath;
1552 + ObjectNamePtr fileObjName;
1553 + std::string filePath;
1554 +
1555 + std::string base; /* same for filename and identifier */
1556 + std::string member; /* same for filename and identifier */
1557 +
1558 + /* identifier-based */
1559 + ObjectPathPtr idObjPath;
1560 + ObjectNamePtr idObjName;
1561 + std::string idPath;
1562 +
1563 + /* currently read */
1564 + ObjectPathPtr objPath;
1565 + ObjectNamePtr objName;
1566 + std::string currMember;
1567 +
1568 + splitIdentifier(filename, fileObjPath, fileObjName);
1569 + splitIdentifier(identifier, idObjPath, idObjName);
1570 +
1571 + if (idObjPath) {
1572 + idPath = idObjPath->string();
1573 + }
1574 +
1575 + if (fileObjPath) {
1576 + filePath = fileObjPath->string();
1577 + }
1578 + if (fileObjName && fileObjName->base().length() > 0) {
1579 + base = fileObjName->base();
1580 + }
1581 + if (fileObjName && fileObjName->member().length() > 0) {
1582 + member = fileObjName->member();
1583 + }
1584 +
1585 + if (filePath.length() == 0) {
1586 + filePath = "./";
1587 + }
1588 +
1589 + LibraryMemberCache::iterator cachedLib;
1590 + if (member.length() > 0) {
1591 + member.insert(0, "[");
1592 + member.append("]");
1593 + cachedLib = libraryMemberCache_.end();
1594 + } else {
1595 + cachedLib = libraryMemberCache_.find(idPath+base);
1596 + }
1597 +
1598 + if (objectCache_.find(idPath + base + member) != objectCache_.end()) {
1599 + out.push_back(objectCache_[idPath + base + member]);
1600 + return 1;
1601 + }
1602 +
1603 + if (cachedLib != libraryMemberCache_.end()) {
1604 + for(LibraryMemberNameContainer::iterator it = cachedLib->second.begin()
1605 + ; it != cachedLib->second.end()
1606 + ; ++it
1607 + ) {
1608 + out.push_back(objectCache_[idPath + base + *it]);
1609 + ++ rv;
1610 + }
1611 + return rv;
1612 + }
1613 +
1614 + std::string dumpcommand = "/usr/bin/dump -Hov -X32_64 '";
1615 + dumpcommand += filePath;
1616 + dumpcommand += base;
1617 + dumpcommand += "' 2>/dev/null";
1618 +
1619 + Dumper dumper(popen(dumpcommand.c_str(), "r"));
1620 +
1621 + std::string line;
1622 +
1623 + enum { NoSection, ImportFileStrings, ObjectModuleHeader } section = NoSection;
1624 +
1625 + ObjectKeyPtr objectKey;
1626 + std::string flags, format;
1627 +
1628 + ObjectPtr objectPtr;
1629 + SharedObjectPtr sharedObject;
1630 + StaticObjectPtr staticObject;
1631 +
1632 + while(readLine(dumper.file(), line)) {
1633 + if (! line.empty() && line[line.length()-1] == ':') {
1634 + if (objectPtr != NULL) {
1635 + objectCache_[idPath + base + currMember] = objectPtr;
1636 + if (currMember.length() > 0) {
1637 + libraryMemberCache_[idPath + base].push_back(currMember);
1638 + }
1639 + if (member.length() == 0 || member == currMember) {
1640 + out.push_back(objectPtr);
1641 + ++ rv;
1642 + }
1643 + objectPtr.forget();
1644 + sharedObject.forget();
1645 + staticObject.forget();
1646 + }
1647 +
1648 + currMember.clear();
1649 +
1650 + splitIdentifier(std::string(&line[0], &line[line.length()-1]),
1651 + objPath, objName);
1652 +
1653 + currMember = objName->member();
1654 +
1655 + if (currMember.length() > 0) {
1656 + currMember.insert(0, "[");
1657 + currMember.append("]");
1658 + }
1659 +
1660 + if (objName->base() != base || objPath->string() != filePath) {
1661 + /* Huh? */
1662 + throw std::runtime_error("unexpected dump output");
1663 + }
1664 + objectKey.eat(new ObjectKey(idObjPath, objName));
1665 + flags="";
1666 + format="";
1667 + continue;
1668 + }
1669 +
1670 + if (line.empty()) {
1671 + section = NoSection;
1672 + continue;
1673 + }
1674 +
1675 + if (! objectPtr && flags.length() > 0 && format.length() > 0) {
1676 + if (flags.find("SHROBJ") != flags.npos) {
1677 + sharedObject.eat(new SharedObject(objectKey, flags, format));
1678 + objectPtr = sharedObject;
1679 + } else
1680 + if (flags.find("EXEC") != flags.npos) {
1681 + sharedObject.eat(new Executable(objectKey, flags, format));
1682 + objectPtr = sharedObject;
1683 + } else {
1684 + staticObject.eat(new StaticObject(objectKey, flags, format));
1685 + objectPtr =staticObject;
1686 + }
1687 + objectPtr->setResolved(filePath + objName->asIdentifier());
1688 + }
1689 +
1690 + if (line.find("***Object Module Header***") != line.npos) {
1691 + section = ObjectModuleHeader;
1692 + continue;
1693 + }
1694 +
1695 + if (line.find("***Import File Strings***") != line.npos) {
1696 + section = ImportFileStrings;
1697 + parseRunpathDeplibs(&dumper, sharedObject);
1698 + section = NoSection;
1699 + continue;
1700 + }
1701 +
1702 + if (section == ObjectModuleHeader && line.find("Flags=(") == 0) {
1703 + line.erase(0, line.find("("));
1704 + line.erase(0, 1);
1705 + line.erase(line.find(")"));
1706 + flags = line;
1707 + continue;
1708 + }
1709 +
1710 + if (section == ObjectModuleHeader && line.find("Magic = ") == 0) {
1711 + line.erase(0, line.find("("));
1712 + line.erase(0, 1);
1713 + line.erase(line.find(")"));
1714 + format = line;
1715 + continue;
1716 + }
1717 +
1718 + }
1719 + if (objectPtr) {
1720 + objectCache_[idPath + base + currMember] = objectPtr;
1721 + if (currMember.length() > 0) {
1722 + libraryMemberCache_[idPath+base].push_back(currMember);
1723 + }
1724 + if (member.length() == 0 || member == currMember) {
1725 + out.push_back(objectPtr);
1726 + ++ rv;
1727 + }
1728 + }
1729 +
1730 + return rv;
1731 +}
1732 +
1733 +}
1734
1735 Added: trunk/aix-miscutils/ldd/ObjectReader.h
1736 ===================================================================
1737 --- trunk/aix-miscutils/ldd/ObjectReader.h (rev 0)
1738 +++ trunk/aix-miscutils/ldd/ObjectReader.h 2008-05-06 13:57:29 UTC (rev 1628)
1739 @@ -0,0 +1,41 @@
1740 +/* Copyright 2008 Gentoo Foundation
1741 + * Distributed under the terms of the GNU General Public License v2
1742 + * Author: Michael Haubenwallner <haubi@g.o>
1743 + */
1744 +
1745 +#ifndef _aixdll_ObjectReader_h
1746 +#define _aixdll_ObjectReader_h
1747 +
1748 +#include <map>
1749 +#include <string>
1750 +
1751 +#include "SharedObject.h"
1752 +#include "StaticObject.h"
1753 +
1754 +namespace aixdll {
1755 +
1756 +class ObjectReader {
1757 +public:
1758 + typedef std::vector<ObjectPtr> ObjectContainer;
1759 +
1760 + ~ObjectReader() {}
1761 + ObjectReader() : objectCache_(), libraryMemberCache_() {}
1762 +
1763 + int readObjects(std::string const& filename
1764 + , std::string const& identifier
1765 + , ObjectContainer& out
1766 + );
1767 +private:
1768 + class Dumper;
1769 + void parseRunpathDeplibs(Dumper *dumper, SharedObjectPtr &object) const;
1770 +
1771 + std::map<std::string, ObjectPtr> objectCache_;
1772 +
1773 + typedef std::vector<std::string> LibraryMemberNameContainer;
1774 + typedef std::map<std::string, LibraryMemberNameContainer> LibraryMemberCache;
1775 + LibraryMemberCache libraryMemberCache_;
1776 +};
1777 +
1778 +}
1779 +
1780 +#endif /* _aixdll_ObjectReader_h */
1781
1782 Added: trunk/aix-miscutils/ldd/SearchPath.h
1783 ===================================================================
1784 --- trunk/aix-miscutils/ldd/SearchPath.h (rev 0)
1785 +++ trunk/aix-miscutils/ldd/SearchPath.h 2008-05-06 13:57:29 UTC (rev 1628)
1786 @@ -0,0 +1,91 @@
1787 +/* Copyright 2008 Gentoo Foundation
1788 + * Distributed under the terms of the GNU General Public License v2
1789 + * Author: Michael Haubenwallner <haubi@g.o>
1790 + */
1791 +
1792 +#ifndef _aixdll_SearchPath_h
1793 +#define _aixdll_SearchPath_h
1794 +
1795 +#include <string>
1796 +#include <vector>
1797 +
1798 +#include "smartptr.h"
1799 +
1800 +namespace aixdll {
1801 +
1802 +class SearchPath : virtual public RefCounted
1803 +{
1804 +public:
1805 + typedef std::vector<std::string> PathContainer;
1806 +
1807 + ~SearchPath() {}
1808 +
1809 + SearchPath()
1810 + : components_()
1811 + {}
1812 +
1813 + SearchPath(std::string const& separated)
1814 + : components_()
1815 + {
1816 + appendSeparated(separated);
1817 + }
1818 +
1819 + void appendSeparated(std::string const& separated)
1820 + {
1821 + std::string::const_iterator start = separated.begin();
1822 + std::string::const_iterator end = start;
1823 + std::string::const_iterator current = end;
1824 + while(end != separated.end()) {
1825 + current = end++;
1826 + if (*current == ':') {
1827 + if (*(current - 1) == '/') {
1828 + components_.push_back(std::string(start, current));
1829 + } else {
1830 + components_.push_back(std::string(start, current) + "/");
1831 + }
1832 + start = end;
1833 + }
1834 + }
1835 + if (current > start) {
1836 + if (*(end-1) == '/') {
1837 + components_.push_back(std::string(start, end));
1838 + } else {
1839 + components_.push_back(std::string(start, end) + "/");
1840 + }
1841 + }
1842 + }
1843 +
1844 + void append(SearchPath const& that)
1845 + {
1846 + components_.insert(components_.end(), that.components_.begin(), that.components_.end());
1847 + }
1848 +
1849 + PathContainer const& components() const
1850 + { return components_; }
1851 +
1852 + std::string asSeparated() const
1853 + {
1854 + std::string separated;
1855 + char const *sep = "";
1856 + for(PathContainer::const_iterator p = components_.begin()
1857 + ; p != components_.end()
1858 + ; p++
1859 + ) {
1860 + separated += sep;
1861 + separated += *p;
1862 + if (p->length() > 1 && (*p)[p->length()-1] == '/') {
1863 + separated.erase(separated.length()-1);
1864 + }
1865 + sep = ":";
1866 + }
1867 + return separated;
1868 + }
1869 +private:
1870 + PathContainer components_;
1871 +};
1872 +
1873 +typedef SmartPtr<SearchPath> SearchPathPtr;
1874 +
1875 +}
1876 +
1877 +#endif /* _aixdll_SearchPath_h */
1878
1879 Added: trunk/aix-miscutils/ldd/SharedObject.h
1880 ===================================================================
1881 --- trunk/aix-miscutils/ldd/SharedObject.h (rev 0)
1882 +++ trunk/aix-miscutils/ldd/SharedObject.h 2008-05-06 13:57:29 UTC (rev 1628)
1883 @@ -0,0 +1,56 @@
1884 +/* Copyright 2008 Gentoo Foundation
1885 + * Distributed under the terms of the GNU General Public License v2
1886 + * Author: Michael Haubenwallner <haubi@g.o>
1887 + */
1888 +
1889 +#ifndef _aixdll_SharedObject_h
1890 +#define _aixdll_SharedObject_h
1891 +
1892 +#include "Object.h"
1893 +#include "Dependency.h"
1894 +
1895 +namespace aixdll {
1896 +
1897 +class ObjectReader;
1898 +
1899 +class SharedObject : public Object
1900 +{
1901 +public:
1902 + typedef std::vector<DependencyPtr> DependencyContainer;
1903 +
1904 + ~SharedObject() {}
1905 +
1906 + SharedObject(ObjectKeyPtr const& key
1907 + , std::string const& flags
1908 + , std::string const& format
1909 + ) : Object(key, flags, format)
1910 + , runpath_()
1911 + , dependencies_()
1912 + {}
1913 +
1914 + DependencyContainer const & getDependencies() const
1915 + { return dependencies_; }
1916 +
1917 + SearchPathPtr const& runpath() const
1918 + { return runpath_; }
1919 +protected:
1920 + friend class ObjectReader;
1921 + void setRunpath(SearchPathPtr const& runpath)
1922 + {
1923 + runpath_ = runpath;
1924 + }
1925 +
1926 + void addDependency(DependencyPtr const& dependency)
1927 + {
1928 + dependencies_.push_back(dependency);
1929 + }
1930 +private:
1931 + SearchPathPtr runpath_;
1932 + DependencyContainer dependencies_;
1933 +};
1934 +
1935 +typedef SmartPtr<SharedObject> SharedObjectPtr;
1936 +
1937 +}
1938 +
1939 +#endif /* _aixdll_SharedObject_h */
1940
1941 Added: trunk/aix-miscutils/ldd/StaticObject.h
1942 ===================================================================
1943 --- trunk/aix-miscutils/ldd/StaticObject.h (rev 0)
1944 +++ trunk/aix-miscutils/ldd/StaticObject.h 2008-05-06 13:57:29 UTC (rev 1628)
1945 @@ -0,0 +1,18 @@
1946 +/* Copyright 2008 Gentoo Foundation
1947 + * Distributed under the terms of the GNU General Public License v2
1948 + * Author: Michael Haubenwallner <haubi@g.o>
1949 + */
1950 +
1951 +#ifndef _aixdll_StaticObject_h
1952 +#define _aixdll_StaticObject_h
1953 +
1954 +#include "Object.h"
1955 +
1956 +namespace aixdll {
1957 +
1958 +typedef Object StaticObject;
1959 +typedef SmartPtr<StaticObject> StaticObjectPtr;
1960 +
1961 +}
1962 +
1963 +#endif /* _aixdll_StaticObject_h */
1964
1965 Added: trunk/aix-miscutils/ldd/aixdll-query.cc
1966 ===================================================================
1967 --- trunk/aix-miscutils/ldd/aixdll-query.cc (rev 0)
1968 +++ trunk/aix-miscutils/ldd/aixdll-query.cc 2008-05-06 13:57:29 UTC (rev 1628)
1969 @@ -0,0 +1,129 @@
1970 +/* Copyright 2008 Gentoo Foundation
1971 + * Distributed under the terms of the GNU General Public License v2
1972 + * Author: Michael Haubenwallner <haubi@g.o>
1973 + */
1974 +
1975 +#include <string>
1976 +#include <map>
1977 +#include <iostream>
1978 +#include <errno.h>
1979 +
1980 +#include "ObjectReader.h"
1981 +
1982 +using namespace aixdll;
1983 +
1984 +typedef ObjectReader::ObjectContainer ObjectContainer;
1985 +typedef std::map<std::string, bool> QuestionContainer;
1986 +
1987 +bool query(std::string const& filename, QuestionContainer const& questions)
1988 +{
1989 + ObjectReader reader;
1990 + ObjectContainer objects;
1991 +
1992 + if (reader.readObjects(filename, filename, objects) == 0) {
1993 + std::cerr << "ldd: " << filename << ": " << strerror(ENOENT) << std::endl;
1994 + return true;
1995 + }
1996 +
1997 + for(ObjectContainer::iterator o = objects.begin()
1998 + ; o != objects.end()
1999 + ; o++
2000 + ) {
2001 + if (questions.find("FILE") != questions.end()) std::cout
2002 + << " FILE='"
2003 + << (*o)->key()->path()->asIdentifier()
2004 + << (*o)->key()->name()->base()
2005 + << "';"
2006 + ;
2007 + if (questions.find("MEMBER") != questions.end()) std::cout
2008 + << " MEMBER='"
2009 + << (*o)->key()->name()->member()
2010 + << "';"
2011 + ;
2012 + if (questions.find("FLAGS") != questions.end()) std::cout
2013 + << " FLAGS='"
2014 + << (*o)->flags()
2015 + << "';"
2016 + ;
2017 + if (questions.find("FORMAT") != questions.end()) std::cout
2018 + << " FORMAT='"
2019 + << (*o)->format()
2020 + << "';"
2021 + ;
2022 + SharedObject *sharedObject = dynamic_cast<SharedObject*>(o->ptr());
2023 + StaticObject *staticObject = dynamic_cast<StaticObject*>(o->ptr());
2024 + if (sharedObject) {
2025 + if (questions.find("SHROBJ") != questions.end()) std::cout
2026 + << " SHROBJ=true;"
2027 + ;
2028 + if (questions.find("RUNPATH") != questions.end()) std::cout
2029 + << " RUNPATH='"
2030 + << sharedObject->runpath()->asSeparated()
2031 + << "';"
2032 + ;
2033 + if (questions.find("DEPLIBS") != questions.end()) {
2034 + std::cout
2035 + << " DEPLIBS=\""
2036 + ;
2037 + SharedObject::DependencyContainer const& deps = sharedObject->getDependencies();
2038 + for(SharedObject::DependencyContainer::const_iterator dep = deps.begin()
2039 + ; dep != deps.end()
2040 + ; dep++
2041 + ) {
2042 + std::cout << " '";
2043 + if ((*dep)->key()) {
2044 + std::cout << (*dep)->key()->asIdentifier();
2045 + } else {
2046 + std::cout << (*dep)->name()->asIdentifier();
2047 + }
2048 + std::cout << "'";
2049 + }
2050 + std::cout << "\";";
2051 + }
2052 + } else {
2053 + if (questions.find("SHROBJ") != questions.end()) std::cout
2054 + << " SHROBJ=false;"
2055 + ;
2056 + if (questions.find("RUNPATH") != questions.end()) std::cout
2057 + << " RUNPATH='';"
2058 + ;
2059 + if (questions.find("DEPLIBS") != questions.end()) std::cout
2060 + << " DEPLIBS='';"
2061 + ;
2062 + }
2063 +
2064 + std::cout << std::endl;
2065 + }
2066 +
2067 + return false;
2068 +}
2069 +
2070 +int main(int argc, char **argv)
2071 +{
2072 + int i;
2073 + QuestionContainer questions;
2074 +
2075 + if (argc < 2) {
2076 + std::cout << argv[0] << " file [what1 [what2] [whatn]]\n"
2077 + "available for [what]:\n"
2078 + "\tFILE MEMBER FLAGS FORMAT SHROBJ RUNPATH DEPLIBS"
2079 + << std::endl;
2080 + return 0;
2081 + }
2082 +
2083 + for(i = 2; i < argc; i++) {
2084 + questions[argv[i]] = true;
2085 + }
2086 +
2087 + if (questions.size() == 0) {
2088 + questions["FILE"] = true;
2089 + questions["MEMBER"] = true;
2090 + questions["FLAGS"] = true;
2091 + questions["FORMAT"] = true;
2092 + questions["SHROBJ"] = true;
2093 + questions["RUNPATH"] = true;
2094 + questions["DEPLIBS"] = true;
2095 + }
2096 +
2097 + return query(argv[1], questions);
2098 +}
2099
2100 Deleted: trunk/aix-miscutils/ldd/ldd
2101 ===================================================================
2102 --- trunk/aix-miscutils/ldd/ldd 2008-04-21 18:37:05 UTC (rev 1627)
2103 +++ trunk/aix-miscutils/ldd/ldd 2008-05-06 13:57:29 UTC (rev 1628)
2104 @@ -1,174 +0,0 @@
2105 -#! /usr/bin/env bash
2106 -# Copyright 2008 Gentoo Foundation
2107 -# Distributed under the terms of the GNU General Public License v2
2108 -# Author: Michael Haubenwallner <haubi@g.o>
2109 -#
2110 -# An ldd for AIX with Linux-like output,
2111 -# using /usr/bin/dump to grok the binaries.
2112 -#
2113 -
2114 -declare -i PATHlen=0 BASElen=0 MEMBERlen=0
2115 -declare -i PATHmin=0 BASEmin=0 MEMBERmin=0
2116 -
2117 -declare -i PATHcol=0 BASEcol=0 MEMBERcol=0
2118 -
2119 -declare -r NOTFOUND=" => not found"
2120 -
2121 -cutoff() {
2122 - local line=$1
2123 - local minlen=$2
2124 - local maxcol=$((${#line}-${minlen}))
2125 - local tmpline value
2126 - if [[ ${line:$((maxcol-1)):1} != ' ' ]]; then
2127 - tmpline=${line:0:${maxcol}}
2128 - tmpline=${tmpline% *}
2129 - maxcol=$((${#tmpline}+1))
2130 - fi
2131 - value=${line:${maxcol}}
2132 - echo ${value}
2133 - echo "${line%${value}}"
2134 -}
2135 -
2136 -ldd_recurse() {
2137 -
2138 - local binary=${1}
2139 - local dodeep=${2:-true}
2140 - local realfile=${binary%%(*}
2141 - if [[ ${realfile} != ${binary} ]]; then
2142 - local shrobj=${binary#*(}
2143 - shrobj=${shrobj%)}
2144 - binary="${realfile}[${shrobj}]"
2145 - fi
2146 - local useThisObject=false haveLoaderSection=false useThisLine=false
2147 - local dynMEMBER dynBASE dynPATH RUNPATH
2148 - local line recurse found
2149 -
2150 - while IFS= read line
2151 - do
2152 - ${useThisLine} && [[ ${line} == '' ]] && break
2153 - if [[ ${line} == *: ]]; then
2154 - ${useThisObject} && break
2155 - useThisObject=false
2156 - haveLoaderSection=false
2157 - useThisLine=false
2158 - [[ ${line} == "${binary}:" ]] && useThisObject=true
2159 - continue
2160 - fi
2161 - ${useThisObject} || continue
2162 -
2163 - if ! ${haveLoaderSection} && [[ ${line} == *"***Import File Strings***"* ]]
2164 - then
2165 - haveLoaderSection=true
2166 - continue
2167 - fi
2168 - ${haveLoaderSection} || continue
2169 -
2170 - if ! ${useThisLine}; then
2171 - if [[ ${line} == "INDEX "* ]]; then
2172 - if [[ ${PATHmin} -eq 0 ]]; then
2173 - MEMBERlen=${#line}
2174 - line=${line%MEMBER *}
2175 - MEMBERmin=${#line}
2176 - MEMBERlen=$((MEMBERlen-MEMBERmin))
2177 - BASElen=${MEMBERmin}
2178 - line=${line%BASE *}
2179 - BASEmin=${#line}
2180 - BASElen=$((BASElen-BASEmin))
2181 - PATHlen=${BASEmin}
2182 - line=${line%PATH *}
2183 - PATHmin=${#line}
2184 - PATHlen=$((PATHlen-PATHmin))
2185 - fi
2186 - useThisLine=true
2187 - fi
2188 - continue
2189 - fi
2190 -
2191 - { IFS= read dynMEMBER; IFS= read line; } <<-EOC
2192 - $(cutoff "${line}" ${MEMBERlen})
2193 - EOC
2194 - { IFS= read dynBASE; IFS= read line; } <<-EOC
2195 - $(cutoff "${line}" ${BASElen})
2196 - EOC
2197 - { IFS= read dynPATH; IFS= read line; } <<-EOC
2198 - $(cutoff "${line}" ${PATHlen})
2199 - EOC
2200 -
2201 - dynINDEX=$(echo ${line})
2202 -
2203 - [[ ! ${dynBASE} && ${dynPATH} ]] && RUNPATH=${dynPATH}
2204 -
2205 - [[ ${dynBASE} && ${dynBASE} != .. && ${dynBASE} != . ]] || continue
2206 -
2207 - recurse="${dynPATH%/}${dynPATH:+/}${dynBASE}${dynMEMBER:+(}${dynMEMBER}${dynMEMBER:+)}"
2208 -
2209 - saveIFS=$IFS; IFS=:; set dummy ${dynPATH:-${LIBPATH}${LIBPATH:+:}${RUNPATH}}; IFS=$saveIFS; shift
2210 - found=${NOTFOUND}
2211 - recurse=${NOTFOUND}
2212 - for p
2213 - do
2214 - p=${p%/}
2215 - test -f "${p}/${dynBASE}" || continue;
2216 - takeit=false
2217 - while IFS= read line; do
2218 - if [[ ${line} == "${p}/${dynBASE}"*: ]]; then
2219 - takeit=false
2220 - if [[ ${line} == "${p}/${dynBASE}${dynMEMBER:+[}${dynMEMBER}${dynMEMBER:+]}:" ]]; then
2221 - takeit=true
2222 - continue
2223 - fi
2224 - fi
2225 - ${takeit} || continue
2226 - [[ ${line} == "Flags=("* ]] || continue
2227 - takeit=false
2228 - if [[ ${line} == *" EXEC "* && ${line} == *" DYNLOAD "* ]]; then
2229 - recurse="${p}/${dynBASE}${dynMEMBER:+(}${dynMEMBER}${dynMEMBER:+)}"
2230 - if [[ ${dynPATH} ]]; then
2231 - found=""
2232 - else
2233 - found=" => ${recurse}"
2234 - fi
2235 - break
2236 - fi
2237 - done <<-EOF
2238 - $(/usr/bin/dump -X32_64 -ov "${p}/${dynBASE}")
2239 - EOF
2240 - [[ ${found} != ${NOTFOUND} ]] && break
2241 - done
2242 - [[ ${SEEN} == *" '${recurse}' "* ]] && recurse=
2243 - if [[ ${recurse} ]]; then
2244 - echo " ${dynPATH%/}${dynPATH:+/}${dynBASE}${dynMEMBER:+(}${dynMEMBER}${dynMEMBER:+)}${found}"
2245 - [[ ${recurse} != ${NOTFOUND} ]] || continue
2246 - SEEN="${SEEN} '${recurse}' "
2247 - ${dodeep} && ldd_recurse "${recurse}" true
2248 - fi
2249 - done <<-EOF
2250 - $(/usr/bin/dump -X32_64 -H "${realfile}")
2251 - EOF
2252 -}
2253 -
2254 -ldd() {
2255 - local arg dodeep=true
2256 - local SEEN=
2257 - local TODO=
2258 -
2259 - for arg
2260 - do
2261 - case ${arg} in
2262 - --shallow) dodeep=false ;;
2263 - --deep) dodeep=true ;;
2264 - *)
2265 - TODO="${TODO} '${arg}'"
2266 - ;;
2267 - esac
2268 - done
2269 - eval "set -- ${TODO}"
2270 - for arg
2271 - do
2272 - [[ $# -gt 1 ]] && echo "${arg}:"
2273 - SEEN=
2274 - ldd_recurse "${arg}" ${dodeep}
2275 - done
2276 -}
2277 -
2278 -ldd "$@"
2279
2280 Added: trunk/aix-miscutils/ldd/ldd.cc
2281 ===================================================================
2282 --- trunk/aix-miscutils/ldd/ldd.cc (rev 0)
2283 +++ trunk/aix-miscutils/ldd/ldd.cc 2008-05-06 13:57:29 UTC (rev 1628)
2284 @@ -0,0 +1,198 @@
2285 +/* Copyright 2008 Gentoo Foundation
2286 + * Distributed under the terms of the GNU General Public License v2
2287 + * Author: Michael Haubenwallner <haubi@g.o>
2288 + */
2289 +
2290 +#include <string>
2291 +#include <vector>
2292 +#include <map>
2293 +#include <iostream>
2294 +#include <errno.h>
2295 +
2296 +#include "ObjectReader.h"
2297 +
2298 +using namespace aixdll;
2299 +
2300 +typedef ObjectReader::ObjectContainer ObjectContainer;
2301 +typedef std::map<std::string, ObjectPtr> SeenContainer;
2302 +typedef std::vector<std::string> MissingContainer;
2303 +
2304 +static bool collectSharedObjects(ObjectReader& reader, bool shallow
2305 + , std::string const& path, std::string const& identifier
2306 + , SeenContainer& read, ObjectContainer& resolved, MissingContainer& unread, SearchPath& runpath
2307 + )
2308 +{
2309 + ObjectContainer objects;
2310 +
2311 + if (reader.readObjects(path + identifier, identifier, objects) == 0) {
2312 + return false;
2313 + }
2314 +
2315 + ObjectContainer::iterator obj;
2316 + for(obj = objects.begin(); obj != objects.end(); obj++) {
2317 + SharedObject* sharedObject = dynamic_cast<SharedObject*>(obj->ptr());
2318 + if (sharedObject == NULL) {
2319 + continue;
2320 + }
2321 +
2322 + runpath.append(*sharedObject->runpath().ptr());
2323 + read[sharedObject->key()->asIdentifier()] = *obj;
2324 + resolved.push_back(*obj);
2325 +
2326 + if (shallow) continue;
2327 +
2328 + SharedObject::DependencyContainer const& dependencies =
2329 + sharedObject->getDependencies();
2330 + SharedObject::DependencyContainer::const_iterator dep;
2331 + for(dep = dependencies.begin(); dep != dependencies.end(); dep++) {
2332 + if ((*dep)->key()) {
2333 + if (read.find((*dep)->key()->asIdentifier()) != read.end()) {
2334 + continue;
2335 + }
2336 + unread.push_back((*dep)->key()->asIdentifier());
2337 + } else
2338 + if ((*dep)->name()) {
2339 + if (read.find((*dep)->name()->asIdentifier()) != read.end()) {
2340 + continue;
2341 + }
2342 + unread.push_back((*dep)->name()->asIdentifier());
2343 + }
2344 + }
2345 + }
2346 +
2347 + return true;
2348 +}
2349 +
2350 +void ldd_r(ObjectReader& reader, bool shallow, std::string const& filename)
2351 +{
2352 + SeenContainer read;
2353 + MissingContainer unread;
2354 + ObjectContainer resolved;
2355 + SearchPath runpath;
2356 + char const* envLibpath = getenv("LIBPATH");
2357 + if (envLibpath) {
2358 + runpath.appendSeparated(envLibpath);
2359 + }
2360 +
2361 + if (!collectSharedObjects(reader, false, "", filename, read, resolved, unread, runpath)) {
2362 + return;
2363 + }
2364 +
2365 + resolved.clear();
2366 +
2367 + while(unread.size() > 0) {
2368 + MissingContainer::iterator unr = unread.begin();
2369 + ObjectPathPtr path;
2370 + ObjectNamePtr name;
2371 + std::string unrName = *unr;
2372 + unread.erase(unr);
2373 + if (read.find(unrName) != read.end()) {
2374 + continue;
2375 + }
2376 + splitIdentifier(unrName, path, name);
2377 + if (path) {
2378 + if (!collectSharedObjects(reader, shallow
2379 + , ""
2380 + , unrName
2381 + , read
2382 + , resolved
2383 + , unread
2384 + , runpath
2385 + )) {
2386 + resolved.push_back(
2387 + ObjectPtr(new Object(
2388 + ObjectKeyPtr(new ObjectKey(path, name))
2389 + , "", ""
2390 + ))
2391 + );
2392 + }
2393 + } else {
2394 + SearchPath::PathContainer::const_iterator p;
2395 + for(p = runpath.components().begin()
2396 + ; p != runpath.components().end()
2397 + ; p++
2398 + ) {
2399 + if (collectSharedObjects(reader, shallow
2400 + , (*p)
2401 + , name->asIdentifier()
2402 + , read
2403 + , resolved
2404 + , unread
2405 + , runpath
2406 + )) {
2407 + break;
2408 + }
2409 + }
2410 + if (p == runpath.components().end()) {
2411 + resolved.push_back(
2412 + ObjectPtr(new Object(
2413 + ObjectKeyPtr(new ObjectKey(path, name))
2414 + , "", ""
2415 + ))
2416 + );
2417 + }
2418 + }
2419 + }
2420 +
2421 + for(ObjectContainer::iterator r = resolved.begin()
2422 + ; r != resolved.end()
2423 + ; r++
2424 + ) {
2425 + std::cout << " " << (*r)->key()->asIdentifier()
2426 + << " => "
2427 + << (*r)->getResolved()
2428 + << std::endl;
2429 + }
2430 +}
2431 +
2432 +bool ldd(ObjectReader& reader, bool shallow, MissingContainer const& toread)
2433 +{
2434 + ObjectContainer objects;
2435 + bool err = false;
2436 +
2437 + for(MissingContainer::const_iterator filename = toread.begin()
2438 + ; filename != toread.end()
2439 + ; filename++
2440 + ) {
2441 + if (reader.readObjects(*filename, *filename, objects) == 0) {
2442 + std::cerr << "ldd: " << *filename << ": " << strerror(ENOENT) << std::endl;
2443 + err = true;
2444 + }
2445 + }
2446 +
2447 + for(ObjectContainer::iterator o = objects.begin()
2448 + ; o != objects.end()
2449 + ; o++
2450 + ) {
2451 + SharedObject *sharedObject = dynamic_cast<SharedObject*>(o->ptr());
2452 + if (!sharedObject) {
2453 + continue;
2454 + }
2455 + if (objects.size() > 1) {
2456 + std::cout << (*o)->key()->asIdentifier() << ":" << std::endl;
2457 + }
2458 + ldd_r(reader, shallow, (*o)->key()->asIdentifier());
2459 + }
2460 +
2461 + return err;
2462 +}
2463 +
2464 +int main(int argc, char **argv)
2465 +{
2466 + ObjectReader reader;
2467 + int i;
2468 + std::string arg;
2469 + bool shallow = false;
2470 + MissingContainer toread;
2471 +
2472 + for(i = 1; i < argc; i++) {
2473 + arg = argv[i];
2474 + if (arg == "--shallow") {
2475 + shallow = true;
2476 + continue;
2477 + }
2478 + toread.push_back(arg);
2479 + }
2480 +
2481 + return ldd(reader, shallow, toread);
2482 +}
2483
2484 Added: trunk/aix-miscutils/ldd/smartptr.h
2485 ===================================================================
2486 --- trunk/aix-miscutils/ldd/smartptr.h (rev 0)
2487 +++ trunk/aix-miscutils/ldd/smartptr.h 2008-05-06 13:57:29 UTC (rev 1628)
2488 @@ -0,0 +1,110 @@
2489 +/* Copyright 2008 Gentoo Foundation
2490 + * Distributed under the terms of the GNU General Public License v2
2491 + * Author: Michael Haubenwallner <haubi@g.o>
2492 + */
2493 +
2494 +#ifndef _aixdll_smartptr_h
2495 +#define _aixdll_smartptr_h
2496 +
2497 +namespace aixdll {
2498 +
2499 +class RefCounted {
2500 +public:
2501 + RefCounted() : refcount_(0) {}
2502 + virtual ~RefCounted() {}
2503 +
2504 + RefCounted(const RefCounted&) : refcount_(0) {}
2505 + RefCounted& operator=(const RefCounted&) { return *this; }
2506 +
2507 + virtual void ref() { refcount_++; }
2508 + virtual void unref() { if (!--refcount_) delete this; }
2509 +
2510 + int refcount() const { return refcount_; }
2511 +
2512 + static void ref(RefCounted* r) { if (r) r->ref(); }
2513 + static void unref(RefCounted* r) { if (r) r->unref(); }
2514 +
2515 +private:
2516 + int refcount_;
2517 +};
2518 +
2519 +
2520 +template <class T> class SmartPtr {
2521 +public:
2522 +
2523 + SmartPtr(): ptr_(0) {}
2524 +
2525 + explicit SmartPtr(T* p): ptr_(p) { RefCounted::ref(ptr_); }
2526 +
2527 + template<class RHS>
2528 + SmartPtr(const SmartPtr<RHS>& p): ptr_(0) { operator=(p); }
2529 +
2530 + SmartPtr(const SmartPtr& p): ptr_(0) { operator=(p); }
2531 +
2532 + ~SmartPtr() { RefCounted::unref(ptr_); }
2533 +
2534 + template<class RHS>
2535 + SmartPtr&
2536 + operator=(
2537 + const SmartPtr<RHS>& p)
2538 + {
2539 + if (this->ptr() != p.ptr()) {
2540 + RefCounted::ref(p.ptr());
2541 + RefCounted::unref(this->ptr());
2542 + ptr_ = p.ptr();
2543 + }
2544 + return *this;
2545 + }
2546 +
2547 + SmartPtr&
2548 + operator=(
2549 + const SmartPtr& p)
2550 + {
2551 + if (this->ptr() != p.ptr()) {
2552 + RefCounted::ref(p.ptr());
2553 + RefCounted::unref(this->ptr());
2554 + ptr_ = p.ptr();
2555 + }
2556 + return *this;
2557 + }
2558 +
2559 + template<class RHS>
2560 + void eat(RHS* p)
2561 + {
2562 + if (p == ptr_) return;
2563 + RefCounted::unref(ptr_);
2564 + ptr_ = p;
2565 + RefCounted::ref(p);
2566 + }
2567 +
2568 + void forget()
2569 + {
2570 + if (ptr_) {
2571 + RefCounted::unref(ptr_);
2572 + ptr_ = NULL;
2573 + }
2574 + }
2575 +
2576 + operator bool() const {
2577 + return static_cast<bool>(ptr_);
2578 + }
2579 + bool operator !() const { return !ptr_; }
2580 + bool operator< (const SmartPtr& that) const { return ptr_< that.ptr_; }
2581 + bool operator==(const SmartPtr& that) const { return ptr_==that.ptr_; }
2582 + bool operator> (const SmartPtr& that) const { return ptr_> that.ptr_; }
2583 + bool operator<=(const SmartPtr& that) const { return ptr_<=that.ptr_; }
2584 + bool operator>=(const SmartPtr& that) const { return ptr_>=that.ptr_; }
2585 +
2586 + T* ptr() const { return ptr_; }
2587 + T* operator->() { return ptr_; }
2588 + const T* cptr() const { return ptr_; }
2589 + const T* operator->() const { return ptr_; }
2590 +
2591 +
2592 +private:
2593 + T* ptr_;
2594 +};
2595 +
2596 +}
2597 +
2598 +#endif
2599
2600 --
2601 gentoo-commits@l.g.o mailing list