xref: /openbmc/openbmc-tools/ipkdbg/ipkdbg.in (revision c7a446e2)
1*c7a446e2SAndrew Jeffery#!/bin/sh
2*c7a446e2SAndrew Jeffery
3*c7a446e2SAndrew Jefferyset -eu
4*c7a446e2SAndrew Jeffery
5*c7a446e2SAndrew Jeffery: ${IPKDBG_OPKG_CACHE:=}
6*c7a446e2SAndrew Jeffery: ${IPKDBG_CONF_HOST:=host.local}
7*c7a446e2SAndrew Jeffery: ${IPKDBG_CONF_MNT:=mountpoint}
8*c7a446e2SAndrew Jeffery: ${IPKDBG_CONF_LOC:=themoon}
9*c7a446e2SAndrew Jeffery: ${IPKDBG_CONF_ROOT:=path}
10*c7a446e2SAndrew Jeffery: ${IPKDBG_CONF_USER:=$USER}
11*c7a446e2SAndrew Jeffery: ${IPKDBG_WGET_OPTS:="--quiet"}
12*c7a446e2SAndrew Jeffery: ${IPKDBG_ZSTD:=zstd}
13*c7a446e2SAndrew Jeffery
14*c7a446e2SAndrew Jefferyipkdbg_error() {
15*c7a446e2SAndrew Jeffery    /bin/echo -e "$@" | fold >&2
16*c7a446e2SAndrew Jeffery}
17*c7a446e2SAndrew Jeffery
18*c7a446e2SAndrew Jefferyipkdbg_info() {
19*c7a446e2SAndrew Jeffery    /bin/echo -e "$@" | fold
20*c7a446e2SAndrew Jeffery}
21*c7a446e2SAndrew Jeffery
22*c7a446e2SAndrew Jefferyipkdbg_help() {
23*c7a446e2SAndrew Jeffery/bin/echo -e "\033[1mNAME\033[0m"
24*c7a446e2SAndrew Jeffery/bin/echo -e "\tipkdbg - debug OpenBMC applications from an (internally) released firmware"
25*c7a446e2SAndrew Jeffery/bin/echo -e
26*c7a446e2SAndrew Jeffery/bin/echo -e "\033[1mSYNOPSIS\033[0m"
27*c7a446e2SAndrew Jeffery/bin/echo -e "\tipkdbg [-q] RELEASE FILE CORE [PACKAGE...]"
28*c7a446e2SAndrew Jeffery/bin/echo -e
29*c7a446e2SAndrew Jeffery/bin/echo -e "\033[1mDESCRIPTION\033[0m"
30*c7a446e2SAndrew Jeffery/bin/echo -e "\tRELEASE is the firmware release whose packages to install"
31*c7a446e2SAndrew Jeffery/bin/echo -e "\tFILE is the absolute path to the binary of interest in the target environment"
32*c7a446e2SAndrew Jeffery/bin/echo -e "\tCORE is an optional core file generated by FILE. Pass '-' for no core file"
33*c7a446e2SAndrew Jeffery/bin/echo -e "\tPACKAGES will be used to populate a temporary rootfs for debugging FILE"
34*c7a446e2SAndrew Jeffery/bin/echo -e
35*c7a446e2SAndrew Jeffery/bin/echo -e "\033[1mOPTIONS\033[0m"
36*c7a446e2SAndrew Jeffery/bin/echo -e "\t\033[1m-h\033[0m"
37*c7a446e2SAndrew Jeffery/bin/echo -e "\tPrint this help."
38*c7a446e2SAndrew Jeffery/bin/echo -e
39*c7a446e2SAndrew Jeffery/bin/echo -e "\t\033[1m-q\033[0m"
40*c7a446e2SAndrew Jeffery/bin/echo -e "\tQuit gdb once done. Intended for use in a scripting environment in combination"
41*c7a446e2SAndrew Jeffery/bin/echo -e "\twith a core file, as the backtrace will be printed as an implicit first command."
42*c7a446e2SAndrew Jeffery/bin/echo -e
43*c7a446e2SAndrew Jeffery/bin/echo -e "\033[1mENVIRONMENT\033[0m"
44*c7a446e2SAndrew Jeffery/bin/echo -e "\tThere are several important environment variables controlling the behaviour of"
45*c7a446e2SAndrew Jeffery/bin/echo -e "\tthe script:"
46*c7a446e2SAndrew Jeffery/bin/echo -e
47*c7a446e2SAndrew Jeffery/bin/echo -e "\t\033[1mIPKDBG_OPKG_CACHE\033[0m"
48*c7a446e2SAndrew Jeffery/bin/echo -e "\tA package cache directory for opkg. Defaults to empty, disabling the cache."
49*c7a446e2SAndrew Jeffery/bin/echo -e
50*c7a446e2SAndrew Jeffery/bin/echo -e "\t\033[1mIPKDBG_CONF_HOST\033[0m"
51*c7a446e2SAndrew Jeffery/bin/echo -e "\tHostname for access to opkg.conf over the web interface"
52*c7a446e2SAndrew Jeffery/bin/echo -e
53*c7a446e2SAndrew Jeffery/bin/echo -e "\tDefaults to '${IPKDBG_CONF_HOST}'"
54*c7a446e2SAndrew Jeffery/bin/echo -e
55*c7a446e2SAndrew Jeffery/bin/echo -e "\t\033[1mIPKDBG_CONF_MNT\033[0m"
56*c7a446e2SAndrew Jeffery/bin/echo -e "\tMount-point for access to opkg.conf"
57*c7a446e2SAndrew Jeffery/bin/echo -e
58*c7a446e2SAndrew Jeffery/bin/echo -e "\tDefaults to '${IPKDBG_CONF_MNT}'"
59*c7a446e2SAndrew Jeffery/bin/echo -e
60*c7a446e2SAndrew Jeffery/bin/echo -e "\t\033[1mIPKDBG_CONF_LOC\033[0m"
61*c7a446e2SAndrew Jeffery/bin/echo -e "\tGeo-location for access to opkg.conf"
62*c7a446e2SAndrew Jeffery/bin/echo -e
63*c7a446e2SAndrew Jeffery/bin/echo -e "\tDefaults to '${IPKDBG_CONF_LOC}'"
64*c7a446e2SAndrew Jeffery/bin/echo -e
65*c7a446e2SAndrew Jeffery/bin/echo -e "\t\033[1mIPKDBG_CONF_ROOT\033[0m"
66*c7a446e2SAndrew Jeffery/bin/echo -e "\tPath to the directory containing build artifacts, for access to opkg.conf"
67*c7a446e2SAndrew Jeffery/bin/echo -e
68*c7a446e2SAndrew Jeffery/bin/echo -e "\tDefaults to '${IPKDBG_CONF_ROOT}'"
69*c7a446e2SAndrew Jeffery/bin/echo -e
70*c7a446e2SAndrew Jeffery/bin/echo -e "\t\033[1mIPKDBG_CONF_USER\033[0m"
71*c7a446e2SAndrew Jeffery/bin/echo -e "\tUsername for access to opkg.conf over the web interface"
72*c7a446e2SAndrew Jeffery/bin/echo -e
73*c7a446e2SAndrew Jeffery/bin/echo -e "\tDefaults to \$USER ($USER)"
74*c7a446e2SAndrew Jeffery/bin/echo -e
75*c7a446e2SAndrew Jeffery/bin/echo -e "\t\033[1mIPKDBG_GDB\033[0m"
76*c7a446e2SAndrew Jeffery/bin/echo -e "\tThe gdb(1) binary to invoke. Automatically detected if unset."
77*c7a446e2SAndrew Jeffery/bin/echo -e
78*c7a446e2SAndrew Jeffery/bin/echo -e "\t\033[1mIPKDBG_WGET_OPTS\033[0m"
79*c7a446e2SAndrew Jeffery/bin/echo -e "\tUser options to pass to wget(1) when fetching opkg.conf. Defaults to"
80*c7a446e2SAndrew Jeffery/bin/echo -e "\t'$IPKDBG_WGET_OPTS'"
81*c7a446e2SAndrew Jeffery/bin/echo -e
82*c7a446e2SAndrew Jeffery/bin/echo -e "\t\033[1mIPKDBG_ZSTD\033[0m"
83*c7a446e2SAndrew Jeffery/bin/echo -e "\tThe zstd(1) binary to extract the compressed core dump. Automatically"
84*c7a446e2SAndrew Jeffery/bin/echo -e "\tdetected if unset."
85*c7a446e2SAndrew Jeffery/bin/echo -e
86*c7a446e2SAndrew Jeffery/bin/echo -e "\033[1mEXAMPLE\033[0m"
87*c7a446e2SAndrew Jeffery/bin/echo -e "\tipkdbg 1020.2206.20220208a \\"
88*c7a446e2SAndrew Jeffery/bin/echo -e "\t\t/usr/bin/nvmesensor - \\"
89*c7a446e2SAndrew Jeffery/bin/echo -e "\t\tdbus-sensors dbus-sensors-dbg"
90*c7a446e2SAndrew Jeffery}
91*c7a446e2SAndrew Jeffery
92*c7a446e2SAndrew JefferyIPKDBG_OPT_QUIT=0
93*c7a446e2SAndrew Jeffery
94*c7a446e2SAndrew Jefferywhile getopts hq f
95*c7a446e2SAndrew Jefferydo
96*c7a446e2SAndrew Jeffery    case $f in
97*c7a446e2SAndrew Jeffery    q) IPKDBG_OPT_QUIT=1;;
98*c7a446e2SAndrew Jeffery    h|\?) ipkdbg_help ; exit 1;;
99*c7a446e2SAndrew Jeffery    esac
100*c7a446e2SAndrew Jefferydone
101*c7a446e2SAndrew Jefferyshift $(expr $OPTIND - 1)
102*c7a446e2SAndrew Jeffery
103*c7a446e2SAndrew Jefferytrap ipkdbg_help EXIT
104*c7a446e2SAndrew Jeffery
105*c7a446e2SAndrew Jefferyipkdbg_core_extract()
106*c7a446e2SAndrew Jeffery{
107*c7a446e2SAndrew Jeffery    if [ "-" = "$1" ]
108*c7a446e2SAndrew Jeffery    then
109*c7a446e2SAndrew Jeffery        echo -
110*c7a446e2SAndrew Jeffery    else
111*c7a446e2SAndrew Jeffery        local src="$(realpath "$1")"
112*c7a446e2SAndrew Jeffery        local dst="${src%.zst}"
113*c7a446e2SAndrew Jeffery
114*c7a446e2SAndrew Jeffery        command -v $IPKDBG_ZSTD > /dev/null
115*c7a446e2SAndrew Jeffery        $IPKDBG_ZSTD --decompress --quiet --quiet --force -o "$dst" "$src" || true
116*c7a446e2SAndrew Jeffery        echo "$dst"
117*c7a446e2SAndrew Jeffery    fi
118*c7a446e2SAndrew Jeffery}
119*c7a446e2SAndrew Jeffery
120*c7a446e2SAndrew JefferyIPKDBG_BUILD=$1; shift
121*c7a446e2SAndrew JefferyIPKDBG_FILE=$1; shift
122*c7a446e2SAndrew JefferyIPKDBG_CORE=$(ipkdbg_core_extract "$1"); shift
123*c7a446e2SAndrew JefferyIPKDBG_PKGS=$@
124*c7a446e2SAndrew Jeffery
125*c7a446e2SAndrew Jeffery: ${IPKDBG_GDB:=}
126*c7a446e2SAndrew Jefferyif [ -n "$IPKDBG_GDB" ]
127*c7a446e2SAndrew Jefferythen
128*c7a446e2SAndrew Jeffery    ipkdbg_info "Using provided gdb command '$IPKDBG_GDB'"
129*c7a446e2SAndrew Jefferyelse
130*c7a446e2SAndrew Jeffery    os_id=$(. /etc/os-release; echo ${ID}-${VERSION_ID})
131*c7a446e2SAndrew Jeffery    case $os_id in
132*c7a446e2SAndrew Jeffery    rhel-8.6 | fedora*)
133*c7a446e2SAndrew Jeffery        IPKDBG_GDB=gdb
134*c7a446e2SAndrew Jeffery        if [ -z "$(command -v $IPKDBG_GDB)" ]
135*c7a446e2SAndrew Jeffery        then
136*c7a446e2SAndrew Jeffery            ipkdbg_error "Please install the gdb package:"
137*c7a446e2SAndrew Jeffery            ipkdbg_error
138*c7a446e2SAndrew Jeffery            ipkdbg_error "\tsudo dnf install gdb"
139*c7a446e2SAndrew Jeffery            ipkdbg_error
140*c7a446e2SAndrew Jeffery            exit 1
141*c7a446e2SAndrew Jeffery        fi
142*c7a446e2SAndrew Jeffery        ;;
143*c7a446e2SAndrew Jeffery    rhel*)
144*c7a446e2SAndrew Jeffery        IPKDBG_GDB=gdb-multiarch
145*c7a446e2SAndrew Jeffery        if [ -z "$(command -v $IPKDBG_GDB)" ]
146*c7a446e2SAndrew Jeffery        then
147*c7a446e2SAndrew Jeffery            ipkdbg_error "Please install the gdb-multiarch package:"
148*c7a446e2SAndrew Jeffery            ipkdbg_error
149*c7a446e2SAndrew Jeffery            ipkdbg_error "\tsudo dnf install gdb-multiarch"
150*c7a446e2SAndrew Jeffery            ipkdbg_error
151*c7a446e2SAndrew Jeffery            exit 1
152*c7a446e2SAndrew Jeffery        fi
153*c7a446e2SAndrew Jeffery        ;;
154*c7a446e2SAndrew Jeffery    ubuntu*)
155*c7a446e2SAndrew Jeffery        IPKDBG_GDB=gdb-multiarch
156*c7a446e2SAndrew Jeffery        if [ -z "$(command -v $IPKDBG_GDB)" ]
157*c7a446e2SAndrew Jeffery        then
158*c7a446e2SAndrew Jeffery            ipkdbg_error "Please Install the gdb-multiarch package"
159*c7a446e2SAndrew Jeffery            ipkdbg_error
160*c7a446e2SAndrew Jeffery            ipkdbg_error "\tsudo apt install gdb-multiarch"
161*c7a446e2SAndrew Jeffery            ipkdbg_error
162*c7a446e2SAndrew Jeffery            exit 1
163*c7a446e2SAndrew Jeffery        fi
164*c7a446e2SAndrew Jeffery        ;;
165*c7a446e2SAndrew Jeffery    *)
166*c7a446e2SAndrew Jeffery        ipkdbg_error "Unrecognised distribution $release_id. Please set IPKDBG_GDB or " \
167*c7a446e2SAndrew Jeffery            "install an appropriate gdb binary to invoke"
168*c7a446e2SAndrew Jeffery        exit 1
169*c7a446e2SAndrew Jeffery        ;;
170*c7a446e2SAndrew Jeffery    esac
171*c7a446e2SAndrew Jeffery    ipkdbg_info "Using gdb command ${IPKDBG_GDB} ($(command -v $IPKDBG_GDB))"
172*c7a446e2SAndrew Jefferyfi
173*c7a446e2SAndrew Jeffery
174*c7a446e2SAndrew Jefferyipkdbg_archive_extract() {
175*c7a446e2SAndrew Jeffery    local offset=$1
176*c7a446e2SAndrew Jeffery    local work=$2
177*c7a446e2SAndrew Jeffery    tail -n+$offset $0 | base64 --decode - | tar -xz -C $work
178*c7a446e2SAndrew Jeffery}
179*c7a446e2SAndrew Jeffery
180*c7a446e2SAndrew Jefferyipkdbg_opkg_path() {
181*c7a446e2SAndrew Jeffery    local root=$1
182*c7a446e2SAndrew Jeffery    local arch=$(uname -m)
183*c7a446e2SAndrew Jeffery    local release_id=$(. /etc/os-release; echo $ID)
184*c7a446e2SAndrew Jeffery    local release_version_id=$(. /etc/os-release; echo $VERSION_ID)
185*c7a446e2SAndrew Jeffery    local p=${root}/bin/${arch}/${release_id}/${release_version_id}/opkg
186*c7a446e2SAndrew Jeffery    if [ ! -x "$p" ]
187*c7a446e2SAndrew Jeffery    then
188*c7a446e2SAndrew Jeffery        ipkdbg_error "Unsupported environment:"
189*c7a446e2SAndrew Jeffery        ipkdbg_error
190*c7a446e2SAndrew Jeffery        ipkdbg_error "Architecture:\t$arch"
191*c7a446e2SAndrew Jeffery        ipkdbg_error "Distribution ID:\t$release_id"
192*c7a446e2SAndrew Jeffery        ipkdbg_error "Distribution Version:\t$release_version_id"
193*c7a446e2SAndrew Jeffery        exit 1
194*c7a446e2SAndrew Jeffery    fi
195*c7a446e2SAndrew Jeffery    echo $p
196*c7a446e2SAndrew Jeffery}
197*c7a446e2SAndrew Jeffery
198*c7a446e2SAndrew Jefferyif [ ! -f $0 ]
199*c7a446e2SAndrew Jefferythen
200*c7a446e2SAndrew Jeffery    ipkdbg_error "Please execute the script with a relative or absolute path"
201*c7a446e2SAndrew Jeffery    exit 1
202*c7a446e2SAndrew Jefferyfi
203*c7a446e2SAndrew Jeffery
204*c7a446e2SAndrew JefferyIPKDBG_DATA=$(awk '/^__ARCHIVE_BEGIN__$/ { print NR + 1; exit 0 }' $0)
205*c7a446e2SAndrew JefferyIPKDBG_WORK=$(mktemp -t --directory ipkdbg.XXX)
206*c7a446e2SAndrew JefferyIPKDBG_BINS=${IPKDBG_WORK}/tools
207*c7a446e2SAndrew JefferyIPKDBG_ROOT=${IPKDBG_WORK}/root
208*c7a446e2SAndrew JefferyIPKDBG_CONF=${IPKDBG_WORK}/opkg.conf
209*c7a446e2SAndrew JefferyIPKDBG_DB=${IPKDBG_WORK}/database
210*c7a446e2SAndrew Jeffery
211*c7a446e2SAndrew Jefferycleanup() {
212*c7a446e2SAndrew Jeffery    rm -rf $IPKDBG_WORK
213*c7a446e2SAndrew Jeffery}
214*c7a446e2SAndrew Jeffery
215*c7a446e2SAndrew Jefferytrap cleanup EXIT INT QUIT KILL
216*c7a446e2SAndrew Jeffery
217*c7a446e2SAndrew Jefferymkdir $IPKDBG_BINS $IPKDBG_DB
218*c7a446e2SAndrew Jefferyipkdbg_archive_extract $IPKDBG_DATA $IPKDBG_BINS
219*c7a446e2SAndrew Jeffery
220*c7a446e2SAndrew JefferyIPKDBG_OPKG_BIN=$(ipkdbg_opkg_path $IPKDBG_BINS)
221*c7a446e2SAndrew Jeffery
222*c7a446e2SAndrew Jefferyipkdbg_build_gen_path() {
223*c7a446e2SAndrew Jeffery    local build=$1
224*c7a446e2SAndrew Jeffery    local component="$2"
225*c7a446e2SAndrew Jeffery    echo /${IPKDBG_CONF_MNT}/${IPKDBG_CONF_LOC}/${IPKDBG_CONF_ROOT}/${build}/"$component"
226*c7a446e2SAndrew Jeffery}
227*c7a446e2SAndrew Jeffery
228*c7a446e2SAndrew Jefferyipkdbg_build_gen_url() {
229*c7a446e2SAndrew Jeffery    local build=$1
230*c7a446e2SAndrew Jeffery    local component="$2"
231*c7a446e2SAndrew Jeffery    echo https://${IPKDBG_CONF_HOST}/${IPKDBG_CONF_MNT}/${IPKDBG_CONF_LOC}/${IPKDBG_CONF_ROOT}/${build}/${component}
232*c7a446e2SAndrew Jeffery}
233*c7a446e2SAndrew Jeffery
234*c7a446e2SAndrew Jefferyipkdbg_build_gen_cache() {
235*c7a446e2SAndrew Jeffery    local build=$1
236*c7a446e2SAndrew Jeffery    local component="$2"
237*c7a446e2SAndrew Jeffery    echo "${HOME}/.cache/ipkdbg/builds/${build}/${component}"
238*c7a446e2SAndrew Jeffery}
239*c7a446e2SAndrew Jeffery
240*c7a446e2SAndrew Jefferyipkdbg_opkg_conf_gen_path() {
241*c7a446e2SAndrew Jeffery    local build=$1
242*c7a446e2SAndrew Jeffery    ipkdbg_build_gen_path $build bmc_ipk/opkg.conf
243*c7a446e2SAndrew Jeffery}
244*c7a446e2SAndrew Jeffery
245*c7a446e2SAndrew Jefferyipkdbg_opkg_fetch_path() {
246*c7a446e2SAndrew Jeffery    local path=$1
247*c7a446e2SAndrew Jeffery    local output=$2
248*c7a446e2SAndrew Jeffery    cp "$path" "$output" > /dev/null 2>&1
249*c7a446e2SAndrew Jeffery}
250*c7a446e2SAndrew Jeffery
251*c7a446e2SAndrew Jefferyipkdbg_opkg_conf_gen_url() {
252*c7a446e2SAndrew Jeffery    local build=$1
253*c7a446e2SAndrew Jeffery    ipkdbg_build_gen_url $build bmc_ipk/opkg.conf
254*c7a446e2SAndrew Jeffery}
255*c7a446e2SAndrew Jeffery
256*c7a446e2SAndrew Jefferyipkdbg_opkg_fetch_url() {
257*c7a446e2SAndrew Jeffery    local url=$1
258*c7a446e2SAndrew Jeffery    local output=$2
259*c7a446e2SAndrew Jeffery    # We don't want URL to wrap
260*c7a446e2SAndrew Jeffery    ipkdbg_info "Authenticating as user $IPKDBG_CONF_USER"
261*c7a446e2SAndrew Jeffery    if ! wget --http-user=$IPKDBG_CONF_USER \
262*c7a446e2SAndrew Jeffery        --ask-password \
263*c7a446e2SAndrew Jeffery        --output-document $output \
264*c7a446e2SAndrew Jeffery        $IPKDBG_WGET_OPTS \
265*c7a446e2SAndrew Jeffery        $url
266*c7a446e2SAndrew Jeffery    then
267*c7a446e2SAndrew Jeffery        ipkdbg_error "Failed to fetch resource"
268*c7a446e2SAndrew Jeffery        exit 1
269*c7a446e2SAndrew Jeffery    fi
270*c7a446e2SAndrew Jeffery}
271*c7a446e2SAndrew Jeffery
272*c7a446e2SAndrew Jefferyipkdbg_opkg_conf_gen_cache() {
273*c7a446e2SAndrew Jeffery    local build=$1
274*c7a446e2SAndrew Jeffery    ipkdbg_build_gen_cache $build opkg.conf
275*c7a446e2SAndrew Jeffery}
276*c7a446e2SAndrew Jeffery
277*c7a446e2SAndrew Jefferyipkdbg_opkg_conf_fetch_cache() {
278*c7a446e2SAndrew Jeffery    local build=$1
279*c7a446e2SAndrew Jeffery    local output=$2
280*c7a446e2SAndrew Jeffery    local path="$(ipkdbg_opkg_conf_gen_cache $build)"
281*c7a446e2SAndrew Jeffery    cp "$path" "$output" > /dev/null 2>&1
282*c7a446e2SAndrew Jeffery}
283*c7a446e2SAndrew Jeffery
284*c7a446e2SAndrew Jefferyipkdbg_opkg_conf_install() {
285*c7a446e2SAndrew Jeffery    local build=$1
286*c7a446e2SAndrew Jeffery    local output=$2
287*c7a446e2SAndrew Jeffery    mkdir -p $(dirname $output)
288*c7a446e2SAndrew Jeffery    if ! ipkdbg_opkg_conf_fetch_cache $build $output
289*c7a446e2SAndrew Jeffery    then
290*c7a446e2SAndrew Jeffery        local cache="$(ipkdbg_opkg_conf_gen_cache $build)"
291*c7a446e2SAndrew Jeffery        mkdir -p $(dirname $cache)
292*c7a446e2SAndrew Jeffery        url=
293*c7a446e2SAndrew Jeffery        ipkdbg_opkg_fetch_path "$(ipkdbg_opkg_conf_gen_path $build)" $cache ||
294*c7a446e2SAndrew Jeffery            (echo "Configuring opkg via $(ipkdbg_opkg_conf_gen_url $build)" &&
295*c7a446e2SAndrew Jeffery                ipkdbg_opkg_fetch_url "$(ipkdbg_opkg_conf_gen_url $build)" $cache)
296*c7a446e2SAndrew Jeffery        ipkdbg_opkg_conf_fetch_cache $build $output
297*c7a446e2SAndrew Jeffery    fi
298*c7a446e2SAndrew Jeffery}
299*c7a446e2SAndrew Jeffery
300*c7a446e2SAndrew Jefferyipkdbg_opkg_db_gen_path() {
301*c7a446e2SAndrew Jeffery    local build=$1
302*c7a446e2SAndrew Jeffery    ipkdbg_build_gen_path $build bmc_ipk/opkg-database.tar.xz
303*c7a446e2SAndrew Jeffery}
304*c7a446e2SAndrew Jeffery
305*c7a446e2SAndrew Jefferyipkdbg_opkg_db_gen_url() {
306*c7a446e2SAndrew Jeffery    local build=$1
307*c7a446e2SAndrew Jeffery    ipkdbg_build_gen_url ${build} bmc_ipk/opkg-database.tar.xz
308*c7a446e2SAndrew Jeffery}
309*c7a446e2SAndrew Jeffery
310*c7a446e2SAndrew Jefferyipkdbg_opkg_db_gen_cache() {
311*c7a446e2SAndrew Jeffery    local build=$1
312*c7a446e2SAndrew Jeffery    ipkdbg_build_gen_cache $build opkg-database.tar.xz
313*c7a446e2SAndrew Jeffery}
314*c7a446e2SAndrew Jeffery
315*c7a446e2SAndrew Jefferyipkdbg_opkg_db_install() {
316*c7a446e2SAndrew Jeffery    local build=$1
317*c7a446e2SAndrew Jeffery    local root=$2
318*c7a446e2SAndrew Jeffery    local state=${root}/var/lib/opkg
319*c7a446e2SAndrew Jeffery    local cache="$(ipkdbg_opkg_db_gen_cache $build)"
320*c7a446e2SAndrew Jeffery    mkdir -p $state
321*c7a446e2SAndrew Jeffery    if ! [ -f $cache ]
322*c7a446e2SAndrew Jeffery    then
323*c7a446e2SAndrew Jeffery        mkdir -p $(dirname $cache)
324*c7a446e2SAndrew Jeffery        ipkdbg_opkg_fetch_path "$(ipkdbg_opkg_db_gen_path $build)" $cache ||
325*c7a446e2SAndrew Jeffery            ipkdbg_opkg_fetch_url "$(ipkdbg_opkg_db_gen_url $build)" $cache ||
326*c7a446e2SAndrew Jeffery            rm -f $cache
327*c7a446e2SAndrew Jeffery    fi
328*c7a446e2SAndrew Jeffery    tar -xf $cache -C $state 2> /dev/null
329*c7a446e2SAndrew Jeffery    mkdir -p ${root}/usr/local
330*c7a446e2SAndrew Jeffery    ln -s ${root}/var ${root}/usr/local/var
331*c7a446e2SAndrew Jeffery}
332*c7a446e2SAndrew Jeffery
333*c7a446e2SAndrew Jefferyipkdbg_opkg() {
334*c7a446e2SAndrew Jeffery    $IPKDBG_OPKG_BIN \
335*c7a446e2SAndrew Jeffery        $([ -z "$IPKDBG_OPKG_CACHE" ] ||
336*c7a446e2SAndrew Jeffery            echo --cache-dir $IPKDBG_OPKG_CACHE --host-cache-dir) \
337*c7a446e2SAndrew Jeffery        -V1 -f $IPKDBG_CONF -o $IPKDBG_ROOT $@
338*c7a446e2SAndrew Jeffery}
339*c7a446e2SAndrew Jeffery
340*c7a446e2SAndrew Jefferyipkdbg_gdb_extract_bin() {
341*c7a446e2SAndrew Jeffery    local core=$1
342*c7a446e2SAndrew Jeffery    $IPKDBG_GDB --core $core -ex quit 2> /dev/null |
343*c7a446e2SAndrew Jeffery        awk -F "[\`']" '/Core was generated by/ { print $2 }' |
344*c7a446e2SAndrew Jeffery        awk -F " " '{ print $1 }' # Chop off the arguments, we only want the binary path
345*c7a446e2SAndrew Jeffery}
346*c7a446e2SAndrew Jeffery
347*c7a446e2SAndrew Jefferyipkdbg_opkg_find() {
348*c7a446e2SAndrew Jeffery    ipkdbg_opkg find $@ | awk '{ print $1 }'
349*c7a446e2SAndrew Jeffery}
350*c7a446e2SAndrew Jeffery
351*c7a446e2SAndrew Jefferyipkdbg_opkg_find_extra() {
352*c7a446e2SAndrew Jeffery    local pkg=$1
353*c7a446e2SAndrew Jeffery
354*c7a446e2SAndrew Jeffery    # Try appending -dbg and -src to the binary package name
355*c7a446e2SAndrew Jeffery    extra_pkgs="$(ipkdbg_opkg_find ${pkg}-dbg) $(ipkdbg_opkg_find ${pkg}-src)"
356*c7a446e2SAndrew Jeffery
357*c7a446e2SAndrew Jeffery    # If that fails, we probably have a split binary package
358*c7a446e2SAndrew Jeffery    if [ -z "$extra_pkgs" ]
359*c7a446e2SAndrew Jeffery    then
360*c7a446e2SAndrew Jeffery        # Strip the last component off as it's probably the split binary package name and
361*c7a446e2SAndrew Jeffery        # try again
362*c7a446e2SAndrew Jeffery        extra_pkgs="$(ipkdbg_opkg_find ${pkg%-*}-dbg) $(ipkdbg_opkg_find ${pkg%-*}-src)"
363*c7a446e2SAndrew Jeffery    fi
364*c7a446e2SAndrew Jeffery    echo $extra_pkgs
365*c7a446e2SAndrew Jeffery}
366*c7a446e2SAndrew Jeffery
367*c7a446e2SAndrew Jefferyipkdbg_opkg_conf_install $IPKDBG_BUILD $IPKDBG_CONF
368*c7a446e2SAndrew Jeffery
369*c7a446e2SAndrew Jeffery# Extract the binary path from the core
370*c7a446e2SAndrew Jefferyif [ '-' = "$IPKDBG_FILE" -a '-' != "$IPKDBG_CORE" ]
371*c7a446e2SAndrew Jefferythen
372*c7a446e2SAndrew Jeffery    IPKDBG_FILE=$(ipkdbg_gdb_extract_bin $IPKDBG_CORE)
373*c7a446e2SAndrew Jefferyfi
374*c7a446e2SAndrew Jeffery
375*c7a446e2SAndrew Jeffery# Update the package database before potentially looking up the debug packages
376*c7a446e2SAndrew Jefferyipkdbg_opkg update
377*c7a446e2SAndrew Jeffery
378*c7a446e2SAndrew Jeffery# Extract the package name for the binary
379*c7a446e2SAndrew Jefferyif [ '-' != "$IPKDBG_CORE" ]
380*c7a446e2SAndrew Jefferythen
381*c7a446e2SAndrew Jeffery    if ipkdbg_opkg_db_install $IPKDBG_BUILD $IPKDBG_DB
382*c7a446e2SAndrew Jeffery    then
383*c7a446e2SAndrew Jeffery        # Look up the package for the binary
384*c7a446e2SAndrew Jeffery        IPKDBG_CORE_PKG="$(IPKDBG_ROOT=$IPKDBG_DB ipkdbg_opkg search ${IPKDBG_DB}${IPKDBG_FILE} | awk '{ print $1 }')"
385*c7a446e2SAndrew Jeffery        if [ -n "$IPKDBG_CORE_PKG" ]
386*c7a446e2SAndrew Jeffery        then
387*c7a446e2SAndrew Jeffery            # Look up the extra (debug, source) packages for the binary package
388*c7a446e2SAndrew Jeffery            IPKDBG_PKGS="$IPKDBG_PKGS $IPKDBG_CORE_PKG"
389*c7a446e2SAndrew Jeffery            IPKDBG_PKGS="$IPKDBG_PKGS $(ipkdbg_opkg_find_extra $IPKDBG_CORE_PKG)"
390*c7a446e2SAndrew Jeffery        fi
391*c7a446e2SAndrew Jeffery    fi
392*c7a446e2SAndrew Jeffery
393*c7a446e2SAndrew Jeffery    if [ -z "$IPKDBG_PKGS" ]
394*c7a446e2SAndrew Jeffery    then
395*c7a446e2SAndrew Jeffery        ipkdbg_error "Unable to determine package-set to install, please specify" \
396*c7a446e2SAndrew Jeffery                 "appropriate packages on the command line"
397*c7a446e2SAndrew Jeffery        exit 1
398*c7a446e2SAndrew Jeffery    fi
399*c7a446e2SAndrew Jefferyfi
400*c7a446e2SAndrew Jeffery
401*c7a446e2SAndrew Jeffery# Force installation of gcc-runtime-dbg to give us debug symbols for libstdc++
402*c7a446e2SAndrew JefferyIPKDBG_PKGS="gcc-runtime-dbg $IPKDBG_PKGS"
403*c7a446e2SAndrew Jeffery
404*c7a446e2SAndrew Jefferyif [ -n "$IPKDBG_OPKG_CACHE" ]
405*c7a446e2SAndrew Jefferythen
406*c7a446e2SAndrew Jeffery    mkdir -p "$IPKDBG_OPKG_CACHE"
407*c7a446e2SAndrew Jeffery    ipkdbg_opkg install --download-only $IPKDBG_PKGS
408*c7a446e2SAndrew Jefferyfi
409*c7a446e2SAndrew Jeffery
410*c7a446e2SAndrew Jefferyipkdbg_opkg install $IPKDBG_PKGS | grep -vF 'Warning when extracting archive entry'
411*c7a446e2SAndrew Jeffery
412*c7a446e2SAndrew Jefferycat <<EOF > ${IPKDBG_BINS}/opkg
413*c7a446e2SAndrew Jeffery#!/bin/sh
414*c7a446e2SAndrew Jefferyexec $IPKDBG_OPKG_BIN -f $IPKDBG_CONF -o $IPKDBG_ROOT \$@
415*c7a446e2SAndrew JefferyEOF
416*c7a446e2SAndrew Jefferychmod +x ${IPKDBG_BINS}/opkg
417*c7a446e2SAndrew Jeffery
418*c7a446e2SAndrew JefferyPATH=${IPKDBG_BINS}:${PATH} $IPKDBG_GDB -q \
419*c7a446e2SAndrew Jeffery    -iex "set solib-absolute-prefix $IPKDBG_ROOT" \
420*c7a446e2SAndrew Jeffery    -iex "add-auto-load-safe-path $IPKDBG_ROOT" \
421*c7a446e2SAndrew Jeffery    -iex "set directories $IPKDBG_ROOT" \
422*c7a446e2SAndrew Jeffery    -iex "cd $IPKDBG_ROOT" \
423*c7a446e2SAndrew Jeffery    $([ '-' = "$IPKDBG_CORE" ] || echo -ex bt) \
424*c7a446e2SAndrew Jeffery    $([ 0 -eq $IPKDBG_OPT_QUIT ] || echo -ex quit) \
425*c7a446e2SAndrew Jeffery    ${IPKDBG_ROOT}${IPKDBG_FILE} \
426*c7a446e2SAndrew Jeffery    $([ '-' = "$IPKDBG_CORE" ] || echo $IPKDBG_CORE)
427*c7a446e2SAndrew Jeffery
428*c7a446e2SAndrew Jefferyexit 0
429*c7a446e2SAndrew Jeffery
430*c7a446e2SAndrew Jeffery__ARCHIVE_BEGIN__
431