Apa yang dimaksud dengan -fPIC saat membuat perpustakaan bersama?

109

Saya tahu opsi ' -fPIC' ada hubungannya dengan menyelesaikan alamat dan independensi antara modul individu, tapi saya tidak yakin apa artinya sebenarnya. Bisakah Anda menjelaskan?

ks1322
sumber
1
Juga jika Anda ingin tahu lebih detail, ada artikel bagus di sini ( akkadia.org/drepper/dsohowto.pdf )
MJ

Jawaban:

61

PIC adalah singkatan dari Position Independent Code

dan mengutip man gcc:

Jika didukung untuk mesin target, keluarkan kode yang tidak bergantung pada posisi, cocok untuk penautan dinamis dan hindari batasan apa pun pada ukuran tabel offset global. Pilihan ini membuat perbedaan pada m68k, PowerPC dan SPARC. Kode yang tidak bergantung posisi memerlukan dukungan khusus, dan oleh karena itu hanya berfungsi pada mesin tertentu.

gunakan ini saat membuat objek bersama (* .so) pada arsitektur yang disebutkan.

sean riley
sumber
1
f tidak berarti apa-apa, itu hanya bagian dari nama opsi.
Zifre
17
Ada perbedaan antara fpic dan fPIC. Keduanya melakukan hal yang sama tetapi fpic menggunakan offset relatif yang lebih pendek jika tersedia. Jadi kompilasi dengan fpic berpotensi menghasilkan file yang lebih kecil. Sayangnya itu tidak selalu berfungsi seperti yang diharapkan, jadi gunakan fPIC. Perhatikan juga tidak semua prosesor mendukung offset yang lebih pendek sehingga mungkin tidak membuat perbedaan.
Martin York
2
'F' adalah mabuk dari cara gcc menangani argumen baris perintah (ini terjadi beberapa tahun yang lalu dan mereka telah mengubah bagian kode ini yang belum saya lihat baru-baru ini). Tetapi pada saat itu hanya huruf atau kombinasi tertentu yang diperbolehkan dalam kondisi yang berbeda (terdapat bahasa yang sangat kompleks untuk mendefinisikan argumen baris perintah) sebagai akibatnya 'f' digunakan untuk membuatnya mudah untuk didefinisikan sebagai argumen baris perintah.
Martin York
2
Apa yang akan terjadi jika seseorang membangun * .so tanpa fPIC?
Isa A
2
@IsaA Saya sedang mengompilasi fungsi c-api mysql dari sumber hari ini dan tidak bisa dibangun, saya mengerti /usr/bin/ld: /tmp/cc7hXILq.o: relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPICjadi saya menambahkan fPIC dan itu dibangun.
cabaiNUT
32

Ini fadalah awalan gcc untuk opsi yang "mengontrol konvensi antarmuka yang digunakan dalam pembuatan kode"

The PICsingkatan "Kode Posisi Independen", itu adalah spesialisasi dari fpicuntuk m68k dan SPARC.

Edit: Setelah membaca halaman 11 dari dokumen yang direferensikan oleh 0x6adb015 , dan komentar oleh coryan, saya membuat beberapa perubahan:

Opsi ini hanya masuk akal untuk pustaka bersama dan Anda memberi tahu OS bahwa Anda menggunakan Tabel Offset Global, GOT. Ini berarti semua referensi alamat Anda relatif terhadap GOT, dan kode dapat dibagikan melalui banyak proses.

Jika tidak, tanpa opsi ini, pemuat harus mengubah semua offset itu sendiri.

Tak perlu dikatakan, kami hampir selalu menggunakan -fpic / PIC.

Mark Beckwith
sumber
1
Saya pikir OS itu gratis untuk memuat perpustakaan di alamat virtual apa pun, tetapi tanpa pic / PIC, pemuat harus memodifikasi kode dan menyesuaikan semua lompatan absolut + arah ke lokasi sebenarnya dari rutinitas / perpustakaan. Dengan pic / PIC kode tidak diubah dan oleh karena itu benar-benar dibagikan ke beberapa proses.
coryan
Beberapa proses sebagian besar kebetulan - intinya adalah bahwa kode dapat dimuat di alamat virtual mana pun dengan perbaikan alamat minimum absolut.
Jonathan Leffler
16

man gcc mengatakan:

-fpic
  Hasilkan kode posisi-independen (PIC) yang cocok untuk digunakan dalam berbagi
  perpustakaan, jika didukung untuk mesin target. Kode tersebut mengakses semua
  alamat konstan melalui tabel offset global (GOT). Dinamika
  loader menyelesaikan entri GOT ketika program dimulai (dinamis
  loader bukan bagian dari GCC; itu adalah bagian dari sistem operasi). Jika
  ukuran GOT untuk executable yang ditautkan melebihi spesifik mesin
  ukuran maksimum, Anda mendapatkan pesan kesalahan dari linker yang menunjukkan
  bahwa -fpic tidak berfungsi; dalam hal ini, kompilasi ulang dengan -fPIC sebagai gantinya.
  (Maksimum ini adalah 8k pada SPARC dan 32k pada m68k dan RS / 6000.
  386 tidak memiliki batasan seperti itu.)

  Kode posisi-independen memerlukan dukungan khusus, dan karenanya
  bekerja hanya pada mesin tertentu. Untuk 386, GCC mendukung PIC untuk
  Sistem V tetapi tidak untuk Sun 386i. Kode dibuat untuk
  IBM RS / 6000 selalu tidak bergantung pada posisi.

-fPIC
  Jika didukung untuk mesin target, keluarkan kode posisi-independen,
  cocok untuk tautan dinamis dan menghindari batasan ukuran
  tabel offset global. Opsi ini membuat perbedaan pada m68k tersebut
  dan SPARC.

  Kode posisi-independen memerlukan dukungan khusus, dan karenanya
  bekerja hanya pada mesin tertentu.
Nikolai Fetissov
sumber