Thread overview
baglayici yazmak
Apr 29, 2010
Mengu
Apr 30, 2010
KUTALMIS
Apr 30, 2010
KUTALMIS
April 30, 2010

merhabalar.

bir c++ kutuphanesine d icin baglayici yazmak istiyorum ama acikcasi nereden baslayacagim ve nasil yapacagim konusunda hicbir fikrim yok. yardimci olursaniz ellerinizden operim. :)

kolay gelsin.

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

April 30, 2010

Öncelikle, derlenmiş bir kod, bağlandığında ne değişir buna bakmak lazım.
Çalişabilen dosya disk üzerinde bazı section denilen bölümlerden oluşuyor. Örnek, .text genelde kod kısmı, .data data kısmı, .bss ilk değer verilmemiş statik nesneler, .stack stack filan.

İşte bir derlenmiş dosyada, içindeki kod veya verilerin kodun bağlanması esnasında nereye yazılacağı bellidir. .text den sonra gelenler, kod, .data dan sonra gelenler data bölümüne yazılmalıdır.

Senin yapman gereken de şu, öncelikle bir dosya da section sayısı kadar yer ayıracaksın. sonra bu yerlere, derlenmiş modüllerde bulunan dataları yazacaksın. Bu dataların adresleri elinde olmalı, örneğin derlenmiş modülde _main, _degisken, _asdf gibi bulunan tüm etiketler, bağlama aşamasında adrese çevirilecek. Tabi ki disk üzerinde adrese değil, belleğe genişletildikten sonraki adrese.

Bu noktada çalışabilen dosyanın başlık kısmını iyi bilmen gerekiyor. Burada örneğin .text bölümünün disk üzerinde nerden başlayıp nereye kadar olduğu ve belleğe yüklendiğinde hangi adreesten başlayıp ne kadar uzun olduğu yazıyor.

Özetle senin yapman gereken, tüm derlenmiş modüllerde data bölümündekileri, tek bir dosyada data bölümüne, kod bölümündekileri kod bölümüne, bss bölümündekileri bss bölümüne yazmak ve, etiket isimleri olarak görünen yerlere gerçek adresleri yazmak.
Tabi o datanın dosya içindeki yerinden bahsetmiyorum, belleğe yüklendikten sonraki adresinden bahsediyorum, bu adresi de demin söylediğim gibi başlık kısmı sayesinde öğrenebilirsin.

İşin belki de en zor kısmı şu, dinamik kütüphane fonksiyonlarına bağlanmak. Bu fonksiyonların adresi bağlama sırasında bilinmediğinden, bunun yerine örneğin .text tablosunun sonunda bir jmp table yaratılır, dinamik kütüphane içindeki fonksiyonun adresi yerine, bu jmp tabledeki bir elemanın adresi yazılır. Tabi ki belleğe yüklenirken bu jmp table de gerçek fonksiyon adresleri vardır. (biz aslında import tablosundan çekiyoruz atlayacağımız adresi, loader ise import tablosuna gerçek fonksiyon adreslerini yazdığından biz herhangi bir fonksiyona bu jmp table ile atlayabiliyoruz)
Örnek bir jmp table.
http://img530.imageshack.us/img530/6958/jmp.png

Fonksiyonların gerçek adresleri o sisteme özgü bir yöntemle alınır. Örneğin windows da

#include <stdio.h>
#include <windows.h>


int main(){

	printf("\n%X",GetProcAddress(LoadLibrary("user32.dll"),"MessageBoxA"));

	getchar();
	return 0;
}

Bu kod ile tüm fonksiyonların adresini alabilirsiniz. Dahası, doğrudan adresi ile bu fonksiyonları çağıra da bilirsiniz, hiç jmp table yada import table olmadan, trojan yazarken çok işe yarar :) Tabi bu loaderin işi, fazla karışmayalım.

Özetle

  • verilen derlenmiş modülerde, kod bölümündeki baytları, son dosyada kod bölümüne, data dakileri dataya vs. verilen sırada yaz.
  • başlık kısmını ayarla ve hangi bölümün bellekte hangi adresten başlayıp kaç bayt uzunluğunda olduğunu belirle.
  • bundan sonra, fonksiyon ve global nesne etiketleri yerine bu adresleri yerleştir.
  • dinamik bağlanacak fonksiyonların isimlerini dosya da ayrı bir yere yaz (import table) bu yerin de adresini başlık kısmına yaz.
  • kod kısmının sonunda, bir jmp tablosu oluştur ve her dinamik bağlantı için bir jmp olsun. Bu jmp lar import tablosundaki belli bir yerdeki adrese atlayacak ör: jmp [ds:1958] gibi, sonra bu ds:1958 kısmına tabiki işletim sistemi loaderi gerçek adresi yazacaktır.

Son olarak bir not. Daha önce ceviz de de bir kaç kez söylemiştim, çalışabilen dosya , aslında direkt main fonksiyonundan başlamaz. Derleyici kodundan başlar, ve derleyici kodunda sonlanır.
Peki bu kod nerden geliyor, nasıl bağlanıp bizim programımızın gerçek başlangıç noktası oluyor.

İşte bu derleyici kodu, genelde cr0.o , cr2.o ya da .obj gibi, derlenmiş ama bağlanmamış modüllerdir. Siz isteseniz de istemesenizde yazdığınız her porgramda, bağlayıcı aynı zamanda bu derlenmiş modülleri de sizin kodunuzla birlikte bağlar.
Tabi ld de başka bir fonksiyonu -e asd şeklinde giriş noktası belirleyebiliriz, kod içinde main fonksiyonu yoksa sorun olmaz, program gerçekten asd fonksiyonundan başlar, derleyici kodu eklenmez.

Özetle bunların hepsini düşünmek zorundasın ancak derleyiciden 10.000 kat daha kolay bir program olduğunu rahatlıkla söyleyebilirim.

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

April 30, 2010

Kutalmış bey merak ettimde sizin anlattığınız şey ingilizce olarak binding olarak mı geçiyor yoksa linker mi ?
Ben sizin anlattığınız konunun Linker olduğunu sanırıyorum. Ama Mengü Beyin istediği şey Binding. Yani C++ kodunu D'ye çevirme.

Ama siz Binding nedir onu anlatıyorsanız ve ben anlayamadıysam kusuruma bakmayın. Benim düzeyim sizinki ile eş değil.

Bu arada bu yanlış anlaşılma sanırım benim binding için önerdiğim iliştirici sözcüğü sevilmemesi ve parantez içinde binding yazılmaması.

(Bu arada bende mengünün mesajını ilk okuduğumda linker nasıl yazılır diye sorduğunu sanmıştım daha sonra binding nasıl yazılır diye sorduğunu anladım. O yüzden belki KUTALMIS beyde aynı hataya düşmüştür diye sorma gereği duydum.)

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

April 30, 2010

Alıntı:

>

Bu terim konusunda böyle yanlış anlamalar bekliyorduk zaten... :)

Bende bekliyordum zaten. Bu yüzden iliştirici sözcüğünü kullanalım dedim :-) (Banane ben haklıyım :-P )

Ama ben bunun yanlış anlaşılmasına ve linker hakkında yazı yazılmasına sevindim. Ama şunu merak ediyorum. Bir derleyicinin yaptığı şeylerin aşamalarını öğrenebileceğim iyi bir Türkçe kaynak var mı ? Ali Bey ile KUTALMIS bey arasında geçen konuşmalarda benimde arkaplanda neler olduğunu öğrenmem gerektiğini düşündüm.

Bu arada Mengü Bey bence ingilizce forumda da bu sorunuz hakkında bir konu açmanız iyi olur bence. Çünkü burdaki çoğunluk yazılmış bağlayıcıları(binding, iliştirici) kullanmayı bekliyor. O yüzden pek bir bilgimiz yok sanırsam ?

Konuya dönersem digitalmars.com'da bu bağlayıcı ile ilgili tek belge bu :http://www.digitalmars.com/d/2.0/htod.html

Ayrıca hatırladığım kadarı ile C++ ile d için bağlayıcı yazmak C ile D için bağlayıcı yazmaktan daha zor olduğunu biliyorum.

(Bu arada içimdeki bir ses Ali Bey bcd'deki curses projesini şuanki güncel dmd ile çalıştırılabilir hale kolaylıkla getirebilir ve bize de nasıl kullancağımızı gösterebilir diyor. Benim içimdeki sesler genelde doğru söyler ama içimdeki sesi duyuyor musunuz ? :-) )

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

April 30, 2010

Geçen konuda bağlayıcı derleyici problemi olmuştu, burda da başlığı görünce direkt atladım :) yine de bilgi bilgidir, belki başka bir arkadaşta bu yazıyı görünce linker yazmaya karar verir :D

Alıntı (canalpay):

>

Ama ben bunun yanlış anlaşılmasına ve linker hakkında yazı yazılmasına sevindim. Ama şunu merak ediyorum. Bir derleyicinin yaptığı şeylerin aşamalarını öğrenebileceğim iyi bir Türkçe kaynak var mı ? Ali Bey ile KUTALMIS bey arasında geçen konuşmalarda benimde arkaplanda neler olduğunu öğrenmem gerektiğini düşündüm.

Ben bu konu hakkında da kaan hoca yoluyla bilgi sahibi olduğumdan, onun yazdığı makaleleri örnek göstereyim. Ayrıca yine dernek bünyesinde geliştirilen bir derleyici projesi var, bittiğinde kaynak koduyla birlikte dökümanları da yayınlanacaktır.

ÇEVİRİCİ PROGRAMLAR, DERLEYİCİLER VE YORUMLAYICILAR
http://www.kaanaslan.com/resource/article/display_article.php?page=2&id=50

DERLEYİCİLERİN KOD OPTİMİZASYONLARI
http://www.kaanaslan.com/resource/article/display_article.php?page=1&id=62
http://www.kaanaslan.com/resource/article/display_article.php?page=1&id=71
http://www.kaanaslan.com/resource/article/display_article.php?page=1&id=75

MICROSOFT C/C++ DERLEYİCİLERİNDE FONKSİYON ÇAĞIRMA BİÇİMLERİ (CALLING CONVENTIONS)
http://www.kaanaslan.com/resource/article/display_article.php?page=2&id=49

Ayrıca mdk dan bir arkadaşın kişisel sitesinde oldukça güzel yazılar olduğunu hatırlıyorum ama format atarken yer imlerini yedeklemeyi unuttuğumdan gitti. Yine de bir bakayım bulursam koyarım buraya.

(buldum ama daha fazla yazı vardı diye hatırlıyorum. http://www.diyezon.com/category/derleyici-tasarimi )

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

April 30, 2010

Bu terim konusunda böyle yanlış anlamalar bekliyorduk zaten... :) KUTALMIS, tabii ki yine de çok teşekkürler!

Mengü, bu konuda elimizde araç olarak BCD var:

http://dsource.org/projects/bcd

Onu kurcalayarak C başlıklarının D iliştiricilerine nasır dönüştürüldüklerini görebilirsin.

Elle de yapılabilir. Benim de daha önceden bir denemem olmuştu:

http://ddili.org/forum/post/220

Oradaki küçücük iliştiriciyi teker teker oluşturmuştum. D programını yazmış ve derlemeye çalışmıştım. Örneğin initscr() çağrısına derleyici hatası alınca C başlığını açmış ve onun eşdeğerini benim_ncurses.d'ye yazmıştım.

Orada WINDOW* gibi bir tür kullanılıyor. Büyük olasılıkla "opaque" bir tür olduğu için void*'in eşdeğeridir diye alias void WINDOW; denemiştim ve çalışmıştı.

Dosyanın en başında extern (C): demek de gerekiyor.

GtkD'nin iliştiricilerine de bakabilirsin. C başlığından D'ye nasıl dönüştürdüklerine...

Bundan başka ben de bilmiyorum... :/

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

April 30, 2010

Alıntı (canalpay):

>

Bir derleyicinin yaptığı şeylerin aşamalarını öğrenebileceğim iyi bir Türkçe kaynak var mı ?

KUTALMIS'ta kesin vardır. :)

Alıntı:

>

Konuya dönersem digitalmars.com'da bu bağlayıcı ile ilgili tek belge bu :http://www.digitalmars.com/d/2.0/htod.html

Linux'ta çalışmıyormuş... :(

Alıntı:

>

(Bu arada içimdeki bir ses Ali Bey bcd'deki curses projesini şuanki güncel dmd ile çalıştırılabilir hale kolaylıkla getirebilir

Zamanım olunca bakarım... :/

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]