Chyba zepuste uClibc na TH - lvm2 i device-mapper
Jakub Bogusz
qboosh w pld-linux.org
Pon, 4 Cze 2007, 19:51:02 CEST
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 w GOT(%ebx), %eax
- testl %eax, %eax
+ cmpl $0, func1 w GOT(%ebx)
je .L2
call func1 w PLT
.L2:
- leal func2 w 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/
Więcej informacji o liście dyskusyjnej pld-devel-pl