精华内容
下载资源
问答
  • ilocker:关注 Android 安全(新手) QQ: 2597294287 重定位就是把符号引用与符号定义链接起来的过程,这也是 android linker 的主要工作之一。 当程序中调用一个函数时...这些重定位信息保存在一系列的重定位项中...

    ilocker:关注 Android 安全(新手) QQ: 2597294287

    重定位就是把符号引用与符号定义链接起来的过程,这也是 android linker 的主要工作之一。

    当程序中调用一个函数时,相关的 call 指令必须在执行期将控制流转到正确的目标地址。所以,so 文件中必须包含一些重定位相关的信息,linker 据此完成重定位的工作。

    这些重定位信息保存在一系列的重定位项中,重定位项的结构如下:

    这些重定位项位于 .rel.plt section 中。

    r_offset:对于可执行文件或 so 文件来说,该值是要进行重定位的存储单元的虚拟地址。

    r_info:该值给出两个重要信息,一个是要重定位的符号在符号表中的索引,另一个是要施行的重定位类型。这两个信息分别由两个宏来提取。

    对于 32 位的 so 来说,ELFW(R_TYPE) 就是 ELF32_R_SYM,ELFW(R_SYM) 就是 ELF32_R_SYM。

    转载于:https://www.cnblogs.com/ilocker/p/4904942.html

    展开全文
  • Nand启动中的代码重定位 CPU可以直接访问SRAM、SDRAM、NorFlash ,不能直接访问 Nand 但是我们依然可以设置为Nand启动,为什么呢? 2440内部硬件可以把Nand前4K代码复制到SRAM上,CPU从0运行。(这里的0地址是SRAM的...

    1、Nand启动为什么需要代码重定位?

    CPU可以直接访问SRAM、SDRAM、NorFlash ,不能直接访问 Nand。因此Nand Flash只有存储代码的功能,它不能运行代码。
    但是我们依然可以设置为Nand启动,为什么呢?
    2440内部硬件可以把Nand前4K代码复制到SRAM上,CPU从0运行。(这里的0地址是SRAM的基地址)

    但是如果程序大于4K时,怎么办?
    把全部程序读出来,放到SDRMA上。(这就是代码重定位,重新确定代码运行的地址)

    2、 Nand启动为什么需要代码重定位?

    因为Nor可以运行代码,所以就不需要把代码复制到SRAM上,
    但是由于Nor Flash特性:可以像内存一样读,但不能像内存直接写
    MOV R0, #0
    LDR R1, [R0] @读有效
    STR R1, [R0] @写无效
    那么程序中含有需要更改的变量,怎么办?
    全局变量在bin文件中,写在Nor上,直接修改变量,是无效的
    因此需要把全局变量/静态变量,重定位放到SDRAM中

    3、写个代码体验下,所谓的Nor不可写的特性:

    #include "s3c2440_soc.h"
    #include "uart.h"
    #include "init.h"
    
    char g_Char = 'A';  //定义一个全局变量
    const char g_Char2 = 'B'; //定义固定的全局变量
    int g_A = 0;
    int g_B;
    
    int main(void)
    {
        uart0_init();
    
        while (1)
        {
            putchar(g_Char); /*让g_Char输出*/
            g_Char++;         /* nor启动时, 此代码无效 */
            delay(1000000);
        }
    
    
        return 0;
    }
    

    查看下sdram.bin文件,发现我们的代码很短,但是文件却很大:
    -rwxrwxr-x 1 book book 33930 4月 9 14:38 sdram.bin*

    查看sdram.dis文件 发现data数据段放在了0x0000848c这个地址导致 程序太大:

    Disassembly of section .rodata:
    
    00000488 <g_Char2>:
     488:	42          	.byte	0x42
    Disassembly of section .data:
    
    00008489 <__data_start>:
        8489:	41          	.byte	0x41
    Disassembly of section .bss:
    
    0000848c <g_A>:
        848c:	00000000 	.word	0x00000000
    
    00008490 <g_B>:
        8490:	00000000 	.word	0x00000000
    

    在makefile中加入这么一句话
    arm-linux-ld -Ttext 0 -Tdata 0x800 start.o led.o uart.o init.o main.o -o sdram.elf

    再次查看下sdram.bin文件大小,这才正常:
    -rwxrwxr-x 1 book book 2049 4月 9 13:56 sdram.bin*

    烧写在NORFlash 和 烧写在NANDFlash观察这两种的效果:
    设置成NANDFlash启动没有问题 显示ABCDE…
    设置成NORFlash启动显示AAA

    从反汇编文件,我们可以知道一个程序里面有:
    .text 代码段
    .data 数据段
    rodata 只读数据段(const全局变量)
    bss段 (初始值为0,无初始值的全局变量)
    commen 注释
    其中bss段和commen 注释不保存在bin文件中。

    程序大小为2049,g_char保存在0x800地址上,0~0x800的内存空间一共为2049字节的大小,所以可见bss不保存在bin文件中:

    Disassembly of section .data:
    
    00000800 <__data_start>:
     800:	41          	.byte	0x41
    Disassembly of section .rodata:
    
    00000488 <g_Char2>:
     488:	42          	.byte	0x42
    Disassembly of section .bss:
    
    00000804 <g_A>:
     804:	00000000 	.word	0x00000000
    
    00000808 <g_B>:
     808:	00000000 	.word	0x00000000
    Disassembly of section .comment:
    
    00000000 <.comment>:
    
    展开全文
  • 1、实现一体式代码重定位 先梳理下把整个程序复制到SDRAM需要哪些技术细节: 把程序从Flash复制到运行地址,链接脚本中就要指定运行地址为SDRAM地址; 编译链接生成的bin文件,需要在SDRAM地址上运行,但上电后却...

    参考韦东山和http://www.bubuko.com/infodetail-2504561.html

    1、实现一体式代码重定位

    把整个程序复制到SDRAM需要哪些技术细节:

    1. 把程序从Flash复制到运行地址,链接脚本中就要指定运行地址为SDRAM地址;
    2. 编译链接生成的bin文件,需要在SDRAM地址上运行,但上电后却必须先在0地址运行,这就要求重定位之前的代码与位置无关(是位置无关码);

    参考Uboot修改链接脚本:

    SECTIONS
    {
        . = 0x30000000;
    
        . = ALIGN(4);
        .text      :
        {
          *(.text)
        }
    
        . = ALIGN(4);
        .rodata : { *(.rodata) }
    
        . = ALIGN(4);
        .data : { *(.data) }
    
        . = ALIGN(4);
        __bss_start = .;
        .bss : { *(.bss) *(.COMMON) }
        _end = .;
    }
    

    修改start.S段:
    注意0x30000000的位置就是汇编文件里定义的_start

        /* 重定位text, rodata, data段整个程序 */
        mov r1, #0
        ldr r2, =_start         /* 第1条指令运行时的地址 */
        ldr r3, =__bss_start    /* bss段的起始地址 */
    
    cpy:
        ldr r4, [r1]
        str r4, [r2]
        add r1, r1, #4
        add r2, r2, #4
        cmp r2, r3
        ble cpy
    
    
        /* 清除BSS段 */
        ldr r1, =__bss_start
        ldr r2, =_end
        mov r3, #0
    clean:
        str r3, [r1]
        add r1, r1, #4
        cmp r1, r2
        ble clean
    
        bl main  
    
    halt:
        b halt
    

    烧写到Nor Flash,启动情况:

    在这里插入图片描述
    运行结果:
    代码是正常运行的
    g_A = 0x00000000
    AaBbCcDdEe

    疑惑:为什么可以运行正常呢,main的跳转是位置无关的,所以是跳转到Nor上的,获取的应该是Nor上的data段,Nor上的数据是不可写的,应该是不停写出AaAa才对吧。

    2、从分析反汇编引入位置无关码的概念

    查看反汇编:
    bl 30000490 <sdram_init>的疑惑,这行代码是在cpy之前执行的,因此我们还没有将代码复制到SDRAM上,而这时候却去SDRAM上执行sdram_init,理论上是执行不了这个函数的。

    30000058:	05810000 	streq	r0, [r1]
    3000005c:	eb00010b 	bl	30000490 <sdram_init>
    30000060:	e3a01000 	mov	r1, #0	; 0x0
    30000064:	e59f204c 	ldr	r2, [pc, #76]	; 300000b8 <halt+0x14>
    30000068:	e59f304c 	ldr	r3, [pc, #76]	; 300000bc <halt+0x18>
    

    我们把链接脚本的起始地址改为0x320000000,发现机器码与之前起始地址为0x300000000是一样的,都是eb00010b,

    32000058:   05810000    streq   r0, [r1]
     3200005c:   eb00010b    bl  32000490 <sdram_init>
     32000060:   e3a01000    mov r1, #0  ; 0x0
    32000064:   e59f204c    ldr r2, [pc, #76]   ; 320000b8 <halt+0x14>
     32000068:   e59f304c    ldr r3, [pc, #76]   ; 320000bc <halt+0x18>
    

    说明不是真的跳到30000490 的地址,实际是跳到pc+off_set的地址:
    从0x30000000执行,当前指令地址为 3000005c,跳到30000490
    从0执行,当前指令地址为 5c,则跳到490

    总结下,位置无关什么意思呢?

    既然这个时候SDRAM还没有代码,那就不去那里找了嘛,我们去别的地方找。别的地方是哪里呢?这个时候代码是运行在SRAM上的,处理器的PC寄存器也是指向这个地方的,有4K代码也是在这个地方的。那我就不用链接指定的地址来寻找想要的代码,我设计一些是与PC寄存器指向的位置有联系的寻址指令来寻址,这样PC寄存器指向哪里,我就在哪里找我想要的代码,而不是去链接指定的地址去找。

    位置无关指令就是这样的指令,他不去链接指定位置寻找代码,而是在PC寄存器指向的位置相对它前后32M的范围寻找代码,也就是说只要我想要调用的代码在PC指向位置前后的32M范围内,就能找到(这是硬件完成的,我们知道位置无关指令就是这个意思就行)。当然,我们的SRAM只有4K,所以寻找的范围肯定就只能在这4K里面才行了,超过了也是找不到的。所以要求我们的重定位代码必须在这4K里面,必要的硬件初始化代码,内存初始化代码,nand初始化代码等等,必须在4K以内完成,否则就会出问题。所以位置无关指令的寻址是基于当前PC寄存器位置来寻址的。
    因此要写位置无关码的时候,我们都要用位置无关的指令。

    位置无关/相关指令:

    B BL ADR MOV ADD等,这些指令都是位置无关指令

    LDR STR等指令是位置有关指令

    怎么写位置无关码?

    • 使用相对跳转命令 b或bl;
    • 重定位之前,不可使用绝对地址,不可访问全局变量/静态变量,也不可访问有初始值的数组(因为初始值放在rodata里,是使用绝对地址来访问);
    • 重定位之后,使用ldr pc = xxx,跳转到/runtime地址;
      写位置无关码,其实就是不使用绝对地址,判断有没有使用绝对地址,除了前面的几个规则,最根本的办法看反汇编。

    在这里插入图片描述
    bl main的时候 是跳转到Nor上的地址,是跳不到SDRAM上的main函数

    要想让main函数在SDRAM执行,需要修改代码:

     //bl main  /*bl相对跳转,程序仍在NOR/sram执行*/
     ldr pc, =main/*绝对跳转,跳到SDRAM*/
    

    你写的的sdram_init是与位置无关的代码,我们可以写一个与位置有关的——访问有初始值的数组,看看运行结果:

    /**************************************************************************   
    * 设置控制SDRAM的13个寄存器
    * 使用位置无关代码
    **************************************************************************/   
    void memsetup(void)
    {
    	unsigned long *p = (unsigned long *)MEM_CTL_BASE;	
    	p[0] = 0x22111110;		//BWSCON
    	p[1] = 0x00000700;		//BANKCON0
    	p[2] = 0x00000700;		//BANKCON1
    	p[3] = 0x00000700;		//BANKCON2
    	p[4] = 0x00000700;		//BANKCON3	
    	p[5] = 0x00000700;		//BANKCON4
    	p[6] = 0x00000700;		//BANKCON5
    	p[7] = 0x00018005;		//BANKCON6
    	p[8] = 0x00018005;		//BANKCON7
    	p[9] = 0x008e07a3;		//REFRESH,HCLK=12MHz:0x008e07a3,HCLK=100MHz:0x008e04f4
    	p[10] = 0x000000b2;		//BANKSIZE
    	p[11] = 0x00000030;		//MRSRB6
    	p[12] = 0x00000030;		//MRSRB7
    }
    
    void sdram_init2(void)
    {
    	unsigned int arr[] = {
    		0x22000000, 	//BWSCON
    		0x00000700, 	//BANKCON0
    		0x00000700, 	//BANKCON1
    		0x00000700, 	//BANKCON2
    		0x00000700, 	//BANKCON3	
    		0x00000700, 	//BANKCON4
    		0x00000700, 	//BANKCON5
    		0x18001, 	//BANKCON6
    		0x18001, 	//BANKCON7
    		0x8404f5, 	//REFRESH,HCLK=12MHz:0x008e07a3,HCLK=100MHz:0x008e04f4
    		 0xb1,	//BANKSIZE
    		 0x20,	//MRSRB6
    		 0x20,	//MRSRB7
    
    		};
    	volatile unsigned int * p = (volatile unsigned int *)0x48000000;
    	int i;
    
    	for (i = 0; i < 13; i++)
    	{
    		*p = arr[i];
    		p++;
    	}
    	
    }
    

    运行结果:
    没有任何输出

    因为我们知道,数组的初始值是保存在rodata段(绝对地址),后面才加载到栈上的。因此在Nor/SRAM上运行sdram_init2函数是需要访问SDRAM上的rodata地址,我们还没拷贝过去,是取不到我们要的数据的。

    展开全文
  •  重定位数据库只能通过symlink方法,因此windows平台无法重定位数据库。为了重定位数据库,应关闭数据库,移动数据库的目录。删除原来的数据库目录,用指向新位置的symlink来代替她,然后启动服务器。  下面用一...

        首先抛出三个问题:   

        1、为什么要移动数据目录的各个部分?

        2、又可以移动什么?

        3、以及怎样进行这些移动?

       一、 MySQL 允许您重定位其中的数据目录或元素。这样做有几个原因:

        1、可以用比缺省定位的文件系统更大的容量在文件系统中放置数据目录;

        2、如果数据目录在繁忙的磁盘上,可以将其放置到较少使用的驱动器上,以平衡物理设备之间的磁盘活动。为了类似的原因,可以将数据库和日志文件放置到不同的驱动器上,或在驱动器之间对数据库进行再分布;

        3、您可以运行多个服务器,并且每个服务器都有属于自己的数据目录。这是一种解决总进程文件描述符限制问题的方法,尤其是不能重新配置系统的核心以得到更高的限制值时。

        4、某些系统将PID文件保存在诸如/var/run的目录中。为了系统运作的一致性,您可以将MySQL PID文件也放在那里。

        二、重定位方法

        有两种对数据目录重定位的方法:

        可以在命令行或在一个选项文件[mysqld]组上,在服务器启动时间制定一个选项;

        可以移动要重定位的内容,然后在原始的位置中做一个指向新位置的symlink (symbolic link,符号链接)

        不过,两种方法都不能为您进行全部的重定位工作。

        您还可以使用缺省数据目录的选项文件my.cnf(该目录编译在服务器中)。笔者不建议使用此文件。如果要重定位数据目录本身,必须保持缺省数据目录的完整性,以便在数据目录中放置一个选项文件,该文件将说明服务器应该在哪里找到“真正”的数据目录!真乱。如果想要用一个选项文件来指定服务器的选项,则最好使用/etc/my.cnf。

       

        三、重定位数据目录

        步骤:

        1、关闭服务器,例如:
        $ mysqladmin –u root -p shutdown
        2、将数据库目录移动到新的位置
        3、然后删除原来的数据库
        4、如果用symlink方法(Unix平台上),例如:
        $ ln –s NEWDIR DATADIR
        DATADIR是标准的数据库目录的位置,也是原来的数据库目录路径。
        如果用起动选项的方法,可以这样启动:
        $safe_mysqld --basedir=/path/to/dir/ & (Unix)
        $mysqld --basedir=x:\datadir\ (Windows)

        如果用选项文件的方法:
        在/etc/my.cnf(Unix)或者c:\my.cnf(Windows)中加入:
        [mysqld]
        datadir=/path/to/dir/

        5、重新启动数据库

        四、重定位数据库

        步骤

        重定位数据库只能通过symlink方法,因此windows平台无法重定位数据库。为了重定位数据库,应关闭数据库,移动数据库的目录。删除原来的数据库目录,用指向新位置的symlink来代替她,然后启动服务器。
        下面用一个实际的例子――备份bigdb――说明这个过程:
        $mysqladmin –u root –p
        $cd DATADIR
        $tar cf bigdb|(cd /var/db;tar xf)
        $mv bigdb bigdb.old
        $ln –s var/db/bigdb .
        $safe_mysqld &

        应该以数据库目录所有者的身份执行这些命令。服务器工作正常之后,可以删除备份目录bigdb.old:
        $rm –rf bigdb.old

        五、重定位状态文件

        状态文件中PID文件、常规日志和更新日志,可以用起动选项或者选项文件的方法重新定位。错误日志由safe_mysqld创建且不能够重新定位,除非编辑safe_mysqld脚本
        为了在另一个位置写状态文件,因关闭服务器,然后用制定新状态文件位置的恰当选项启动他。
        启动选项:
        --pid-file=pidfile PID文件
        --log=logfile 常规日志
        --log-update=updatefile 更新日志

        选项文件
        [mysqld]
        pid-file=pidfile
        log=logfile
        log-update=updatefile

        状态文件的命名规则:
        1、如果以绝对路径指定一个状态文件的名称,则用该路径创建改文件。
        例如,你指定—pid-file=/var/run/mysqld.pid,则该PID文件的就是/var/run/mysqld.pid
        2、如果你只给出文件名,则文件在数据库目录下创建。
        例如,你指定—pid-file=mysqld.pid则该PID文件为DATADIR/mysqld.pid
        3、如果没有给出文件,则状态文件使用缺省的名字。
        这样做将告诉服务器启用状态文件,这对PID文件没有意义,因为服务器总是使用它。例如:
        $safe_mysqld --log --log-update &
        或者,使用选项文件:
        [mysqld]
        log
        log-update

        对于常规日志,将生成DATADIR/hostname.log文件,hostname是运行服务器的主机名。对于更新日志,生成DATADIR/hostname.nnn的顺序文件。
        4、对于更新日志,如果指定一个没有扩展名的更新日志,则MySQL在打开该更新日志是将生成数据的名字。这些名字用.nnn扩展名创建,这里的.nnn是违背已有的更新日志文件使用过的第一个号码(如,hostname.001、hostname.002等等)。可以通过指定明确的扩展名来忽略顺序名字的生成,然后服务器将仅使用您指定的名字。

    展开全文
  • 程序代码如下:(最简单的hello.c) #include <stdio.h> int main() { printf("hello, world!...这是有关可重定位目标文件的结构图(从mooc ppt上所截) 计算机系统基础(一)第周第三讲 让我们...
  • 目录课程作业 课程 课程汇总 作业
  • 开发年,就只剩下这套Java开发体系了 &gt;&gt;&gt; 1、tortoisegit重定位  选择设置      "Git--&gt;远端--&gt;URL"修改,即可
  • 4)对于每个需要重定位的模块,它会解析模块的重定位段,并修改模块在磁盘文件中的代码。 5)将每个模块新的首选基地址写入各个模块磁盘文件中。 所以推荐在构建完所有项目后运行Rebase.exe。 9、...
  • CDPR老总 毕竟CDPR对《赛博朋克2077》的定位年内最优秀的游戏而不仅仅是年度最佳,蠢驴想细细打磨以呈现出更好的品质可以理解。 不过也有玩家把原定4月发售的《2077》跳票至9月与近日另两款游戏改期的事情联系...
  • = runtimeaddr程序本身要重定位 核心程序运行时应该位于 runtimeaddr(reloate addr)或者链接地址 bin文件 1 elf生成bin文件 2 硬件机制启动 3 如果bin文件所在位置 不等于runtimeaddr ,程序本身实现重定位 bin...
  • 快换类型的工具应用很多,在项目中一台机器人可能既要进行取放工作,还要进行焊接工作,需要在焊枪和爪手直接切换,在PS软件中我们将使用Mount和...选择Atc打开重定位对话框,然后选择Atc的Atc_base坐标和机器人的...
  • 程序地址重定位和模块绑定

    千次阅读 2014-05-09 19:36:31
    默认情况下,对于EXE程序而言,windows链接器会将它的首选基地址设置为0X400000(四万),而DLL程序的首选基地址则被设置为0X10000000(1千万),然后链接器将该地址以及一些相关数据和代码的地址写入到PE文件中。...
  • ARM Cortex-M3 内核结构ARM Cortex-M3 处理器简介2.1.1 概述ARM公司成立于上个世纪九年代初,致力于处理器内核研究,ARM 即 Advanced RISC Machines 的缩写,ARM公司本身不生产芯片,只设计内核,靠转让设计许可,...
  • 韦东山嵌入式Linux学习笔记之——代码重定位002_链接脚本的引入 首先修改链接脚本: 注释: 然后修改start.S文件: 在main函数中加入一个全局变量: 结果: 最后说明数据段(....
  • 显然,这次百度“回来”,身上所带的绝不再是过去那种资本市场定位,回港某种程度上也是一次全新的企业价值估机会——虽然百度作为一个整体其发展并未中断,但站在资本市场的角度看,是时候有一个新的“百度”了。...
  • 11月23日,第一届中国卫星导航年会在四川省成都市盛大召开。年会首日,北斗星通旗下企业和芯星通正式发布了最新一代全系统全频厘米级高精度GNSS芯片——和芯星云NebulasⅣ。这颗芯片代表了国内卫星导航芯片的最高...
  • 】 在新的旗舰A卡发布之前,今天我们就来回顾横评一波这年的A卡旗舰,从HD5870到RadeonVII,7代旗舰显卡,让我们一起看看年间A卡性能增长了多少,又为何会被老黄抛离这么远,本次内容转自B站KOL-搞机猛男,由.....
  • switch 总体注解: 程序控制按照expression的值跳转到相应的case标签处。然后程序流程继续通过所有...如果没有与表达式值相匹配的case标签, 那么控制定位到标签为default的语句,如果它存在的话。否则,控制传递给紧
  • 除了这八种,其实还有定位方法,眼看就快失传了,今天小编让失传已久的定位方法出江湖!一、十八种定位方法前八种是大家都熟悉的,经常会用到的1.id定位:find_element_by_id(self, id_)2.name定位:find_...
  • selenium自动化测试之定位一、元素定位二、鼠标事件三、键盘事件四、iframe定位五、select定位六、alert定位七、xpath定位八、css定位九、元素获取、jquery定位十一、js定位 一、元素定位 1、通过id进行定位 find_...
  • 本项目是一个基于百度地图的实时定位项目源码,可以通过网络基站和gps三重定位,位置信息更准确。移动的时候定位信息会跟着变动。...例子大全里也有几个关于gps定位的项目源码。需要的可以自取。
  • 除了这八种,其实还有定位方法,眼看就快失传了,今天小编让失传已久的定位方法出江湖!一、十八种定位方法前八种是大家都熟悉的,经常会用到的1.id定位:find_element_by_id(self, id_)2.name定位:find_...
  • 2.27 18种定位方法总结

    2018-06-14 15:09:00
    除了这八种,其实还有定位方法,眼看就快失传了,今天小编让失传已久的定位方法出江湖! 一、十八种定位方法 前八种是大家都熟悉的,经常会用到的 1.id定位:find_element_by_id(self, id_)2.name定位:...
  • 单片机差分GPS定位系统设计

    千次阅读 多人点赞 2018-03-23 19:50:54
    随着GPS定位的不断发展和普及,用户对GPS定位精度的要求越来越高,单点的GPS定位精度在水平方向上只能达到几米的精度。在实际应用中往往不能满足要求。差分GPS定位技术可以使定位精度达到米级甚至更高精度。购买...
  • 进入二一世纪多年以来,人口老龄化的增长速度加快,独生子女现象也愈演愈烈,同时各种危及到老人孩子的事故层出不穷,如拐卖儿童,老年痴呆症患者迷路走失等,所以他们的安全成为社会尤其是亲人关注的中之。...
  • 除了这八种,其实还有定位方法,眼看就快失传了,今天小编让失传已久的定位方法出江湖! 一、十八种定位方法 前八种是大家都熟悉的,经常会用到的 1.id定位:find_element_by_id(self, id_) 2.name定位:...

空空如也

空空如也

1 2 3 4 5 ... 17
收藏数 325
精华内容 130
关键字:

十重定位