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

...IDE, compilers, κλπ

Συντονιστής: konnn

Static-dynamic linking με ld

Δημοσίευσηαπό alkismavridis » 13 Ιαν 2013, 15:41

Καλησπέρα σας!
Επειδή οι γνώσεις μου πάνω σε θέματα 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??

Ευχαριστώ πολύ!
Γνώσεις ⇛ Linux: Μέτριο┃ Προγραμματισμός: Java, Assembly, Fortran, μαθαίνω C/X11┃ Αγγλικά: Μέτρια
Λειτουργικό σε Η/Υ ϰ μοντέλο: Ubuntu 14.04 64-bit ┃ Τρόπος εγκατάστασης: Live USB
Προδιαγραφές ⇛ Desktop: Intel i5 2320 3.00GHz.┃ MotherBoard: Asus p8h61 -m pro
Προδιαγραφές ⇛ RAM: 4GB ┃ Τροφοδοτικό Corsair CX430

GPU: Intel 2nd Generation Core Processor Family Integrated Graphics Controller [8086:0102] {i915}
5 eth0: Realtek RTL8111/8168B PCI Express Gigabit Ethernet controller [10ec:8168] (rev 06) ⋮ wlan0: 0b05:1723 ASUS WL-167G v2 802.11g Adapter [Ralink RT2571W]
Οθόνη Schaub Lorenz (Tv)
alkismavridis
punkTUX
punkTUX
 
Δημοσιεύσεις: 273
Εγγραφή: 18 Μαρ 2009, 18:46
Εκτύπωση

Re: Static-dynamic linking με ld

Δημοσίευσηαπό simosx » 13 Ιαν 2013, 19:14

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
προσωπικό ιστολόγιο ϗ πλανήτης Ubuntu-gr
Συμβάλετε και εσείς στο ελληνικό βιβλίο Ubuntu!
1 Γνώσεις Linux: Πολύ καλό ┃ Προγραμματισμού: Πολύ καλό ┃ Αγγλικών: Πολύ καλό
2 Ubuntu 13.10 saucy 3.11.0-031100rc1-generic 64bit (el_GR.UTF-8, Unity ubuntu)
3 AMD E-450 APU with Radeon HD Graphics ‖ RAM 3555 MiB ‖ Sony Corporation VAIO
4 AMD nee ATI Wrestler [Radeon HD 6320] [1002:9806] {fglrx_pci}
5 eth0: Atheros Inc. AR8151 v2.0 Gigabit Ethernet [1969:1083] (rev c0) ⋮ wlan0: Atheros Inc. AR9285 [168c:002b] (rev 01)
Φτιάξτε και εσείς τη δική σας υπογραφή (παραπάνω κείμενο) αυτόματα με κλικ εδώ!
simosx
Επίτιμο μέλος
Επίτιμο μέλος
 
Δημοσιεύσεις: 10334
Εγγραφή: 11 Μάιος 2008, 18:52
Launchpad: simosx
IRC: simosx
Εκτύπωση

Re: Static-dynamic linking με ld

Δημοσίευσηαπό alkismavridis » 13 Ιαν 2013, 21:05

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

Έδωσα την εντολή που μου είπες, και απο ότι βλέπω ο gcc καλεί το ld, προσπαθώντας να συνδέσει με κάτι άλλα περίεργα όπως crt1.o... Γιατί αυτό;
Το αποτέλεσμα είναι κάτι error για πολλαπλες "_start", γιατί στο αρχείο crt1.o υπάρχουν και άλλες εκτώς από τη δική μου..
Δε γίνεται η δουλειά χωρίς να μπέξω με τον gcc; Απ ευθείας με το ld;
Γνώσεις ⇛ Linux: Μέτριο┃ Προγραμματισμός: Java, Assembly, Fortran, μαθαίνω C/X11┃ Αγγλικά: Μέτρια
Λειτουργικό σε Η/Υ ϰ μοντέλο: Ubuntu 14.04 64-bit ┃ Τρόπος εγκατάστασης: Live USB
Προδιαγραφές ⇛ Desktop: Intel i5 2320 3.00GHz.┃ MotherBoard: Asus p8h61 -m pro
Προδιαγραφές ⇛ RAM: 4GB ┃ Τροφοδοτικό Corsair CX430

GPU: Intel 2nd Generation Core Processor Family Integrated Graphics Controller [8086:0102] {i915}
5 eth0: Realtek RTL8111/8168B PCI Express Gigabit Ethernet controller [10ec:8168] (rev 06) ⋮ wlan0: 0b05:1723 ASUS WL-167G v2 802.11g Adapter [Ralink RT2571W]
Οθόνη Schaub Lorenz (Tv)
alkismavridis
punkTUX
punkTUX
 
Δημοσιεύσεις: 273
Εγγραφή: 18 Μαρ 2009, 18:46
Εκτύπωση

Re: Static-dynamic linking με ld

Δημοσίευσηαπό simosx » 13 Ιαν 2013, 21:27

Έχω γράψει οδηγό στο φόρουμ μας για τη μεταγλώττιση μέσω nasm, όπου αναφέρω κάποια πράγματα.
Για να κάνουμε το όλο έργο πιο πρακτικό, μπορείς να δώσεις τέτοια μικρά αρχεία, με lib1.nasm που θα είναι στατικό, lib2.nasm που θα είναι δυναμικό και θα γίνει βιβλιοθήκη, και ένα main.nasm.
Οπότε από εκεί θα προσπαθήσουμε να φτιάξουμε τη δυναμική βιβλιοθήκη και να παραχθεί το τελικό εκτελέσιμο.
προσωπικό ιστολόγιο ϗ πλανήτης Ubuntu-gr
Συμβάλετε και εσείς στο ελληνικό βιβλίο Ubuntu!
1 Γνώσεις Linux: Πολύ καλό ┃ Προγραμματισμού: Πολύ καλό ┃ Αγγλικών: Πολύ καλό
2 Ubuntu 13.10 saucy 3.11.0-031100rc1-generic 64bit (el_GR.UTF-8, Unity ubuntu)
3 AMD E-450 APU with Radeon HD Graphics ‖ RAM 3555 MiB ‖ Sony Corporation VAIO
4 AMD nee ATI Wrestler [Radeon HD 6320] [1002:9806] {fglrx_pci}
5 eth0: Atheros Inc. AR8151 v2.0 Gigabit Ethernet [1969:1083] (rev c0) ⋮ wlan0: Atheros Inc. AR9285 [168c:002b] (rev 01)
Φτιάξτε και εσείς τη δική σας υπογραφή (παραπάνω κείμενο) αυτόματα με κλικ εδώ!
simosx
Επίτιμο μέλος
Επίτιμο μέλος
 
Δημοσιεύσεις: 10334
Εγγραφή: 11 Μάιος 2008, 18:52
Launchpad: simosx
IRC: simosx
Εκτύπωση

Re: Static-dynamic linking με ld

Δημοσίευσηαπό alkismavridis » 13 Ιαν 2013, 21:56

****επεξεργασία****** αν μπείτε στην διαδικασία να δείτε τι κάνουν οι 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 που έχει δημιουργηθεί, το πράγμα δουλεύει ακόμα...
Γνώσεις ⇛ Linux: Μέτριο┃ Προγραμματισμός: Java, Assembly, Fortran, μαθαίνω C/X11┃ Αγγλικά: Μέτρια
Λειτουργικό σε Η/Υ ϰ μοντέλο: Ubuntu 14.04 64-bit ┃ Τρόπος εγκατάστασης: Live USB
Προδιαγραφές ⇛ Desktop: Intel i5 2320 3.00GHz.┃ MotherBoard: Asus p8h61 -m pro
Προδιαγραφές ⇛ RAM: 4GB ┃ Τροφοδοτικό Corsair CX430

GPU: Intel 2nd Generation Core Processor Family Integrated Graphics Controller [8086:0102] {i915}
5 eth0: Realtek RTL8111/8168B PCI Express Gigabit Ethernet controller [10ec:8168] (rev 06) ⋮ wlan0: 0b05:1723 ASUS WL-167G v2 802.11g Adapter [Ralink RT2571W]
Οθόνη Schaub Lorenz (Tv)
alkismavridis
punkTUX
punkTUX
 
Δημοσιεύσεις: 273
Εγγραφή: 18 Μαρ 2009, 18:46
Εκτύπωση

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

Δημοσίευσηαπό simosx » 13 Ιαν 2013, 23:12

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.
προσωπικό ιστολόγιο ϗ πλανήτης Ubuntu-gr
Συμβάλετε και εσείς στο ελληνικό βιβλίο Ubuntu!
1 Γνώσεις Linux: Πολύ καλό ┃ Προγραμματισμού: Πολύ καλό ┃ Αγγλικών: Πολύ καλό
2 Ubuntu 13.10 saucy 3.11.0-031100rc1-generic 64bit (el_GR.UTF-8, Unity ubuntu)
3 AMD E-450 APU with Radeon HD Graphics ‖ RAM 3555 MiB ‖ Sony Corporation VAIO
4 AMD nee ATI Wrestler [Radeon HD 6320] [1002:9806] {fglrx_pci}
5 eth0: Atheros Inc. AR8151 v2.0 Gigabit Ethernet [1969:1083] (rev c0) ⋮ wlan0: Atheros Inc. AR9285 [168c:002b] (rev 01)
Φτιάξτε και εσείς τη δική σας υπογραφή (παραπάνω κείμενο) αυτόματα με κλικ εδώ!
simosx
Επίτιμο μέλος
Επίτιμο μέλος
 
Δημοσιεύσεις: 10334
Εγγραφή: 11 Μάιος 2008, 18:52
Launchpad: simosx
IRC: simosx
Εκτύπωση

Re: Static-dynamic linking με ld

Δημοσίευσηαπό alkismavridis » 14 Ιαν 2013, 19:26

Ok!!
Σε ευχαριστώ πολύ!
Θα κάτσω να το διαβάσω τον οδηγό...
Όσο για την εντολή του ld είναι ακριβώς ό,τι χρειαζόμουν!! :thumbup: :thumbup: :thumbup:
Γνώσεις ⇛ Linux: Μέτριο┃ Προγραμματισμός: Java, Assembly, Fortran, μαθαίνω C/X11┃ Αγγλικά: Μέτρια
Λειτουργικό σε Η/Υ ϰ μοντέλο: Ubuntu 14.04 64-bit ┃ Τρόπος εγκατάστασης: Live USB
Προδιαγραφές ⇛ Desktop: Intel i5 2320 3.00GHz.┃ MotherBoard: Asus p8h61 -m pro
Προδιαγραφές ⇛ RAM: 4GB ┃ Τροφοδοτικό Corsair CX430

GPU: Intel 2nd Generation Core Processor Family Integrated Graphics Controller [8086:0102] {i915}
5 eth0: Realtek RTL8111/8168B PCI Express Gigabit Ethernet controller [10ec:8168] (rev 06) ⋮ wlan0: 0b05:1723 ASUS WL-167G v2 802.11g Adapter [Ralink RT2571W]
Οθόνη Schaub Lorenz (Tv)
alkismavridis
punkTUX
punkTUX
 
Δημοσιεύσεις: 273
Εγγραφή: 18 Μαρ 2009, 18:46
Εκτύπωση

Re: Static-dynamic linking με ld

Δημοσίευσηαπό simosx » 14 Ιαν 2013, 19:35

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


Μόλις έχεις έτοιμες τις αλλαγές, γράψε εδώ. Έφτιαξα ένα αποθετήριο με τον υπάρχον κώδικα (Git) και θα ήθελα να το βάλω στο Ubuntu-gr στο github.
προσωπικό ιστολόγιο ϗ πλανήτης Ubuntu-gr
Συμβάλετε και εσείς στο ελληνικό βιβλίο Ubuntu!
1 Γνώσεις Linux: Πολύ καλό ┃ Προγραμματισμού: Πολύ καλό ┃ Αγγλικών: Πολύ καλό
2 Ubuntu 13.10 saucy 3.11.0-031100rc1-generic 64bit (el_GR.UTF-8, Unity ubuntu)
3 AMD E-450 APU with Radeon HD Graphics ‖ RAM 3555 MiB ‖ Sony Corporation VAIO
4 AMD nee ATI Wrestler [Radeon HD 6320] [1002:9806] {fglrx_pci}
5 eth0: Atheros Inc. AR8151 v2.0 Gigabit Ethernet [1969:1083] (rev c0) ⋮ wlan0: Atheros Inc. AR9285 [168c:002b] (rev 01)
Φτιάξτε και εσείς τη δική σας υπογραφή (παραπάνω κείμενο) αυτόματα με κλικ εδώ!
simosx
Επίτιμο μέλος
Επίτιμο μέλος
 
Δημοσιεύσεις: 10334
Εγγραφή: 11 Μάιος 2008, 18:52
Launchpad: simosx
IRC: simosx
Εκτύπωση


Επιστροφή στο Εφαρμογές για Ανάπτυξη Λογισμικού

cron