ELF 解析所以重定位节 包含REL RELA

本文详细解析了ELF文件中的重定位节,涵盖了REL和RELA两种类型,主要关注32位的i386和arm平台。探讨了如何处理这些重定位信息,为理解ELF格式和程序加载过程提供关键洞察。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ELF 解析所以重定位节 包含REL RELA,并未支持所有平台,仅实现了i386和arm平台 32位支持

/*
 * ParseRelocation.c
 *
 *  Created on: 2014年7月20日
 *      Author: angel-toms
 */

#include "ElfParser.h"

static void get_rel_dyn_type(u2 machineType,u4 rInfo,u1* type);

void print_elf_section_of_reldyn(MemMapping* mem,Elf32_Ehdr* pHeader,Elf32_Shdr* pSheader){
	Elf32_Rel* pRel						= NULL;
	Elf32_Sym* pSymMem  			    = NULL;
	u1* shStringTableMem				= NULL;
	u4 i 								= 0;
	u4 size								= 0;
	u1 buf[55];
	LookupSection* pLookupSection 		= NULL;
	LookupSection* pLookupStrSection 	= NULL;
	Elf32_Shdr* pReldyn					= NULL;
	shStringTableMem = get_elf_section_of_shstr_table(mem,pHeader,pSheader);
	if(NULL == shStringTableMem){
		printf("Error,get elf section header string table failed !\n");
		goto Exit;
	}

	for( ; i < pHeader->e_shnum ; i++){
		if(pSheader[i].sh_type == SHT_REL && strcmp((const char*)(shStringTableMem + pSheader[i].sh_name),".rel.dyn") == 0){
			size = (pSheader[i].sh_size / pSheader[i].sh_entsize);
			pRel = (Elf32_Rel*)(mem->base + pSheader[i].sh_offset);
			pReldyn = (Elf32_Shdr*) &pSheader[i];
			break;
		}
		continue;
	}

	if(NULL != pRel){
		//@1 by default ,rel.dyn link dynsym ,so it sh_link is the index
		pLookupSection = get_section_by_index(mem,pHeader,pSheader,pReldyn->sh_link);
		if(NULL == pLookupSection){
			printf("Error,get section by index failed\n");
			goto Exit;
		}
		pSymMem = (Elf32_Sym*)pLookupSection->base;
		pLookupStrSection = get_section_by_index(mem,pHeader,pSheader,pLookupSection->link);
		if(NULL == pLookupStrSection){
			printf("Error,get sym tab link failed\n");
			goto Exit;
		}
		i = 0;
		printf("Relocation section '.rel.dyn' at offset 0x%.8x contains %d entries:\n",pReldyn->sh_addr,size);
		printf("Offset     Info     Type           Sym.Value  Sym. Name\n");
		for( ; i < size ; i++ ){
			printf("0x%.8x ",pRel[i].r_offset);
			printf("%.8x ",pRel[i].r_info);
			memset(&buf,0,55);
			get_rel_dyn_type((u2)pHeader->e_machine,(u4)ELF32_R_TYPE(pRel[i].r_info),(u1*)buf);
			printf("%-15s",buf);
			if(pSymMem[ELF32_R_SYM(pRel[i].r_info)].st_name != 0){
				printf("%.8x   ",pSymMem[ELF32_R_SYM(pRel[i].r_info)].st_value);
				printf("%s",(pLookupStrSection->base + pSymMem[ELF32_R_SYM(pRel[i].r_info)].st_name));
			}
			printf("\n");
		}
	}

	Exit:
	if(shStringTableMem)
		free(shStringTableMem);
	if(pLookupSection)
		free(pLookupSection);
	if(pLookupStrSection)
		free(pLookupStrSection);
}

//this impl  code almost sample as the top  print_elf_section_of_reldyn,but its' sh_info  point to which section will be relocated
void print_elf_section_of_relplt(MemMapping* mem,Elf32_Ehdr* pHeader,Elf32_Shdr* pSheader){
	Elf32_Rel* pRelplt					= NULL;
	Elf32_Sym* pSymMem  			    = NULL;
	u1* shStringTableMem				= NULL;
	u4 i 								= 0;
	u4 size								= 0;
	u1 buf[55];
	LookupSection* pLookupSection 		= NULL;
	LookupSection* pL
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值