Наши партнеры

UnixForum





Библиотека сайта rus-linux.net

На главную -> MyLDP -> Программирование и алгоритмические языки


Ulrich Drepper "Как писать разделяемые библиотеки"
Назад Оглавление Вперед

A. Вычисляемые перемещения

Следующий скрипт вычисляет количество обычных и относительных перемещений, а также количество записей PLT, которые есть в двоичном модуле. Если используется соответствующая реализация readelf, то скрипт можно использовать для поиска всех файлов в архиве. Если есть и используется механизм предкомпоновки prelink [7], скрипт также попытается предоставить информацию о том, как часто используется DSO. Это наведет пользователя на мысль о том, каков будет "ущерб" от неправильно написанного DSO.

#! /usr/bin/perl
eval "exec /usr/bin/perl -S $0 $*"
	if 0;
# Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Ulrich Drepper
# Автор Ulrich Drepper <drepper@gmail.com>, 2000.

# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.   */

for ($cnt = 0; $cnt <= $#ARGV; ++$cnt) {
	$relent = 0;
	$relsz = 0;
	$relcount = 0;
	$pltrelsz = 0;
	$extplt = 0;
	$users = 0;

	open (READLINK, "readlink -f $ARGV[$cnt] |") || die "cannot open readlink";
	while (<READLINK>) {
		chop;
		$fullpath = $_;
	}
	close (READLINK);

	open (READELF, "eu-readelf -d $ARGV[$cnt] |") || die "cannot open $ARGV[$cnt]";
	while (<READELF>) {
		chop;
		if (/.* \(RELENT\) *([0-9]*).*/) {
			$relent = $1 + 0;
		} elsif (/.* \(RELSZ\) *([0-9]*).*/) {
			$relsz = $1 + 0;
		} elsif (/.* \(RELCOUNT\) *([0-9]*).*/) {
			$relcount = $1 + 0;
		} elsif (/.* \(PLTRELSZ\) *([0-9]*).*/) {
			$pltrelsz = $1 + 0;
		}
	}
	close (READELF);

	open (READELF, "eu-readelf -r $ARGV[$cnt] |") || die "cannot open $ARGV[$cnt]";
	while (<READELF>) {
		chop;
		if (/.*JU?MP_SLOT *0+ .*/) {
			++$extplt;
		}

	}
	close (READELF);

	if (open (PRELINK, "/usr/sbin/prelink -p 2>/dev/null | fgrep \"$fullpath\" |")) {
		while (<PRELINK>) {
			++$users;
		}
		close(PRELINK);
	} else {
		$users = -1;
	}

	printf("%s: %d relocations, %d relative (%d%%), %d PLT entries, %d for local syms (%d%%)",
		$ARGV[$cnt], $relent == 0 ? 0 : $relsz / $relent, $relcount,
		$relent == 0 ? 0 : ($relcount * 100) / ($relsz / $relent),
		$relent == 0 ? 0 : $pltrelsz / $relent,
		$relent == 0 ? 0 : $pltrelsz / $relent - $extplt,
		$relent == 0 ? 0 : ((($pltrelsz / $relent - $extplt) * 100)
			/ ($pltrelsz / $relent)));
	if ($users >= 0) {
		printf(", %d users", $users);
	}
	printf("\n");
}

Предыдущий раздел:   Следующий раздел:
Назад Оглавление Вперед