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)的完整描述,但是如果你想要知道更多,可以参考这个文档 - 这里

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在Linux运行ELF文件的命令是:./文件名。其中,文件名是指要运行ELF文件的名称。在运行之前,需要先给该文件添加可执行权限,即使用chmod命令将其权限设置为755或777。然后,通过终端进入该文件所在的目录,输入./文件名即可运行ELF文件。 ### 回答2: 在Linux系统中,运行elf文件的命令是"./文件名"或者 "sh 文件名"。 1. ./文件名 在Linux中,使用"./"可以直接运行当前文件夹中的程序。因此,如果要运行名为"example"的elf文件,只需要在终端中输入"./example"即可。 2. sh 文件名 另一种运行elf文件的命令是"sh 文件名"。这种方法是通过让Shell解释器运行elf文件来实现的。在这种情况下,Shell会打开一个新的进程并启动elf文件。这种方法适用于那些没有显式可执行权限的elf文件。 除了以上两种方法,还有其他一些方法可以运行elf文件,比如"exec 文件名"和"source 文件名"等。这些命令可能需要应用于不同的情况,具体情况具体分析。 需要注意的是,如果想要运行一个elf文件,必须先保证文件具备可执行权限。如果没有权限,可以使用chmod命令为其添加可执行权限。命令格式为"chmod +x 文件名"。 ### 回答3: 在Linux系统中,运行ELF文件的命令是通过命令行终端来完成的。以下是运行ELF文件的命令详解: 1. 在终端中切换到ELF文件所在的目录 在运行ELF文件之前,需要先进入包含该文件的目录。可以通过cd命令进入该目录。如例:假设我们的文件名是test,它所在的目录是/home/username/Documents/test,那么我们可以使用以下命令来进入该目录: cd /home/username/Documents/test 2. 运行ELF文件 进入包含ELF文件的目录后,可以使用下面的命令来运行该文件: ./test 该命令中的“.”表示当前目录,“/”表示根目录。运行该命令后,系统会根据文件首部中的信息读取程序入口地址,从而开始执行程序。 3. 设置文件的执行权限 在运行ELF文件之前,还需要确保文件已经有正确的执行权限。如果没有执行权限的话,需要使用以下命令添加权限: chmod +x test 该命令中的“+x”表示添加执行权限。 4. 在环境变量中指定路径 如果在任意目录下运行ELF文件,需要首先将该文件所在的路径添加到用户的环境变量中。可以通过在.bashrc文件中添加以下命令来实现: export PATH=$PATH:/path/to/test 其中,“/path/to/test”代表ELF文件所在的完整路径。 总之,以上是运行ELF文件的命令详解,希望对大家有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值