Если это общая библиотека
Вы, к сожалению, отыгрались; невозможно узнать, где
библиотеки были помещены в память динамическим компоновщиком после факта .
Ну, есть возможность получить информацию не из двоичного файла, а из объекта. Но вам нужен базовый адрес объекта. И эта информация все еще находится в coredump, в структуре link_map.
Итак, сначала вы хотите импортировать struct link_map в GDB. Итак, давайте скомпилируем программу с символом отладки и добавим ее в GDB.
link.c
#include <link.h>
toto(){struct link_map * s = 0x400;}
get_baseaddr_from_coredump.sh
#!/bin/bash
BINARY=$(which myapplication)
IsBinPIE ()
{
readelf -h $1|grep 'Type' |grep "EXEC">/dev/null || return 0
return 1
}
Hex2Decimal ()
{
export number="`echo "$1" | sed -e 's:^0[xX]::' | tr '[a-f]' '[A-F]'`"
export number=`echo "ibase=16; $number" | bc`
}
GetBinaryLength ()
{
if [ $# != 1 ]; then
echo "Error, no argument provided"
fi
IsBinPIE $1 || (echo "ET_EXEC file, need a base_address"; exit 0)
export totalsize=0
# Get PT_LOAD's size segment out of Program Header Table (ELF format)
export sizes="$(readelf -l $1 |grep LOAD |awk '{print $6}'|tr '\n' ' ')"
for size in $sizes
do Hex2Decimal "$size"; export totalsize=$(expr $number + $totalsize); export totalsize=$(expr $number + $totalsize)
done
return $totalsize
}
if [ $# = 1 ]; then
echo "Using binary $1"
IsBinPIE $1 && (echo "NOT ET_EXEC, need a base_address..."; exit 0)
BINARY=$1
fi
gcc -g3 -fPIC -shared link.c -o link.so
GOTADDR=$(readelf -S $BINARY|grep -E '\.got.plt[ \t]'|awk '{print $4}')
echo "First do the following command :"
echo file $BINARY
echo add-symbol-file ./link.so 0x0
read
echo "Now copy/paste the following into your gdb session with attached coredump"
cat <<EOF
set \$linkmapaddr = *(0x$GOTADDR + 4)
set \$mylinkmap = (struct link_map *) \$linkmapaddr
while (\$mylinkmap != 0)
if (\$mylinkmap->l_addr)
printf "add-symbol-file .%s %#.08x\n", \$mylinkmap->l_name, \$mylinkmap->l_addr
end
set \$mylinkmap = \$mylinkmap->l_next
end
Он напечатает все содержимое файла link_map в наборе команд GDB.
Само по себе это может показаться непонятным, но с base_addr общего объекта, о котором мы говорим, вы можете получить дополнительную информацию из адреса, отлаживая непосредственно связанный общий объект в другом экземпляре GDB.
Оставьте первый GDB, у которого есть идея символа.
ПРИМЕЧАНИЕ: скрипт довольно неполный, я подозреваю, что вы можете добавить ко второму параметру add-symbol-file и вывести сумму с этим значением:
readelf -S $SO_PATH|grep -E '\.text[ \t]'|awk '{print $5}'
где $ SO_PATH - это первый аргумент файла добавления символа
Надеюсь, это поможет