GNU/Linux >> Belajar Linux >  >> Linux

memuat peringatan:tidak dapat menemukan simbol entri _start

Gunakan label _start bukannya main untuk titik masuk ELF. main menyiratkan itu seperti C main fungsi, tetapi ini bahkan bukan fungsi (mis. Anda tidak dapat ret ).

Anda tidak mengatakannya, tetapi dari pesan kesalahan dan kode saya menganggap Anda sedang membuat kode 32bit Anda dengan nasm -felf32 hello32.asm && ld -melf_i386 -o hello32 hello32.o

(Jika Anda benar-benar membuat kode 64bit, Anda beruntung kode itu berhasil, tetapi akan rusak segera setelah Anda melakukan apa pun dengan esp bukannya rsp .)

Pesan kesalahan berasal dari ld , bukan dari nasm . Dikatakan begitu tepat di pesan. Komentar Tim benar:ld mencari _start simbol dalam file yang ditautkan, tetapi menyetel titik masuk ke awal segmen teks jika tidak menemukannya.

Tidak masalah simbol global/eksternal apa pun yang Anda tentukan. main tidak memiliki relevansi sama sekali di sini, dan dapat menunjuk ke mana saja yang Anda inginkan. Ini hanya berguna untuk keluaran pembongkaran dan hal-hal seperti itu. Kode Anda akan bekerja persis sama jika Anda mengeluarkan global main / main: baris, atau mengubahnya menjadi nama lain.

Memberi label sebagai main tidak bijaksana karena titik masuk ELF bukan fungsi . Ini tidak main() , dan tidak menerima argc dan argv argumen, dan tidak bisa ret karena ESP menunjuk ke argc bukannya alamat pengirim.

Hanya gunakan main jika Anda menautkan dengan kode startup CRT gcc / glibc yang mencari main simbol dan memanggilnya setelah menginisialisasi libc. (Jadi fungsi seperti printf berfungsi. Kait linker yang dinamis secara teknis biarkan libc menginisialisasi dirinya sendiri sebelum _start Anda jika Anda menautkannya, tetapi umumnya jangan lakukan itu kecuali Anda benar-benar mengerti apa yang Anda lakukan). Terkait:Merakit binari 32-bit pada sistem 64-bit (rangkaian alat GNU)

misalnya gcc -m32 -no-pie -o hello main.o jika Anda mendefinisikan main:
bukannya gcc -m32 -static -nostdlib -o hello start.o
(yang setara dengan ld kosong Anda ).

(Selama beberapa tahun terakhir, distro Linux telah mengonfigurasi GCC dengan -pie sebagai default, yang menginginkan kode yang tidak bergantung pada posisi. Tapi itu benar-benar merepotkan dalam mode 32-bit tanpa pengalamatan relatif RIP (lihat keluaran asm GCC misalnya), dan berarti ld tidak akan mengonversi call printf ke dalam call [email protected] untukmu. Jadi untuk sebagian besar asm tulisan tangan yang mengikuti sebagian besar tutorial, Anda menginginkan executable non-PIE tradisional sehingga tidak diperlukan relokasi teks.)


Saya menyarankan agar Anda menautkan file objek Anda (bagaimanapun itu diproduksi) dengan gcc , bukan ld .

gcc akan memanggil ld dengan opsi yang sesuai, karena ia mengetahui lebih banyak tentang kode sumber dan akan membuat apa pun yang diperlukan untuk asumsi bahwa ld membuat.


Linux
  1. Cara Memperbaiki kesalahan Konfigurasi:tidak dapat menemukan direktori makro 'm4' [Terpecahkan]

  2. Tidak dapat menemukan baseurl yang valid:Kesalahan YumRepo [Terpecahkan]

  3. kesalahan konfigurasi phpize:tidak dapat menemukan sumber (config.m4)

  1. Kesalahan Tidak dapat menemukan [Ekstensi PHP mysqlnd] OpenSSL

  2. Tidak dapat menemukan pspell – Perbaiki Kesalahan Konfigurasi PHP

  3. Tidak Dapat Menemukan -lm?

  1. Apache Tidak Dapat Dimulai Setelah Menginstal Ulang

  2. /usr/bin/ld:tidak dapat menemukan -lpython2.7

  3. Tidak dapat menemukan kesalahan perpustakaan libcrypto