Σελίδα 1 από 1

Static-dynamic linking με ld

ΔημοσίευσηΔημοσιεύτηκε: 13 Ιαν 2013, 15:41
από alkismavridis
Καλησπέρα σας!
Επειδή οι γνώσεις μου πάνω σε θέματα linking είναι παιδαριώδεις, θα ήθελα να σας ρωτήσω το εξής:

Πως με το ld μπορώ να συνδέσω static (δηλαδή το αρχείο που θα βγει να έχει "καταπιεί" την βιβλιοθήκη), και πως dynamic (δηλαδή το αρχείο που θα βγεί να συνδέεται κατά την εκτέλεση με την βιβλιοθήκη);;;

Ας το κάνω πιο συγκεκριμένο:
έχω 5 αρχεία:
τα lib1.o, lib2.o lib3.o, lib4.o και main.o

Όλα compiled από το NASM (καθαρό assembly) σε μορφή elf64. Το main.o πρέπει να συνδεθεί με τα άλλα 4 για να δουλέψει.
Και θέλω: Η σύνδεση με τα δύο πρώτα να είναι static, δηλαδή ακόμα και αν τα σβήσω, το πρόγραμμα να δουλεύει κανονικά,
και η σύνδηση με τα δύο τελευταία να είναι dynamic, δηλαδή το πρόγραμμα να μην τα "εσωκλείει", αλλά να τα ψάχνει κατά την εκτέλεση.
Τι πρέπει να πατήσω στο ld??

Ευχαριστώ πολύ!

Re: Static-dynamic linking με ld

ΔημοσίευσηΔημοσιεύτηκε: 13 Ιαν 2013, 19:14
από simosx
alkismavridis έγραψε:Ας το κάνω πιο συγκεκριμένο:
έχω 5 αρχεία:
τα lib1.o, lib2.o lib3.o, lib4.o και main.o

Όλα compiled από το NASM (καθαρό assembly) σε μορφή elf64. Το main.o πρέπει να συνδεθεί με τα άλλα 4 για να δουλέψει.
Και θέλω: Η σύνδεση με τα δύο πρώτα να είναι static, δηλαδή ακόμα και αν τα σβήσω, το πρόγραμμα να δουλεύει κανονικά,
και η σύνδηση με τα δύο τελευταία να είναι dynamic, δηλαδή το πρόγραμμα να μην τα "εσωκλείει", αλλά να τα ψάχνει κατά την εκτέλεση.
Τι πρέπει να πατήσω στο ld??


Τα δύο πρώτα ούτως ή άλλως θα συμπεριληφθούν στο τελικό εκτελέσιμο. Για τα δύο άλλα, πρέπει να τα φτιάξεις σε δυναμικές βιβλιοθήκες, π.χ. lib3.so, lib4.so, και κατά τη μεταγλώττιση να γράψεις κάτι σαν
Κώδικας: Επιλογή όλων
gcc lib1.o lib2.o -L. -l3 -l4 main.o -o main

Re: Static-dynamic linking με ld

ΔημοσίευσηΔημοσιεύτηκε: 13 Ιαν 2013, 21:05
από alkismavridis
Οκ... άρα το όλο θέμα έχει να κάνει με το compile...
Μήπως ξέρετε πως ο NASM δημιουργεί δυναμικές βιβλιοθήκες;; στο manual δε βγάζω άκρη :(

Έδωσα την εντολή που μου είπες, και απο ότι βλέπω ο gcc καλεί το ld, προσπαθώντας να συνδέσει με κάτι άλλα περίεργα όπως crt1.o... Γιατί αυτό;
Το αποτέλεσμα είναι κάτι error για πολλαπλες "_start", γιατί στο αρχείο crt1.o υπάρχουν και άλλες εκτώς από τη δική μου..
Δε γίνεται η δουλειά χωρίς να μπέξω με τον gcc; Απ ευθείας με το ld;

Re: Static-dynamic linking με ld

ΔημοσίευσηΔημοσιεύτηκε: 13 Ιαν 2013, 21:27
από simosx
Έχω γράψει οδηγό στο φόρουμ μας για τη μεταγλώττιση μέσω nasm, όπου αναφέρω κάποια πράγματα.
Για να κάνουμε το όλο έργο πιο πρακτικό, μπορείς να δώσεις τέτοια μικρά αρχεία, με lib1.nasm που θα είναι στατικό, lib2.nasm που θα είναι δυναμικό και θα γίνει βιβλιοθήκη, και ένα main.nasm.
Οπότε από εκεί θα προσπαθήσουμε να φτιάξουμε τη δυναμική βιβλιοθήκη και να παραχθεί το τελικό εκτελέσιμο.

Re: Static-dynamic linking με ld

ΔημοσίευσηΔημοσιεύτηκε: 13 Ιαν 2013, 21:56
από alkismavridis
****επεξεργασία****** αν μπείτε στην διαδικασία να δείτε τι κάνουν οι lib1.asm και lib.asm, διαβάστε πρώτα την lib2 :-)


Οκ δίνω τα εξής:
Στο αρχείο lib1.asm (αυτή την κατάληξη συνηθίζω, αλλά δε νομίζω ότι κάνει διαφορά...). Ας πούμε αυτή να είναι η στατική:

Κώδικας: Επιλογή όλων
global printNumber32R

[section .bss]
num resb 10



[section .text]




printNumber32R:   
   ;does the same with printNumber32, but doesn't affect any Register
   ;the number to print MUST be in eax
   ;ebx -> index of the memory to save the digit
   ;ecd -> Numbering system, wich is...10
   
   
   
   push rax ;save registers
   push rbx
   push rcx
   push rdx
   
   
   mov [num+10], byte 10 ;new line
   mov ebx, num
   add ebx, 9 ;aim to the last
   mov ecx,10 ;the divisor/numbering system. If you change this, you will get other numbering systems
   
   
   
   digitloop: ;-----------------------calculate the digits-----------------------
   mov edx,0 ;clean the remainder area!
   div ecx ;now the eax=result, edx=remainder
   
   add dl,30h ;convert to ascii and put it to the memory!
   mov [ebx],dl
   
   dec ebx ;go to the next digit's place, otherwise.
   cmp eax,0 ;finish if you wrote all digits
   je clearloop
   jmp digitloop
   
   
   clearloop: ;------------------------clear the higher digits from what they may had before---------------------
   cmp ebx,num
   jle clearend
   mov [ebx], byte 0
   dec ebx
   jmp clearloop
   clearend:
   

   mov eax, 4 ;----------------------write it!----------------------------
   mov ebx,1
   mov ecx, num
   mov edx, 11
   int 80h
   
   pop rdx ;restore registers
   pop rcx
   pop rbx
   pop rax
   ret


Στο αρχείο lib2.asm (η δυναμική)
Κώδικας: Επιλογή όλων
global printNumber32

[section .bss]
num resb 10

[section .text]



printNumber32:
   ;the number to print MUST be in eax
   
   ;ebx -> index of the memory to save the digit
   ;ecd -> Numbering system, wich is...10
   
   mov [num+10], byte 10 ;new line
   mov ebx, num
   add ebx, 9 ;aim to the last
   mov ecx,10 ;the divisor/numbering system. If you change this, you will get other numbering systems
   
   
   
   digitloop: ;-----------------------calculate the digits-----------------------
   mov edx,0 ;clean the remainder area!
   div ecx ;now the eax=result, edx=remainder
   
   add dl,30h ;convert to ascii and put it to the memory!
   mov [ebx],dl
   
   dec ebx ;go to the next digit's place, otherwise.
   cmp eax,0 ;finish if you wrote all digits
   je clearloop
   jmp digitloop
   
   
   clearloop: ;------------------------clear the higher digits from what they may had before---------------------
   cmp ebx,num
   jle clearend
   mov [ebx], byte 0
   dec ebx
   jmp clearloop
   clearend:
   

   mov eax, 4 ;----------------------write it!----------------------------
   mov ebx,1
   mov ecx, num
   mov edx, 11
   int 80h

   ret

(στην ουσία κάνει την ίδια δουλειά με την lib1.asm, αλλά δεν μπαίνει στον κόπο να σώσει τα registers)

και η main.asm:
Κώδικας: Επιλογή όλων
extern printNumber32, printNumber32R
global _start

[section .text]


_start:

   mov eax,159872
   call printNumber32R
   
   mov eax,2
   call printNumber32
   
   mov eax,1
   mov ebx,0
   int 80h


Αν πατήσεις τις εντολές
Κώδικας: Επιλογή όλων
alkis@Alkis:~/Programs/assembly/linking$ nasm -felf64 lib1.asm
alkis@Alkis:~/Programs/assembly/linking$ nasm -felf64 lib2.asm
alkis@Alkis:~/Programs/assembly/linking$ nasm -felf64 main.asm
alkis@Alkis:~/Programs/assembly/linking$ ld -o Program lib1.o lib2.o main.o
alkis@Alkis:~/Programs/assembly/linking$ ./Program
159872
2
alkis@Alkis:~/Programs/assembly/linking$

παιζει κανονικά.
Αλλά εδώ είναι όλα στατικά.
Αν πχ. πάω και σβήσω το lib2.o που έχει δημιουργηθεί, το πράγμα δουλεύει ακόμα...

Re: Static-dynamic linking με ld  Το θέμα επιλύθηκε

ΔημοσίευσηΔημοσιεύτηκε: 13 Ιαν 2013, 23:12
από simosx
alkismavridis έγραψε:Αλλά εδώ είναι όλα στατικά.
Αν πχ. πάω και σβήσω το lib2.o που έχει δημιουργηθεί, το πράγμα δουλεύει ακόμα...


Το lib2.asm χρειάζεται να τροποποιηθεί ώστε να είναι εφικτό να δημιουργηθεί μια δυναμική/διαμοιραζόμενη βιβλιοθήκη.
Δες την ενότητα 9.2 στο http://www.nasm.us/doc/nasmdoc9.html

Περιληπτικά,
1. μια διαμοιραζόμενη βιβλιοθήκη τοποθετείται στη μνήμη κατά τη φόρτωση, οπότε ο παραδοσιακός τρόπος χειρισμού των μεταβλητών δε λειτουργεί (πρέπει να καθορίσεις σε σχέση με τη μετατόπιση από τη θέση που θα τοποθετηθεί σε κάθε εκτέλεση). Εδώ χρησιμοποιείς μετατοπίσεις σε σχέση με το GOT, global offset table. Στον παραπάνω σύνδεσμο αναφέρει λεπτομέρειες, στο 9.2.
Χρειάζεται δηλαδή μετατροπή στον κώδικα.

2. Για τη μεταγλώττιση του lib2.asm, γράφεις κάτι σαν
Κώδικας: Επιλογή όλων
ld -shared -o lib2.so lib2.o

οπότε και θα παραχθεί δυναμική/διαμοιραζόμενη βιβλιοθήκη lib2.so.

Re: Static-dynamic linking με ld

ΔημοσίευσηΔημοσιεύτηκε: 14 Ιαν 2013, 19:26
από alkismavridis
Ok!!
Σε ευχαριστώ πολύ!
Θα κάτσω να το διαβάσω τον οδηγό...
Όσο για την εντολή του ld είναι ακριβώς ό,τι χρειαζόμουν!! :thumbup: :thumbup: :thumbup:

Re: Static-dynamic linking με ld

ΔημοσίευσηΔημοσιεύτηκε: 14 Ιαν 2013, 19:35
από simosx
alkismavridis έγραψε:Ok!!
Σε ευχαριστώ πολύ!
Θα κάτσω να το διαβάσω τον οδηγό...
Όσο για την εντολή του ld είναι ακριβώς ό,τι χρειαζόμουν!! :thumbup: :thumbup: :thumbup:


Μόλις έχεις έτοιμες τις αλλαγές, γράψε εδώ. Έφτιαξα ένα αποθετήριο με τον υπάρχον κώδικα (Git) και θα ήθελα να το βάλω στο Ubuntu-gr στο github.