日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

linux 运行elf64,Elf64 格式

發布時間:2023/12/14 linux 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux 运行elf64,Elf64 格式 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

ELF文件格式

ELF (Executable and Linkable Format)是一種為可執行文件,目標文件,共享鏈接庫和內核轉儲(core dumps)準備的標準文件格式。 Linux和很多類Unix操作系統都使用這個格式。 讓我們來看一下64位ELF文件格式的結構以及內核源碼中有關于它的一些定義。

一個ELF文件由以下三部分組成:

ELF頭(ELF header) - 描述文件的主要特性:類型,CPU架構,入口地址,現有部分的大小和偏移等等;

程序頭表(Program header table) - 列舉了所有有效的段(segments)和他們的屬性。 程序頭表需要加載器將文件中的節加載到虛擬內存段中;

節頭表(Section header table) - 包含對節(sections)的描述。

現在讓我們對這些部分有一些更深的了解。

ELF頭(ELF header)

ELF頭(ELF header)位于文件的開始位置。 它的主要目的是定位文件的其他部分。 文件頭主要包含以下字段:

ELF文件鑒定 - 一個字節數組用來確認文件是否是一個ELF文件,并且提供普通文件特征的信息;

文件類型 - 確定文件類型。 這個字段描述文件是一個重定位文件,或可執行文件,或...;

目標結構;

ELF文件格式的版本;

程序入口地址;

程序頭表的文件偏移;

節頭表的文件偏移;

ELF頭(ELF header)的大小;

程序頭表的表項大小;

其他字段...

你可以在內核源碼種找到表示ELF64 header的結構體 elf64_hdr:

typedef struct elf64_hdr {

unsigned chare_ident[EI_NIDENT];

Elf64_Half e_type;

Elf64_Half e_machine;

Elf64_Word e_version;

Elf64_Addr e_entry;

Elf64_Off e_phoff;

Elf64_Off e_shoff;

Elf64_Word e_flags;

Elf64_Half e_ehsize;

Elf64_Half e_phentsize;

Elf64_Half e_phnum;

Elf64_Half e_shentsize;

Elf64_Half e_shnum;

Elf64_Half e_shstrndx;

} Elf64_Ehdr;

這個結構體定義在 elf.h

節(sections)

所有的數據都存儲在ELF文件的節(sections)中。 我們通過節頭表中的索引(index)來確認節(sections)。 節頭表表項包含以下字段:

節的名字;

節的類型;

節的屬性;

內存地址;

文件中的偏移;

節的大小;

到其他節的鏈接;

各種各樣的信息;

地址對齊;

這個表項的大小,如果有的話;

而且,在linux內核中結構體 elf64_shdr 如下所示:

typedef struct elf64_shdr {

Elf64_Word sh_name;

Elf64_Word sh_type;

Elf64_Xword sh_flags;

Elf64_Addr sh_addr;

Elf64_Off sh_offset;

Elf64_Xword sh_size;

Elf64_Word sh_link;

Elf64_Word sh_info;

Elf64_Xword sh_addralign;

Elf64_Xword sh_entsize;

} Elf64_Shdr;

程序頭表(Program header table)

在可執行文件或者共享鏈接庫中所有的節(sections)都被分為多個段(segments)。 程序頭是一個結構的數組,每一個結構都表示一個段(segments)。 它的結構就像這樣:

typedef struct elf64_phdr {

Elf64_Word p_type;

Elf64_Word p_flags;

Elf64_Off p_offset;

Elf64_Addr p_vaddr;

Elf64_Addr p_paddr;

Elf64_Xword p_filesz;

Elf64_Xword p_memsz;

Elf64_Xword p_align;

} Elf64_Phdr;

在內核源碼中。

elf64_phdr 定義在相同的 elf.h 文件中.

EFL文件也包含其他的字段或結構。 你可以在 Documentation 中查看。 現在我們來查看一下 vmlinux 這個ELF文件。

vmlinux

vmlinux 也是一個可重定位的ELF文件。 我們可以使用 readelf 工具來查看它。 首先,讓我們看一下它的頭部:

$ readelf -h vmlinux

ELF Header:

Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00

Class: ELF64

Data: 2's complement, little endian

Version: 1 (current)

OS/ABI: UNIX - System V

ABI Version: 0

Type: EXEC (Executable file)

Machine: Advanced Micro Devices X86-64

Version: 0x1

Entry point address: 0x1000000

Start of program headers: 64 (bytes into file)

Start of section headers: 381608416 (bytes into file)

Flags: 0x0

Size of this header: 64 (bytes)

Size of program headers: 56 (bytes)

Number of program headers: 5

Size of section headers: 64 (bytes)

Number of section headers: 73

Section header string table index: 70

我們可以看出 vmlinux 是一個64位可執行文件。 我們可以從 Documentation/x86/x86_64/mm.txt 讀到相關信息:

ffffffff80000000 - ffffffffa0000000 (=512 MB) kernel text mapping, from phys 0

之后我們可以在 vmlinux ELF文件中查看這個地址:

$ readelf -s vmlinux | grep ffffffff81000000

1: ffffffff81000000 0 SECTION LOCAL DEFAULT 1

65099: ffffffff81000000 0 NOTYPE GLOBAL DEFAULT 1 _text

90766: ffffffff81000000 0 NOTYPE GLOBAL DEFAULT 1 startup_64

值得注意的是,startup_64 例程的地址不是 ffffffff80000000, 而是 ffffffff81000000。 現在我們來解釋一下。

. = __START_KERNEL;

...

...

..

/* Text and read-only data */

.text : AT(ADDR(.text) - LOAD_OFFSET) {

_text = .;

...

...

...

}

其中,__START_KERNEL 定義如下:

#define __START_KERNEL(__START_KERNEL_map + __PHYSICAL_START)

從這個文檔中看出,__START_KERNEL_map 的值是 ffffffff80000000 以及 __PHYSICAL_START 的值是 0x1000000。 這就是 startup_64的地址是 ffffffff81000000的原因了。

最后我們通過以下命令來得到程序頭表的內容:

readelf -l vmlinux

Elf file type is EXEC (Executable file)

Entry point 0x1000000

There are 5 program headers, starting at offset 64

Program Headers:

Type Offset VirtAddr PhysAddr

FileSiz MemSiz Flags Align

LOAD 0x0000000000200000 0xffffffff81000000 0x0000000001000000

0x0000000000cfd000 0x0000000000cfd000 R E 200000

LOAD 0x0000000001000000 0xffffffff81e00000 0x0000000001e00000

0x0000000000100000 0x0000000000100000 RW 200000

LOAD 0x0000000001200000 0x0000000000000000 0x0000000001f00000

0x0000000000014d98 0x0000000000014d98 RW 200000

LOAD 0x0000000001315000 0xffffffff81f15000 0x0000000001f15000

0x000000000011d000 0x0000000000279000 RWE 200000

NOTE 0x0000000000b17284 0xffffffff81917284 0x0000000001917284

0x0000000000000024 0x0000000000000024 4

Section to Segment mapping:

Segment Sections...

00 .text .notes __ex_table .rodata __bug_table .pci_fixup .builtin_fw

.tracedata __ksymtab __ksymtab_gpl __kcrctab __kcrctab_gpl

__ksymtab_strings __param __modver

01 .data .vvar

02 .data..percpu

03 .init.text .init.data .x86_cpu_dev.init .altinstructions

.altinstr_replacement .iommu_table .apicdrivers .exit.text

.smp_locks .data_nosave .bss .brk

這里我們可以看出五個包含節(sections)列表的段(segments)。 你可以在生成的鏈接器腳本 - arch/x86/kernel/vmlinux.lds 中找到所有的節(sections)。

就這樣吧。 當然,它不是ELF(Executable and Linkable Format)的完整描述,但是如果你想要知道更多,可以參考這個文檔 - 這里

總結

以上是生活随笔為你收集整理的linux 运行elf64,Elf64 格式的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。