> > > Av rent intresse, vad är SONAME? > > > > Namnet på biblioteket som loadern använder när den skall resolva > > symbolnamn. > > > > $ ldd /bin/ld > > librt.so.1 => /lib/librt.so.1 (0x4001a000) > > libc.so.6 => /lib/libc.so.6 (0x4002b000) > > libpthread.so.0 => /lib/libpthread.so.0 (0x40146000) > > /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000) > > libc.so.6, librt.so.1 etc. är SONAME. > > Jag tackar och bockar! > > > Anledning att du byter SONAME är att biblioteken inte är binär > > kompatibla på ett eller annat vis. Alltså fungerar med stor sanolikhet > > inte ett program som är länkat mot libvorbisfile0 med libvorbisfile3. > > Detta är givetvis beroende på vilken del av ABI som används av > > programmet i fråga. > > Där dök den upp igen! Denna märkliga akronym, ABI, som dök upp i Min > Verklighet för ett litet tag sedan när jag såg att den senaste versionen av > gcc hade... öh... ändrat något som hade med ABI att göra. Det var för svårt > för mig att förså vad det var... ARGH! Vad jag känner mig dum ibland. > > > Hoppas det blev något klarare. > > Absolut, tack än en gång. > > /Fredrik Persson > >
Känn dig inte dum redan. Ett välkännt faktum är att ju mer man kan om en sak, destå mer blir man medveten om hur lite man egentligen vet! Ett exempel på ett ABI är: http://www.caldera.com/developers/gabi/2000-07-17/contents.html som anger System V's ABI. Man tar upp begrepp som objektfiler, programladdning och dynamisk länkning. ABI är utrikiska (USAiska närmare bestämt) och är en förkortning för "Application Binary Interface", vilket inte gör en så speciellt mycket klokare (se ovanstående mening). Men på svenska betyder det ungefär: Tänk dig att du gör ett program på din dator. Du kompilerar (shit, ännu en term (jäklar "shit" va visst utrikiska)) och kör sedan programmet: $ gcc hello.c -o hello $ ./hello hello world! Det du utgår från är källkod (t.ex någonting du skrivit i C), typ: Filen hello.c: #include "stdio.h" int main( int argc, char * argv[] ) { printf( "hello world!\n"); return 0; } ** preprocessorn ** gcc gör om detta i olika steg. Första steget är "preprocessorn" (-E stoppar gcc efter preprocessorn (gcc gör inte preprocessorsteget själv utan låter ett annat program "cpp" göra det), sed-commandot tar bort tomma rader och head;echo; tail visar de första och sista raderna med ... mellan av utskriften): $ gcc -E hello.c | sed -e '/^[ \t]*$/d' | (head -5; echo ...; tail -6) # 1 "hello.c" # 1 "/usr/include/stdio.h" 1 3 # 1 "/usr/include/features.h" 1 3 # 142 "/usr/include/features.h" 3 # 208 "/usr/include/features.h" 3 ... extern void funlockfile (FILE *__stream) ; # 1 "hello.c" 2 int main( int argc, char * argv[] ) { printf( "hello world!\n"); return 0; } Vilket fortfarande är c-kod fast utan #include och #define. Raderna typ # 1 "hello.c" är till för att kompilatorn ska kunna veta var i din fil ev. fel skedde. Raden med "extern" fanns i någon av include-filerna (stdio.h har andra #include i sig). ** kompilering ** Nästa steg är att "kompilera", i gcc's fall att göra om det till assembler (-S gör att gcc produserar en .s (assembler) -fil, sköts av "cc1"): $ gcc -S hello.c $ cat hello.s .file "hello.c" .version "01.01" gcc2_compiled.: .section .rodata .LC0: .string "hello world!\n" .text .align 4 .globl main .type main,@function main: pushl %ebp movl %esp,%ebp subl $8,%esp addl $-12,%esp pushl $.LC0 call printf * addl $16,%esp xorl %eax,%eax * jmp .L2 * .p2align 4,,7 * .L2: leave ret .Lfe1: .size main,.Lfe1-main .ident "GCC: (GNU) 2.95.4 20011002 (Debian prerelease)" Assembler är så nära binärkod vi kan komma medan det fortfarande är "läsbart". ** optimering ** Efter detta kan gcc "optimera" (göra den mindre och/eller snabbare) koden (t.ex med "gcc -O2 ..."). Raderna jag markerat med "*" ovan tas bort av gcc om du kör med -O2. ** assemblering ** Nästa steg är att "assemblera", vilket sköts av "as". Du får då en så kallad objektfil (.o): $ gcc -c hello.c $ cat -v hello.o | fold -w60 - [EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED] @[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@^@([EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED] @[EMAIL PROTECTED]|[EMAIL PROTECTED]@[EMAIL PROTECTED]@M-hM-| [EMAIL PROTECTED]@M-IM-CM-^MM-4&[EMAIL PROTECTED]@[EMAIL PROTECTED]@M-^MM-<' [EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED] world! [EMAIL PROTECTED]@GCC: (GNU) 2.95.4 20011002 (Debian prerelease)[EMAIL PROTECTED]@.symta [EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED] [EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED] @[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@^ @[EMAIL PROTECTED]@[EMAIL PROTECTED]@^@@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED] @[EMAIL PROTECTED]@ [EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@ [EMAIL PROTECTED]@ [EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@ [EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED] [EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@ [EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@^@ [EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@^ @[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@>[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@ [EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@^ @[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED] @[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@ [EMAIL PROTECTED]@[EMAIL PROTECTED]@ [EMAIL PROTECTED]@^@ [EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@^@ [EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@^@ [EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@^@ [EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@^ @[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED] @[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@^D^@ [EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED] [EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED] [EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@^@"[EMAIL PROTECTED]@^ @[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@gcc2_com [EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED]@[EMAIL PROTECTED] [EMAIL PROTECTED]@ Den är ju inte direkt läsbar. Den innehåller instruktionerna (binärkoden) som du specade i c-koden på ett sådant sätt som processorn förstår. ** länkning ** Men det räcker inte med det för att kunna köra filen: $ chmod 755 hello.o $ ./hello.o bash: ./hello.o: cannot execute binary file $ eftersom filen inte är uppbyggd så att man köra den direkt. Den innehåller ett anrop på printf man inte vad prinf gör. #include <stdio.h> som fanns i källkoden talar bara om hur man anropar printf (dvs. API't), men inte hur man gör när man gör "printf". Dessutom, printf vet hur den ska skriva ut, men den har inte någon hum om hur man får stdout att bli skärmen. Till det behövs någon kontakt med omgivningen (görs av lib som heter libcrt och liknande, gör gcc -v hello.c för att se vilka program som gcc använder och deras argumentlista, där ser också du vilka lib som automagiskt följer med). API betyder "Application Programming Interface" eller något liknande, och anger hur man gör i källkoden (typ: "#include <stdio.h>" och printf("hello world!\n")) för att utnyttja det (printf i det här fallet) som någon annan gjort. Man har istället gjort .o filer så att det ska vara lätt att kombinera dem med varandra. Detta kallas för att länka filerna. Program för att hantera objektfiler finns i binutils: $ echo `cat /var/lib/dpkg/info/binutils.list | grep /usr/bin/ | > sed -e 's|/usr/bin/||g'` | fold -w60 -b size objdump ar strings ranlib objcopy addr2line readelf nm strip c++filt as gprof ld (Kolla gärna upp deras mansidor eller kör "info binutils"). Det finns olika objektfilsformat. Det som används nu kallas ELF. Ett gammalt format heter COFF, och ett annat hetar a.out. Kör objdump -i för att se alla som binutils känner till. http://www.linuxjournal.com/article.php?sid=1059 http://www.linuxjournal.com/article.php?sid=1060 berättar lite om elf-formatet. Nåväl, objektfiler är indelade i något som kallas för "sections" (det är väl taget från litteraturen, meningarna i en bok är grupperade i "sections" dvs. stycken). I en "section" som kallas för "text" finns binärkoden, och i "symtab" finns en lista över alla symboler i objektfilen. En symbol är helt enkelt en funktion, variabel eller något annat som vi behöver veta vilken adress den befinner sig på. För man behöver i vårt falla para ihop anropet "printf" men adressen i något lib där printf's kod finns. Och då tittar men i alla libben som gcc angett, i deras sektionen symtab om det finns någon symbol som heter printf som har ett värde, dvs. koden finns där på den adressen (hmm, lätt förenklat förståss). Nå, var var vi. Jo, efter assemblering måste vi "länka" objektfilerna. Dvs. vi måste: . para ihop alla anrop till funktioner och användningen av globala variabler som inte är definierade i samma objektfil . slå ihop alla objektfiler som angets på kommandoraden . lägga till alla statiska bibliotek (lib) . lägga till info så att vi kan länka (igen) alla dynamisk bibliotek när vi ska köra programmet . skriva ut detta på disken som filen/programmet "hello" (i mitt exempel) ** programladdning och dynamisk länkning ** Sedan när vi ska "köra" programmet, så måste vi ladda programet till minnet och göra den sista dynamiska länkningen. DVS.: Ett ABI är en specifikation. Den ska se till att alla steg (från att man har objektfiler till det att man kan köra programmet) fungerar. För att detta ska fungera måste ABI't speca objektfilernas format, programladdningen och den dynamiska länkning. Hälsningar, /Karl ----------------------------------------------------------------------- Karl Hammar Aspö Data [EMAIL PROTECTED] Lilla Aspö 2340 0173 140 57 Nätverk S-742 94 Östhammar 018 260 900 Datorer/Utrustning Sweden 010 270 26 67 Linux/Unix konsulting -----------------------------------------------------------------------