Chyba zepuste uClibc na TH - lvm2 i device-mapper
Jakub Bogusz
qboosh at pld-linux.org
Mon Jun 4 19:51:02 CEST 2007
On Mon, Jun 04, 2007 at 05:52:55PM +0200, Jakub Bogusz wrote:
> Nawet jeśli ten poprzedni prototyp dołącza wcześniej, to w krótkim kodzie
> nie powoduje to pominięcia warunku:
>
> #v+
> #include <stdlib.h>
>
> extern void func1(void);
> extern void func2(void) __attribute__((visibility("hidden")));
>
> extern void __attribute__((weak)) func1(void);
> extern void __attribute__((weak)) func2(void) __attribute__((visibility("hidden")));
>
> # define likely(x) __builtin_expect((!!(x)),1)
>
> int main()
> {
> if(likely(func1 != NULL))
> func1();
> if(likely(func2 != NULL))
> func2();
> }
> #v-
Dobra, mam warunki brzegowe.
-O{1,2,s} + -fPIC.
Przy czym w zrzucie drzewa warunek dalej jest, nie ma go dopiero
w kodzie asemblerowym.
#v+
$ cat ah.c.t93.optimized
;; Function main (main)
Analyzing Edge Insertions.
main ()
{
<bb 0>:
if (func1 != 0B) goto <L0>; else goto <L1>;
<L0>:;
func1 ();
<L1>:;
if (func2 != 0B) goto <L2>; else goto <L3>;
<L2>:;
func2 () [tail call];
<L3>:;
return;
#v-
#v+
$ diff -u ah.s.O{0,1}
--- ah.s.O0 2007-06-04 19:18:03.849740867 +0200
+++ ah.s.O1 2007-06-04 19:17:59.273480081 +0200
@@ -8,22 +8,18 @@
pushl -4(%ecx)
pushl %ebp
movl %esp, %ebp
- pushl %ebx
- pushl %ecx
+ subl $8, %esp
+ movl %ecx, (%esp)
+ movl %ebx, 4(%esp)
call __i686.get_pc_thunk.bx
addl $_GLOBAL_OFFSET_TABLE_, %ebx
- movl func1 at GOT(%ebx), %eax
- testl %eax, %eax
+ cmpl $0, func1 at GOT(%ebx)
je .L2
call func1 at PLT
.L2:
- leal func2 at GOTOFF(%ebx), %eax
- testl %eax, %eax
- je .L7
call func2
-.L7:
- popl %ecx
- popl %ebx
+ movl (%esp), %ecx
+ movl 4(%esp), %ebx
leave
leal -4(%ecx), %esp
ret
#v-
Też bym się nie spodziewał, że przy adresie wyliczanym względem kodu,
bez tablicy relokacji, wyjdzie NULL ;)
Już rozumiem jak to działa:
- bez -fPIC są inne relokacje i adresy wstawiane bezpośrednio w kod
(przez ld przy linkowaniu statycznym; przy dynamicznym przez ld-linux,
ale nie na wszystkich architekturach jest to obsługiwane) - tutaj gcc
nie zakłada niezerowości
- przy -fPIC i visibility=default i linkowaniu dynamicznym rekolacja
obliczana jest w runtime i sprawdzenie musi być obecne w kodzie;
przy statycznym jest obliczana przez ld
- przy -fPIC i visibility=hidden i linkowaniu dynamicznym adres jest
obliczany przez ld; i tu sprawdza się założenie gcc o niezerowości
adresu - symbol jest zawsze obecny w bibliotece współdzielonej
(no dobra, da się zlinkować bez, ale to nie ma sensu, bo binarka
czy inna biblioteka już tego symbolu nie dostarczy)
natomiast przy statycznym linkowaniu kodu PIC fakt niezerowości
adresu symbolu jest znany w momencie linkowania, a kod został już
zoptymalizowany wcześniej z błędnym założeniem.
W sumie to się nadaje do zgłoszenia do gcc - jeśli zakładają nie
robienie takich rzeczy, to niech przynajmniej udokumentują, że
przy PIC+weak+visibility=hidden dla extern "weak" jest ignorowane.
A swoją drogą na listę uclibc też to można opisać.
--
Jakub Bogusz http://qboosh.pl/
More information about the pld-devel-pl
mailing list