爱技术

 找回密码
 注册会员

QQ登录

只需一步,快速开始

微信登录

微信扫一扫,快速登录

搜索
查看: 3060|回复: 8
收起左侧

ELF Loader 动态节区不理解

[复制链接]
发表于 2009-6-9 09:32:55 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?注册会员 微信登录

x
大家好,我最近在贵FTP上下了你们的ELF Loader,对ELF格式比较感兴趣,对elfloader.cpp中的PT_DYNAMIC段不是很了解,PT_DYNAMIC是用来重定位的吧?这个段中只对DT_REL进行了解析,在解析DT_REL的时候ELF32_R_TYPE()得到值(例如R_ARM_RABS32)具体什么意思?现在疑惑的是我们这个Loader所加载的ELF程序是编译时系统库采用静态的还是动态的?(感觉应该是动态的,因为处理了DT_RET)但是对PT_DYNAMIC段为什么只处理DT_REL,处理DT_REL时只处理了R_ARM_RABS32,R_ARM_ABS32,R_ARM_RELATIVE这几个类型,对系统的函数和全局变量是怎么重定位的呢(好像没有看到GOT和PLT)?

把不理解的一段拷过来请大家指点:
m=0;
      //выполним релокацию REL
      if (dyn[DT_RELSZ]!=0) {
while (m*sizeof(Elf32_Rel)<dyn[DT_RELSZ]){
#ifdef wintel
   cout<<"rel: of="<<hex<<((Elf32_Rel *)(reloc+dyn[DT_REL]-phdrs[n].p_vaddr))[m].r_offset
     <<" , sym_idx="<<ELF32_R_SYM(((Elf32_Rel *)(reloc+dyn[DT_REL]-phdrs[n].p_vaddr))[m].r_info)
              <<" , rel_type="<<dec<<(int) ELF32_R_TYPE(((Elf32_Rel *)(reloc+dyn[DT_REL]-phdrs[n].p_vaddr))[m].r_info)<<endl;
#endif
          Elf32_Word ri=ELF32_R_TYPE(((Elf32_Rel *)(reloc+dyn[DT_REL]-phdrs[n].p_vaddr))[m].r_info);
          if (ri!=R_ARM_RBASE)
          {
            if (ri==R_ARM_RABS32)
            {
              *((long*)(base+((Elf32_Rel *)(reloc+dyn[DT_REL]-phdrs[n].p_vaddr))[m].r_offset))+=(long)base-minadr;
            }
            else
              switch(ri){
               
              case R_ARM_NONE: break; // пустой релокейшен
              
              case R_ARM_ABS32:
#ifdef wintel
                cout << "base="<<hex<<(long)base<< endl;
                cout << "of="<<hex<<((Elf32_Rel *)(reloc+dyn[DT_REL]-phdrs[n].p_vaddr))[m].r_offset-minadr<<endl;
#endif
                *((long*)(base+((Elf32_Rel *)(reloc+dyn[DT_REL]-phdrs[n].p_vaddr))[m].r_offset-minadr))+=(long)base;
                break;
               
              case R_ARM_RELATIVE: // вообще говоря не minadr а начало сегмента содержащего символ
                *((long*)(base+((Elf32_Rel *)(reloc+dyn[DT_REL]-phdrs[n].p_vaddr))[m].r_offset-minadr))+=(long)base-minadr;
                break; // ignore
               
                //   case R_ARM_RABS32:
                //     *((long*)(base+((Elf32_Rel *)(reloc+dyn[DT_REL]-phdrs[n].p_vaddr))[m].r_offset))+=(long)base-minadr;
                //            break;
               
                //              case R_ARM_RBASE: break;
              default:  //неизвестный тип релокации
#ifdef wintel
                cout << "Invalid reloc type: " <<dec<<(unsigned)ELF32_R_TYPE(((Elf32_Rel *)(reloc+dyn[DT_REL]-phdrs[n].p_vaddr))[m].r_info) << endl;
#else
                fclose(fin, &iError);
#endif
                mfree(base);
                mfree(reloc);
                return -13;
              }

请指教,多谢!
发表于 2009-6-9 10:09:17 | 显示全部楼层
现在疑惑的是我们这个Loader所加载的ELF程序是编译时系统库采用静态的还是动态的?

静态的,

对于手机本身的函数的调用,是通过swi指令来实现的,moto的elf是通过直接call函数地址实现,所以他们的elf只能针对一个机型,也算是静态吧
回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-6-9 10:20:11 | 显示全部楼层
也就是说在编译ELF应用程序的时候把系统库函数和全局变量都静态的编译到程序里了?要是采用静态编译应用程序的size会比动态编译大多少呢?
还有请问你说的swi指令是什么意思,刚开始接触不是很理解!谢谢
回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-6-9 10:35:26 | 显示全部楼层
本帖最后由 henshiduju 于 2009-6-9 10:45 编辑

BingK ,谢谢你!针对静态编译,我想获取系统中的系统全局变量,应该怎样找到系统全局变量对应的值呢?
采用静态编译了怎么还需要PT_DYNAMIC段?
回复 支持 反对

使用道具 举报

发表于 2009-6-9 11:31:36 | 显示全部楼层
也就是说在编译ELF应用程序的时候把系统库函数和全局变量都静态的编译到程序里了?要是采用静态编译应用程序的size会比动态编译大多少呢?
还有请问你说的swi指令是什么意思,刚开始接触不是很理解!谢谢
henshiduju 发表于 2009-6-9 10:20

呃,其实我也不大清楚这些。
目前西机的ELF还无法实现动态编译的吧,库函数通过SWI(软件中断)调用,不需要编译到程序里。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-6-9 13:14:29 | 显示全部楼层
BingK,我查了一下swi,但是我现在不明白西机的ELF的swi是怎么和系统函数关联起来的是不是通过这种方式:
#pragma swi_number=0x0118
__swi        __arm        char * strstr (const char *s1,const char *s2);
也就是说swi 0x0118,就相当于调用函数strstr ?

系统中的全局变量又是怎么链接的呢?
最上面动态解析的代码还是不是很了解,还请你指点
回复 支持 反对

使用道具 举报

发表于 2009-6-9 14:58:31 | 显示全部楼层
SWI 就是你说的这样了
系统的全局变量通过直接用RAM地址写道swilib中,也通过SWI调用,
上面那个代码我也不是很明白
回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-6-9 17:04:04 | 显示全部楼层
好的,多谢!我再自己看看程序
回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-6-11 10:17:24 | 显示全部楼层

__swi 疑惑

上次BingK跟我说系统函数是通过swi指令来实现的,这段时间也想了一下swi,还是有些疑惑,请帮我解释一下

1.
#pragma swi_number=95
__swi __arm int GetFreeRamAvail();

#pragma swi_number=95
我猜应该是定义一个swi中断号

下面函数就是对应的中断响应函数
请帮我解释一下#pragma swi_number=95具体功能吗,或者怎么实现的

2.上面那个代码都是我们自己定义的,我们很清楚中断号对应的中断响应函数,但是我们编译程序时,编译器怎么知道将对GetFreeRamAvail的调用编译成swi 95呢?

谢谢!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员 微信登录

本版积分规则

小黑屋|Archiver|手机版|爱技术 ( 沪ICP备08115260号-3 )

GMT+8, 2024-5-20 04:14

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表