博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
慢慢欣赏linux elf文件
阅读量:4069 次
发布时间:2019-05-25

本文共 4331 字,大约阅读时间需要 14 分钟。

void parse_elf(void *output){	Elf32_Ehdr ehdr;	Elf32_Phdr *phdrs, *phdr;		memcpy(phdrs, output + ehdr.e_phoff, sizeof(*phdrs) * ehdr.e_phnum);	for (i = 0; i < ehdr.e_phnum; i++) {		phdr = &phdrs[i];		switch (phdr->p_type) {		case PT_LOAD:#ifdef CONFIG_RELOCATABLE			dest = output;			/*				参考下面的vmlinux.lds脚本				dest = out + (phdr->p_paddr - LOAD_PHYSICAL_ADDR)					 = out + (ADDR(.text) - LOAD_OFFSET) - LOAD_PHYSICAL_ADDR					 = out + (LOAD_OFFSET + LOAD_PHYSICAL_ADDR - LOAD_OFFSET) - LOAD_PHYSICAL_ADDR					 = out			 */			dest += (phdr->p_paddr - LOAD_PHYSICAL_ADDR);#else			dest = (void *)(phdr->p_paddr);	// p_paddr 为加载地址#endif			memcpy(dest,			       output + phdr->p_offset,			       phdr->p_filesz);			break;		default: /* Ignore other PT_* */ break;		}	}}

对应的lds脚本

SECTIONS{#ifdef CONFIG_X86_32        . = LOAD_OFFSET + LOAD_PHYSICAL_ADDR;        phys_startup_32 = startup_32 - LOAD_OFFSET;#endif	/* Text and read-only data */	.text :  AT(ADDR(.text) - LOAD_OFFSET) {	// AT 定义加载地址,属于 PT_LOAD 段		_text = .;		/* bootstrapping code */		HEAD_TEXT#ifdef CONFIG_X86_32		. = ALIGN(PAGE_SIZE);		*(.text.page_aligned)#endif		. = ALIGN(8);		_stext = .;		TEXT_TEXT		SCHED_TEXT		LOCK_TEXT		KPROBES_TEXT		IRQENTRY_TEXT		*(.fixup)		*(.gnu.warning)		/* End of text section */		_etext = .;	} :text = 0x9090		/* Data */	.data : AT(ADDR(.data) - LOAD_OFFSET) {		/* Start of data section */		_sdata = .;		/* init_task */		INIT_TASK_DATA(THREAD_SIZE)#ifdef CONFIG_X86_32		/* 32 bit has nosave before _edata */		NOSAVE_DATA#endif		PAGE_ALIGNED_DATA(PAGE_SIZE)		CACHELINE_ALIGNED_DATA(L1_CACHE_BYTES)		DATA_DATA		CONSTRUCTORS		/* rarely changed data like cpu maps */		READ_MOSTLY_DATA(INTERNODE_CACHE_BYTES)		/* End of data section */		_edata = .;	} :data

linux设备查看

[root@cliffr linux-2.6.32]# readelf -h vmlinuxELF Header:  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00   Class:                             ELF32  Data:                              2's complement, little endian  Version:                           1 (current)  OS/ABI:                            UNIX - System V  ABI Version:                       0  Type:                              EXEC (Executable file)  Machine:                           Intel 80386  Version:                           0x1  Entry point address:               0x400000  Start of program headers:          52 (bytes into file)  Start of section headers:          90528352 (bytes into file)  Flags:                             0x0  Size of this header:               52 (bytes)  Size of program headers:           32 (bytes)  Number of program headers:         3  Size of section headers:           40 (bytes)  Number of section headers:         70  Section header string table index: 67[root@cliffr linux-2.6.32]# [root@cliffr linux-2.6.32]# readelf -l vmlinuxElf file type is EXEC (Executable file)Entry point 0x400000There are 3 program headers, starting at offset 52Program Headers:  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align  LOAD           0x001000 0xc0400000 0x00400000 0x58f000 0x58f000 R E 0x1000  LOAD           0x590000 0xc098f000 0x0098f000 0xfe000 0x34e000 RWE 0x1000  NOTE           0x3e396c 0xc07e296c 0x007e296c 0x00168 0x00168     0x4 Section to Segment mapping:  Segment Sections...   00     .text .notes __ex_table .rodata __bug_table .pci_fixup __ksymtab __ksymtab_gpl __kcrctab __kcrctab_gpl __ksymtab_strings __init_rodata __param    01     .data .init.text .init.data .x86_cpu_dev.init .parainstructions .altinstructions .altinstr_replacement .exit.text .data.percpu .smp_locks .bss .brk    02     .notes 对于第二个LOAD来说, 也就是数据段, 从elf的角度来看, 两者存放的位置是紧挨着。我们看一下代码段内存加载的位置:dest = out + (phdr->p_paddr - LOAD_PHYSICAL_ADDR)	= out + (AT(ADDR(.text)) + text_len - LOAD_OFFSET - LOAD_PHYSICAL_ADDR)	= out + text_len[root@cliffr linux-2.6.32]# cat .config | grep CONFIG_PHYSICAL_STARTCONFIG_PHYSICAL_START=0x400000

简单介绍一下Linux中ELF格式文件

http://www.elecfans.com/emb/20190402898901.html

ELF结构

http://blog.chinaunix.net/uid-8473611-id-3184556.html

vmlinux 和普通elf文件的差别 linux kernel加载简述

https://blog.csdn.net/wdjjwb/article/details/81145255

ELF格式大致描述

https://blog.csdn.net/qq_36503007/article/details/82821922

链接脚本使用AT加载地址的总结

https://blog.csdn.net/czg13548930186/article/details/78770601

关于链接脚本.lds的小知识点

https://blog.csdn.net/yilongdashi/article/details/84873908

你可能感兴趣的文章
pdns 域名绑定 IP 故障备忘
查看>>
pdns 错误解决[备忘]
查看>>
intel x540-at2 openstack 下桥接故障
查看>>
内存控制器错误信息[备忘]
查看>>
常见监控工具说明
查看>>
多 bonding 使用不同 mode 方法
查看>>
利用 4 个磁盘进行 RAID10 自动创建
查看>>
ping 返回 no buffer space available 解决方法
查看>>
欢迎使用CSDN-markdown编辑器
查看>>
ssh passphrase 测试
查看>>
openstack 与 ceph (架构)
查看>>
openstack 与 ceph (monitor初始化)
查看>>
openstack 与 ceph (osd 部署)
查看>>
openstack 管理三十八 - ceph 与 crushmap
查看>>
mysql 插入/更新的简单方法
查看>>
osd 故障测试
查看>>
openstack 管理 三十七 - 创建 vm 并 指定IP 地址
查看>>
利用数据库自定义并发 bunket 功能
查看>>
ceph OSD 故障记录
查看>>
ceph osd 更换硬盘记录
查看>>