b-link有没有穿衣搭配的app掌声app

查看: 598|回复: 9
给福州球迷一个掌声
发表于 3&天前
。。。。总是为落后的一方加油。。。不管是李林,还是李王。。。。
。。福州果然是福地,出了有福气的球迷。。。。
发表于 3&天前
有知名度的才会这样,
发表于 3&天前
不仅福州,大部分的国人都不错的,否则5兄也不会在中羽待这么久了,对不?
发表于 3&天前
不仅福州,大部分的国人都不错的,否则5兄也不会在中羽待这么久了,对不?
.....同意好的多。。。。。。呆在这里主要全是对羽球运动的兴趣。。。。
发表于 3&天前
福州球迷好样的
发表于 3&天前
大波分分钟撕碎你们
发表于 3&天前
大波比说福州观众不爱国,派黑裁咬死你
发表于 3&天前
本帖最后由 习小小 于
09:48 编辑
给福州球迷掌声,不是等于间接抽马国球迷的脸么?
发表于 3&天前
<font color="#37 发表于
.....同意好的多。。。。。。呆在这里主要全是对羽球运动的兴趣。。。。
兼容并包,世俗理性本来就是华人的特点,只是近百年国家集弱久经战乱,n多问题,但本质没变过。
发表于 3&天前
兼容并包,世俗理性本来就是华人的特点,只是近百年国家集弱久经战乱,n多问题,但本质没变过。
。。。是是。。。。家家/国国都有本难念的经。。。还是做好自己本分。。
Powered by后使用快捷导航没有帐号?
欢迎您首次访问华人街请选择您当前所在国家位置进行内容切换:
此操作将在您下回登录时自动记录您的这次国家选择。如需重新切换,可通过切换国家完成。
查看: 112|回复: 3
关于邮局app的网上注册
在线时间 小时
发表于 昨天&14:54
马上注册,结交更多街友,享用更多功能,让你轻松玩转华人街。
才可以下载或查看,没有帐号? &&&&
注册到这一步的时候 我居然找不到意大利 有没有注册过的人告诉我一下要怎么弄
在线时间 小时
发表于 昨天&14:55
前面 italy 没有?
在线时间 小时
发表于 昨天&14:59
前面 italy 没有?
在线时间 小时
发表于 昨天&16:28
再下面点点
半小时前1&小时前3&小时前3&小时前4&小时前4&小时前4&小时前4&小时前4&小时前
12726671993113797518359466467325210953340
紧急!?小伙子你上火了吧,旁边大妈都笑开花了!老外对日本料理的刺身好感度怎样?法国??本土纯正顶级巧克力!la fabrique 这样回家会比较安全点吧?4438人阅读
最近在一直在做uboot的移植工作,uboot中有很多&#20540;得学习的东西,之前总结过uboot的启动流程,但uboot一个非常核心的功能没有仔细研究,就是uboot的relocation功能。
这几天研究下uboot的relocation功能,记录在此,跟大家共享。
自己辛苦编辑,转载请注明出处,谢谢!
所谓的relocation,就是重定位,uboot运行后会将自身代码拷贝到sdram的另一个位置继续运行,这个在uboot启动流程分析中说过。
但基于以前的理解,一个完整可运行的bin文件,link时指定的链接地址,load时的加载地址,运行时的运行地址,这3个地址应该是一致的
relocation后运行地址不同于加载地址 特别是链接地址,ARM的寻址会不会出现问题?
新版uboot跟老版uboot不太一样的地方在于新版uboot不管uboot的load addr(entry pointer)在哪里,启动后会计算出一个靠近sdram顶端的地址,将自身代码拷贝到该地址,继续运行。
个人感觉uboot这样改进用意有二,一是为kernel腾出低端空间,防止kernel解压覆盖uboot,二是对于由静态存储器(spiflash nandflash)启动,这个relocation是必须的。
但是这样会有一个问题,relocation后uboot的运行地址跟其链接地址不一致,compiler会在link时确定了其中变量以及函数的绝对地址,链接地址 加载地址 运行地址应该一致,
这样看来,arm在寻址这些变量 函数时找到的应该是relocation之前的地址,这样relocation就没有意义了!
当然uboot不会这样,我们来分析一下uboot下relocation之后是如何寻址的,开始学习之前我是有3个疑问,如下
(1)如何对函数进行寻址调用
(2)如何对全局变量进行寻址操作(读写)
(3)对于全局指针变量中存储的其他变量或函数地址在relocation之后如何操作
搞清楚这3个问题,对于我来说relocation的原理就算是搞明白了。
为了搞清楚这些,在uboot的某一个文件中加入如下代码
void test_func(void)
printf(&test func\n&);
static void * test_func_val = test_
static int test_val = 10;
void rel_dyn_test()
test_val = 20;
printf(&test = 0x%x\n&, test_func);
printf(&test_func = 0x%x\n&, test_func_val);
test_func();
rel_dyn_test函数中就包含了函数指针 变量赋&#20540; 函数调用这3种情况,寻址肯定要汇编级的追踪才可以,编译完成后反汇编,得到u-boot.dump(objdump用-D选项,将所有section都disassemble出来)
找到rel_dyn_test函数,如下:
80e9d3cc &test_func&:
ldr r0, [pc, #0] 80e9d3d4 &test_func+0x8&
80e8dfc4 &printf&
0x80eb1c39
80e9d3d8 &rel_dyn_test&:
ldr r2, [pc, #44] 80e9d40c &rel_dyn_test+0x34&
mov r3, #20 ; 0x14
ldr r1, [pc, #36] 80e9d410 &rel_dyn_test+0x38&
str r3, [r2]
ldr r0, [pc, #32] 80e9d414 &rel_dyn_test+0x3c&
80e8dfc4 &printf&
ldr r3, [pc, #28] 80e9d418 &rel_dyn_test+0x40&
ldr r0, [pc, #28] 80e9d41c &rel_dyn_test+0x44&
ldr r1, [r3]
80e8dfc4 &printf&
pop {r4, lr}
80e9d3cc &test_func&
0x80eb75c0
0x80e9d3cc
0x80eb1c44
0x80eaa54c
0x80eb1c51
80eb75c0 &test_val&:
0x0000000a
80eaa54c &test_func_val&:
0x80e9d3cc
rel_dyn_test反汇编后,最后多了一部分从0x80e9d40c开始的内存空间,对比发现这部分内存空间地址上的&#20540;竟然是函数需要的变量test_val test_func_val的地址。
网上资料称这些函数末尾存储变量地址的内存空间为Label,(编译器自动分配)
一条条指令来分析。
ldr &r2, & [pc, &#44] ========& r2 = [pc &#43; 0x2c]=======&r2 = [0x80e9d3e0 &#43; 0x2c]=======&r2 =[0x80e9d40c]
需要注意,由于ARM的流水线机制,当前PC&#20540;为当前地址加8个字节
这样r2获取的是0x80e9d40c地址的&#eb75c0,这就是test_val的&#20540;嘛
mov r3, #20======& r3 = 20
对应C函数这应该是为test_val = 20做准备,先跳过后面2条指令,发现
str &r3, & [r2]
很明显了,将立即数20存入0x80eb75c0中也就是test_val中。
这3条指令说明,ARM对于变量test_val的寻址如下:
(1)将变量test_val的地址存储在函数尾端的Label中(这段内存空间是由编译器自动分配的,而非人为)
(2)基于PC相对寻址获取函数尾端Label上的变量地址
(3)对test_val变量地址进行读写操作
再来看其中的几条指令
ldr&& r3, [pc,&& #28] =====& r3 = [0x80e9d3fc &#43; 0x1c] =====& r3 = [0x80e9d418] ====& r3 = 0x80eaa54c
ldr&& r1, [r3] =====& r1 = [0x80eaa54c] ======& r1 = 0x80e9d3cc
0x80e9d3cc这个地址可以看出是test_func的入口地址,这里是printf打印test_func_val的&#20540;
可以看出对于函数指针变量的寻址跟普通变量一样。
接下来来看函数的调用,可以看到对于printf以及test_func,使用的是指令bl以及b进行跳转,这2条指令都是相对寻址(pc &#43; offset)
说明ARM调用函数使用的是相对寻址指令bl或b,与函数的绝对地址无关
对于这3种情况的寻址方法已经知道了,那就需要思考一下relocation之后会有什么变化。
将rel_dyn_test& relocation之后可以想象,函数的调用还是没有问题的,因为使用了bl或b相对跳转指令。
但是对于变量的寻址就有问题了,寻址的前2步没有问题,相对寻址获取尾部Label中的变量地址,但获取的变量地址是在 link时就确定下来的绝对地址啊!
而对于指针变量的寻址呢,问题更多了,
首先跟普通变量寻址一样,尾部内存空间的变量地址是link时的绝对地址,再者,指针变量存储的变量指针或者函数指针也是在link时确定的绝对地址,relocation之后这个&#20540;也变了!
那uboot是如何来处理这些情况的呢?更准确的说应该是compiler和uboot如何一起来处理这些情况的呢?
这里利用了PIC位置无关代码,通过为编译器指定编译选项-fpic或-fpie产生,
这样编译产生的目标文件包含了PIC所需要的信息,-fpic,-fpie是gcc的PIC编译选项。ld也有PIC连接选项-pie,要获得一个完整的PIC可运行文件,连接目标文件时必须为ld指定-pie选项,
察看uboot的编译选项发现,在arch/arm/config.mk,如下:
# needed for relocation
LDFLAGS_u-boot += -pie
uboot只指定了-pie给ld,而没有指定-fPIC或-fPIE给gcc。
指定-pie后编译生成的uboot中就会有一个rel.dyn段,uboot就是靠rel.dyn段实现了完美的relocation!
察看u-boot.dump中的rel.dyn段,如下:
Disassembly of section .rel.dyn:
80eb7d54 &__rel_dyn_end-0x5c10&:
r0, r8, r0, lsr #32
r0, r0, r7, lsl r0
r0, r8, r4, lsr #32
r0, r0, r7, lsl r0
r0, r8, r8, lsr #32
r0, r0, r7, lsl r0
&span style=&color:#FF0000;&&80eba944:
sp, r9, ip, lsl #8
r0, r0, r7, lsl r0
sp, r9, r0, lsl r4
r0, r0, r7, lsl r0
sp, r9, r4, lsl r4
r0, r0, r7, lsl r0
sp, r9, r8, lsl r4
r0, r0, r7, lsl r0
sp, r9, ip, lsl r4
r0, r0, r7, lsl r0&/span&
有没有注意到,rel_dyn_test末尾存储全局变量地址的Label地址也存储在这里,那有什么用呢,那就来看一下uboot的核心函数relocate_code是如何实现自身的relocation的,
在arch/arm/lib/relocate.S中
ENTRY(relocate_code)
r1, =__image_copy_start /* r1 &- SRC &__image_copy_start */
r4, r0, r1
/* r4 &- relocation offset */
relocate_done
/* skip relocation */
r2, =__image_copy_end
/* r2 &- SRC &__image_copy_end */
copy_loop:
r1!, {r10-r11}
/* copy from source address [r1]
r0!, {r10-r11}
/* copy to
target address [r0]
/* until source end address [r2]
* fix .rel.dyn relocations
r2, =__rel_dyn_start
/* r2 &- SRC &__rel_dyn_start */
r3, =__rel_dyn_end
/* r3 &- SRC &__rel_dyn_end */
r2!, {r0-r1}
/* (r0,r1) &- (SRC location,fixup) */
r1, r1, #0xff
/* relative fixup? */
/* relative fix: increase location by offset */
r0, r0, r4
r1, r1, r4
relocate_done:
前半部分在uboot启动流程中讲过,将__image_copy_start到__image_copy_end之间的数据进行拷贝
来看一下arm的link script,在arch/arm/cpu/u-boot.lds,如下:
OUTPUT_FORMAT(&elf32-littlearm&, &elf32-littlearm&, &elf32-littlearm&)
OUTPUT_ARCH(arm)
ENTRY(_start)
. = ALIGN(4);
*(.__image_copy_start)
CPUDIR/start.o (.text*)
. = ALIGN(4);
.rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
. = ALIGN(4);
. = ALIGN(4);
. = ALIGN(4);
.u_boot_list : {
&pre name=&code& class=&cpp&&
KEEP(*(SORT(.u_boot_list*)));
. = ALIGN(4);
.image_copy_end :
*(.__image_copy_end)
.rel_dyn_start :
*(.__rel_dyn_start)
.rel.dyn : {
.rel_dyn_end :
*(.__rel_dyn_end)
_image_binary_end = .;
可以看出__image_copy_start---end之间包括了text data rodata段,但是没有包括rel_dyn。
继续看relocate_code函数,拷贝__image_copy_start----end之间的数据,但没有拷贝rel.dyn段。
首先获取__rel_dyn_start地址到r2,将start地址上连续2个4字节地址的&#20540;存在r0 r1中
判断r1中的&#20540;低8位,如果为0x17,则将r0中的&#20540;加relocation offset。
获取以此r0中&#20540;为地址上的&#20540;,存到r1中
将r1中&#20540;加relocation offset,再存回以r0中&#20540;为地址上。
以此循环,直到__rel_dyn_end。
这样读有些拗口。来以咱们的rel_dyn_test举例子。
上面rel.dyn段中有一段如下:
sp, r9, ip, lsl #8
r0, r0, r7, lsl r0
按照上面的分析,判断第二个四字节为0x17,r0中存储为0x80e9d40c。这个是rel_dyn_test末尾Label的地址啊,
将r0加上relocation offset,则到了relocation之后rel_dyn_test的末尾Label。
获取r0为地址上的&#20540;到r1中,0x80eb75c0,可以看到,这个&#20540;就是变量test_val的首地址啊。
最后将r1加上relocation offset,写回以r0为地址上。意思是将变量test_val地址加offset后写回到relocation之后rel_dyn_test的末尾Label中。
这样relocate_code完成后,再来看对test_val的寻址。寻址第三步获取到的是修改之后的relocation addr啊,这样就可以获取到relocation之后的test_val&#20540;!
对于普通变量寻址是这样,那对于指针变量呢,如test_func_val呢?
获取test_func_val relocation后地址的步骤跟上面一样,但是我们在获取test_func_val的&#20540;时要注意,这个变量存储的是函数test_func指针,之前是0x80e9d3cc,relocation之后就变化了,所以test_func_val的&#20540;也应该变化,这个该怎么办?
方法是一样的,可以在rel.dyn段中找到如下一段:
sl, sl, ip, asr #10
r0, r0, r7, lsl r0
这上面存储的是test_func_val的地址,按照relocate_code的操作,完成后80eaa54c &#43; offset上的&#20540;也应该&#43;offset了。
这就解决了,test_func_val的&#20540;也就是test_func的地址也被修改为relocation之后的地址了。
网上查阅资料,这里对于rel.dyn段中每一个rel section(8个字节)第二个4字节,0x17,是一种label的类型R_ARM_RELATIVE,
经过上面uboot的relocate_code后,我们提出的3个问题的寻址都可以正常工作。
还有一个疑问,是谁来决定哪些label放到rel.dyn中,特别是对于存储指针的变量,如何分辨,这样看来,是compiler的ld来完成的这个工作,将所有需要relocate的label放到rel.dyn段中,真是牛&#36924;的compiler啊!
总结一下,可以看出,
使用-pie选项的compiler,将需要relocate的&#20540;(全局变量地址 &函数入口地址)的地址存储在rel.dyn段中,uboot运行中relocate_code遍历rel.dyn段,根据rel.dyn中存储的&#20540;,对以(这些&#20540;&#43;offset)为地址上的&#20540;进行了relocate,完成对所有需要relocate的变量的修改!。。。。还是有些拗口。。。
需要注意的是,在uboot的整个relocate_code中rel.dyn不仅没有拷贝,也没有修改,修改只是针对rel.dyn中&#20540;&#43;offset为地址上的&#20540;!
查阅网上资料,compiler在cc时加入-fPIC或-fPIE选项,会在目标文件中生成GOT(global offset table),将本文件中需要relocate的&#20540;存放在GOT中,函数尾部的Label来存储GOT的offset以及其中变量的offset,变量寻址首先根据尾部Label相对寻址找到GOT地址,以及变量地址在GOT中的位置,从而确定变量地址,这样对于目标文件统一修改GOT中的&#20540;,就修改了变量地址的offset,完成了relocation。
ld时加入-pie选项,就会将GOT并入到rel.dyn段中,uboot在relocate_code中统一根据rel.dyn段修改需要relocation的数&#20540;。
uboot中ld使用-pie而cc没有使用-fPIC或-fPIE,目标文件中就不会生成GOT,函数中寻址还是在尾部Label中直接存储变量的绝对地址,但这个Label同样存在rel.dyn中,uboot根据rel.dyn段修改Label上的&#20540;,就完成了relocation。
这样不仅节省了每个目标文件的GOT段,而且不需要去相对寻址GOT,直接修改函数尾部Label所存储的变量地址就可以啦!
uboot的relocation就是如此!
版权声明:本文为博主原创文章,未经博主允许不得转载。
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:352537次
积分:4911
积分:4911
排名:第2906名
原创:120篇
转载:95篇
评论:190条
阅读:5085
阅读:10840
阅读:33394
(1)(2)(2)(3)(2)(1)(1)(4)(2)(1)(1)(4)(5)(2)(6)(2)(7)(7)(3)(10)(1)(2)(7)(3)(1)(7)(13)(13)(6)(7)(9)(10)(13)(11)(12)(7)(8)(17)(2)《掌声有没有》技术 - 穿越火线视频 - 爱拍原创后使用快捷导航没有帐号?
只需一步,快速开始
查看: 215|回复: 4
在线时间8 小时经验值168 最后登录注册时间帖子阅读权限40UID
高中生, 积分 168, 距离下一级还需 32 积分
TA的每日心情无聊 12:53签到天数: 1 天[LV.1]初来乍到
G币2 最后登录注册时间
马上注册,结交更多机友,下载更多应用,让你轻松玩转手机。
已有帐号?   下载游戏和软件,请【】进入机锋市场!
本帖最后由 dante.titor 于
16:07 编辑
前几天刷了一个包,然后通讯录就挂掉了。能不能麻烦各位5.0的用户传一下这个apk,位置是\system\priv-app\Phonebook,感激不尽...
在线时间4 小时经验值327 最后登录注册时间帖子阅读权限50UID5037555
大学专科, 积分 327, 距离下一级还需 73 积分
TA的每日心情开心 22:11签到天数: 1 天[LV.1]初来乍到
G币2 最后登录注册时间
在线时间4 小时经验值327 最后登录注册时间帖子阅读权限50UID5037555
大学专科, 积分 327, 距离下一级还需 73 积分
TA的每日心情开心 22:11签到天数: 1 天[LV.1]初来乍到
G币2 最后登录注册时间
附件怎么穿不上
21:49 上传
点击文件名下载附件
下载积分: G币 -1
10.21 MB, 下载次数: 1, 下载积分: G币 -1
在线时间8 小时经验值168 最后登录注册时间帖子阅读权限40UID
高中生, 积分 168, 距离下一级还需 32 积分
TA的每日心情无聊 12:53签到天数: 1 天[LV.1]初来乍到
G币2 最后登录注册时间
阳坤宿雨 发表于
附件怎么穿不上
刚刚才看到,十分感谢!
在线时间2 小时经验值802 最后登录注册时间帖子阅读权限70UID
学士, 积分 802, 距离下一级还需 298 积分
TA的每日心情奋斗10&小时前签到天数: 282 天[LV.8]以坛为家I
G币2939 最后登录注册时间
你为啥不解压ROM自己动手呢?
Powered by

我要回帖

更多关于 b站有没有app 的文章

 

随机推荐