Portál AbcLinuxu, 2. května 2025 05:33

Nástroje: Začni sledovat (1) ?Zašle upozornění na váš email při vložení nového komentáře.

Vložit další komentář
8.6.2017 23:48 Sten
Rozbalit Rozbalit vše Re: Analýza ELF binárky - jak ji oholit o přebytečné bajty
Odpovědět | Sbalit | Link | Blokovat | Admin
Nepůsobí -fdata-sections a -ffunction-sections naopak zvětšení binárky, když má každá funkce svou sekci, která je uvedena ve výsledkem souboru, nebo ty sekce linker nakonec spojí do jedné?
limit_false avatar 9.6.2017 00:28 limit_false | skóre: 23 | blog: limit_false
Rozbalit Rozbalit vše Re: Analýza ELF binárky - jak ji oholit o přebytečné bajty
Ze zkušenosti ne. Když se na ty symboly dívám, tak akorát vyžadují zarování na 32-bit hranici, ale to potřebovali i předtím. Ten trik se sekcemi jen jenom hack na linker.

Zřejmě každý typ sekce má jiný alignment. Tyhle .text.symbol se mi zarovnávají na 4 bajty, .text sekce celá na 16 bajtů. Aktuální objdump dokonce ukazuje i "fill" (nepoužité bajty kvůli zarovnání).

Zřejmě víc by bylo vidět z linker scriptu.
When people want prime order group, give them prime order group.
limit_false avatar 9.6.2017 01:16 limit_false | skóre: 23 | blog: limit_false
Rozbalit Rozbalit vše Re: Analýza ELF binárky - jak ji oholit o přebytečné bajty
Manuál gcc má taky zmínku o zvětšení object fajlu, ale když to zkouším, tak mi to vychází opačně - zmenší se.

V mém případě (kvůli kterému jsem tohle řešil) jenom ty dva flagy ořezali z cca 35 MB ARM binárky asi 2.5 MB.

S -Wl,-verbose lze vypsat aktuální linker script, ale zatím jsem z toho nevyčetl podstatní rozdíl.
When people want prime order group, give them prime order group.
9.6.2017 01:37 pc2005 | skóre: 38 | blog: GardenOfEdenConfiguration | liberec
Rozbalit Rozbalit vše Re: Analýza ELF binárky - jak ji oholit o přebytečné bajty
Odpovědět | Sbalit | Link | Blokovat | Admin
Zkoušels i -fwhole-program a zda nějak zmenší binárku?
Intel meltdown a = arr[x[0]&1]; karma | 帮帮我,我被锁在中国房
limit_false avatar 9.6.2017 12:13 limit_false | skóre: 23 | blog: limit_false
Rozbalit Rozbalit vše Re: Analýza ELF binárky - jak ji oholit o přebytečné bajty
Vyzkoušel jsem to, ale nemá to žádný efekt.
When people want prime order group, give them prime order group.
9.6.2017 15:46 iptriz | skóre: 1 | blog: twktms
Rozbalit Rozbalit vše Re: Analýza ELF binárky - jak ji oholit o přebytečné bajty
Odpovědět | Sbalit | Link | Blokovat | Admin
Výborně, něco takového jsem před pár dny řešil (jen s řádově menší binárkou), akorát by to chtělo ještě ten kumulativní výpočet velikosti symbolů, no snad mi to moc nepotrvá. Kdyby se mezitím někomu nelíbil sed/awk, tohle se tváří funkčně ekvivalentně...
objdump -d "$1" | perl -lne 'if(/<([^+]*).*?>(:?)/){if($2){$w=$1}elsif($w ne$1){print"$w $1"}}' | sort -u
9.6.2017 17:49 iptriz | skóre: 1 | blog: twktms
Rozbalit Rozbalit vše Re: Analýza ELF binárky - jak ji oholit o přebytečné bajty
Tak bohužel se ukázalo, že to moc nefunguje – když jdu grafem od mainu, posbírám jen 1/3 velikosti programu. Ověřil jsem si, že to je problém v objdump, kde minimálně jedna funkce nemá jiný odkaz než sama na sebe. Nějaké nápady, co s tím?
#!/bin/sh
objdump -d "$1" | perl -lne 'next unless/<([^+]*).*?>(:?)/;
	if($2){$w=$1}elsif($w ne$1){print"$w $1"}' | sort -u > deps

nm --synthetic --print-size --size-sort --radix=d "$1" | awk '
	function collect(name, set,  i) {
		used[name]++
		if (set[name]++)
			return
		for (i = 0; i < deps[name]; i++)
			collect(deps[name, i], set)
	}
	function run(name,  set, sum, i) {
		set[name] = sum = 0
		collect(name, set)
		for (i in set) sum += sizes[i]
		print name, sizes[name], sum
	}
	{ sizes[$4] = $2 + 0 } END {
		while ((getline < "deps") > 0) { deps[$1, deps[$1]++] = $2 }
		for (name in sizes) run(name)
		for (name in used) if (used[name] < 2) print name > "unreferenced"
	}' | sort -nk3
9.6.2017 18:00 iptriz | skóre: 1 | blog: twktms
Rozbalit Rozbalit vše Re: Analýza ELF binárky - jak ji oholit o přebytečné bajty
000000000041865f <my_funny_callback>:
  41865f:       55                      push   %rbp
[...]
  418739:       be 5f 86 41 00          mov    $0x41865f,%esi
Vypadá to, že to bude chtít mnohem víc Perlu.
9.6.2017 18:25 iptriz | skóre: 1 | blog: twktms
Rozbalit Rozbalit vše Re: Analýza ELF binárky - jak ji oholit o přebytečné bajty
Abych z toho udělal nějaký závěr:
  • objdump neresolvuje callbacky předávané argumentem – lze vyřešit
  • objdump neresolvuje callbacky z dat – nelze vyřešit
Tedy vždy to bude pouze orientační, každopádně velmi rychlé a jednoduché.
limit_false avatar 10.6.2017 01:18 limit_false | skóre: 23 | blog: limit_false
Rozbalit Rozbalit vše Re: Analýza ELF binárky - jak ji oholit o přebytečné bajty
Jop, čekal jsem něco podobného. objdump někdy resolvuje parametry předáváné odkazem (původně jsem třeba podezříval pthread_create za skrývání symbolů) a někdy resolvuje callbacky z dat (nevím nakolik je tolerantní na zanořené reference).

Každopádně mi to přijde jako zajímavý problém, kterého řešení by mohlo zajímat i někoho jiného. Linker (GNU ld) všechny potřebné informace má, otázka zní, jak to z něj dostat?

Nějaký tip kam se zeptat? Našel jsem binutils mailing-list, ale nevím zda je to vhodný mailinglist (plus nevidím způsob jak se subscribnout).
When people want prime order group, give them prime order group.
10.6.2017 03:22 pc2005 | skóre: 38 | blog: GardenOfEdenConfiguration | liberec
Rozbalit Rozbalit vše Re: Analýza ELF binárky - jak ji oholit o přebytečné bajty
Co když mám pole callbacků (a generuju adresu přes nějakej index)? O tom snad linker nemůže vědět ne?

Je nutné se subscribovat? Já když posílám patche do kernelu, tak jen pošlu mail na mailing list z MAINTAINERS. V nejhorším ti přijde mail ať pošleš subscribe majordom botovi. Takže bych jen poslal mail na binutils at sourceware dot org (okopírované z jednoho mailu) a hotovo :-D.
limit_false avatar 10.6.2017 21:13 limit_false | skóre: 23 | blog: limit_false
Rozbalit Rozbalit vše Re: Analýza ELF binárky - jak ji oholit o přebytečné bajty
Úplně nerozumím, jaký je problém s polem callbacků. Linker prostě musí vzít všechny symboly, které jsou referencované a doplnit je do binárky buď kopírovaním nebo jako UNDEFINED odkaz.
When people want prime order group, give them prime order group.
11.6.2017 00:21 pc2005 | skóre: 38 | blog: GardenOfEdenConfiguration | liberec
Rozbalit Rozbalit vše Re: Analýza ELF binárky - jak ji oholit o přebytečné bajty
Jo on ten callback bude vlastně někde přiřazenej a to udělá referenci :-/.
10.6.2017 03:15 pc2005 | skóre: 38 | blog: GardenOfEdenConfiguration | liberec
Rozbalit Rozbalit vše Re: Analýza ELF binárky - jak ji oholit o přebytečné bajty
Jo callbacky jsou zlo!
10.6.2017 15:56 iptriz | skóre: 1 | blog: twktms
Rozbalit Rozbalit vše Re: Analýza ELF binárky - jak ji oholit o přebytečné bajty
Víc Perlu vypadá takto:
objdump -d "$1" | perl -lne '
	if (/^0*([\da-f]+) <(.+?)>:/) { $a{$1} = $w = $2
	} elsif (/<([^+]*).*?>/) { print "$w $1" if $w ne $1
	} elsif (/0x([\da-f]+),/) { push @{$deps{$w}}, $1
	} END { while (my ($w, $refs) = each %deps) {
		for (@$refs) { print "$w $a{$_}" if exists $a{$_} }
	}}' | sort -u > deps
Skóre: main vzrostl z 26.1% na 35.6% velikosti sstripnuté binárky. _start začal být větší než main. Konkrétní program obsahuje callbacky v datech s nemalým podstromem.
10.6.2017 16:22 iptriz | skóre: 1 | blog: twktms
Rozbalit Rozbalit vše Re: Analýza ELF binárky - jak ji oholit o přebytečné bajty
Drobnou úpravou se dostáváme k 21.8% → 51.7% sstripnutého release buildu:
objdump -d "$1" | perl -lne '
	if (/^0*([\da-f]+) <(.+?)>:/) { $a{$1} = $w = $2; next }
	print "$w $1" if /<([^+]*).*?>/ && $w ne $1;
	push @{$deps{$w}}, $1 if /0x([\da-f]+),/;
	END { while (my ($w, $refs) = each %deps) {
		for (@$refs) { print "$w $a{$_}" if exists $a{$_} }
	}}' | sort -u > deps
10.6.2017 17:42 iptriz | skóre: 1 | blog: twktms
Rozbalit Rozbalit vše Re: Analýza ELF binárky - jak ji oholit o přebytečné bajty
Ještě jde resolvnout pár zbylých odkazů na data a zde asi definitivně končím:
nm "$1" | perl -lne 'print for /^0*(\S+) . (\S+)/' > addresses
objdump -d "$1" | perl -lne '
	if (/<([^+]*).*?>(:?)/) { $w = $1 if $2; print "$w $1" if $w ne $1 }
	BEGIN { %a = (split " ", `cat addresses`) }
	print "$w $a{$1}" if /0x([\da-f]+),/ && exists $a{$1}' | sort -u > deps
Další krok je omílaný linker nebo potenciálně DWARF.
12.6.2017 01:04 iptriz | skóre: 1 | blog: twktms
Rozbalit Rozbalit vše Re: Analýza ELF binárky - jak ji oholit o přebytečné bajty
Mimovolně jsem ještě došel k tomu, že ty informace jdou vytahat z object souborů, přes objdump -x. Člověk si ze "symbol table" posbírá offsety a velikosti a pak projíždí "relocation records" a zpětně resolvuje. Object soubory jenom už může být trochu problém posbírat, možná přes nějaký falešný kompilátor/linker jak to dělá scan-build analyzátor, ccache a podobné, a pořád to nemusí být triviální (více object files na jedny zdrojáky s různými defines), tak možná počkat na finální link příkaz do binárky a poprat se i s .a soubory. Teoreticky by se to dalo sledovat i přes strace/ptrace místo wrapperů.
12.6.2017 01:09 iptriz | skóre: 1 | blog: twktms
Rozbalit Rozbalit vše Re: Analýza ELF binárky - jak ji oholit o přebytečné bajty
Ono to jde vytahat i z toho output.map souboru ze sekce "Linker script and memory map", řádky LOAD s názvy souborů se dají docela snadno vyparsovat. Problém je, když se linkuje víc věcí, pak se ty output.map přepisují.
limit_false avatar 10.6.2017 03:14 limit_false | skóre: 23 | blog: limit_false
Rozbalit Rozbalit vše Re: Analýza ELF binárky - jak ji oholit o přebytečné bajty
Celkem bych se mi hodil nějaký krátký příklad, na kterém se to projevuje. (Plus compile a link flagy).
When people want prime order group, give them prime order group.
10.6.2017 03:42 pc2005 | skóre: 38 | blog: GardenOfEdenConfiguration | liberec
Rozbalit Rozbalit vše Re: Analýza ELF binárky - jak ji oholit o přebytečné bajty
Odpovědět | Sbalit | Link | Blokovat | Admin
BTW o co že takhle diskuze nakonec skončí u analýzy pomocí spuštění v QEMU :-D.
Intel meltdown a = arr[x[0]&1]; karma | 帮帮我,我被锁在中国房

Založit nové vláknoNahoru

Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.