AT91SAM7x:可能由链接器引起的DisASM混乱

时间:2012-08-27 11:27:19

标签: c linker thumb arm7

我使用Eclipse和Yagarto工具链(非eabi,GCC 4.7.1)编程ARM 7芯片(Atmel的AT91SAM7X256), 这个项目的目标是将一个引导加载程序放在一个已定义的ROM范围内,稍后将其复制到RAM中(参见下图,ROM地址0x104000,应用程序代码启动是固定的)。 按预期工作......直到您调试程序(SEGGER J-Link和GDB)。

内存结构图像显示在此处:http://i47.tinypic.com/2vb6f7o.jpg(抱歉,无法在此处发布图片)。

问题始于链接的.text部分,主要使用以下方法,它启动整个.text部分(正确): (由 objdump -e -h common / exhandler.o> exhandler.lst 反汇编的C代码)

   00000000 <EXHANDLER_printHex>:
      0:    e92d4038    push    {r3, r4, r5, lr}
      4:    e1a05000    mov r5, r0
      8:    e3a0401c    mov r4, #28
      c:    e1a03435    lsr r3, r5, r4
     10:    e203000f    and r0, r3, #15
     14:    e3500009    cmp r0, #9
     18:    c2800027    addgt   r0, r0, #39 ; 0x27
     1c:    e2800030    add r0, r0, #48 ; 0x30
     20:    ebfffffe    bl  0 <DBGUNIT_sendCharacter>
     24:    e2444004    sub r4, r4, #4
     28:    e3740004    cmn r4, #4
     2c:    1afffff6    bne c <EXHANDLER_printHex+0xc>
     30:    e8bd4038    pop {r3, r4, r5, lr}
     34:    e12fff1e    bx  lr

反汇编链接的ELF文件时,代码输出为:(错误

00104000 <EXHANDLER_printHex>:
  104000:   e92d4038    push    {r3, r4, r5, lr}
  104004:   5000        str r0, [r0, r0]
  104006:   401ce1a0    andsmi  lr, ip, r0, lsr #3
  10400a:   e3a0        b.n 10474e <ADCDAC_get16BitChannel+0x82>
  10400c:   e1a03435    .word   0xe1a03435
  104010:   e203000f    and r0, r3, #15
  104014:   e3500009    cmp r0, #9
  104018:   0027        movs    r7, r4
  10401a:   0030c280    eorseq  ip, r0, r0, lsl #5
  10401e:   e280        b.n 104522 <CSTARTUP_lowLevelInit+0xfa>
  104020:   eb003367    bl  110dc4 <__DBGUNIT_sendCharacter_from_arm>
  104024:   4004        ands    r4, r0
  104026:   e244        .short  0xe244
  104028:   e3740004    cmn r4, #4
  10402c:   1afffff6    .word   0x1afffff6
  104030:   e8bd4038    pop {r3, r4, r5, lr}
  104034:   e12fff1e    .word   0xe12fff1e

虽然字节序列保持不变,但这些ASM命令的解释不同。 我的假设是在链接过程中Thumb和ARM代码出了问题。

我的链接文件:

/*
 * Linker script for AT91SAM7X256 with internal bootloader.
 *
 * Bootloader is put into first 16 kB of Flash, then loaded to RAM and will connect by DBGU UART interface
 * (115 kBaud, no parity bit).
 */
OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
OUTPUT_ARCH(arm)

MEMORY
{
  flash-boot (rx) : ORIGIN = 0x00100000, LENGTH = 16K       /* read-only flash memory for boot-loader and startup sequence */
  flash-app  (rx) : ORIGIN = 0x00104000, LENGTH = 240K      /* read-only flash memory for application */
  ram (rwx)       : ORIGIN = 0x00200000, LENGTH = 64K       /* read/write S-RAM memory */
}


/* Stack is growing backwards, starting at end of RAM and is aligned at 4 byte. First entry in stack will
   use RAM address 0x20fffc to 0x20ffff. */
_estack = 0x20fffc; 




SECTIONS
{
  . = 0;


    /* Elements required during start-up sequence. Must be first elements in ROM. */
    .startup : {
        obj/sys/startup.o(.text .rodata)
        . = ALIGN(4);
        obj/sys/swi_handler.o(.text .rodata)
        . = ALIGN(4);
        _estartup = .;                          /* end of startup segment */
    } >flash-boot

    .ramvect : {                        /* used for vectors remapped to RAM */
        __ram_start = .;
        . = 0x40;
    } >ram

    /* Further elements for bootloader, which are placed into RAM for allowing chip flash. */   
    .bootloader : {
        _bootloader = .;        /* RAM */
        obj/comm/dbgunit.o(.text .rodata)
        . = ALIGN(4);
        _ebootloader = .;       /* RAM */
    } >ram AT>flash-boot

    /* Code starts at fixed address in flash (application start) and is kept there. */
    .text : {
        CREATE_OBJECT_SYMBOLS
        *(.text .text.* .gnu.linkonce.t.*)         /* remaining code */
        *(.plt)
        *(.gnu.warning)
        *(.glue_7) *(.glue_7t)  /* stub for code which glues together ARM7 and Thumb code */

        . = ALIGN(4);
        *(.rodata .rodata.* .gnu.linkonce.r.*)  /* read-only data (constants) */        
        *(.ARM.extab* .gnu.linkonce.armextab.*)
        *(.gcc_except_table)

        *(.init)
        *(.fini)

        PROVIDE_HIDDEN (__preinit_array_start = .);
        KEEP (*(.preinit_array))
        PROVIDE_HIDDEN (__preinit_array_end = .);
        PROVIDE_HIDDEN (__init_array_start = .);
        KEEP (*(SORT(.init_array.*)))
        KEEP (*(.init_array))
        PROVIDE_HIDDEN (__init_array_end = .);
        PROVIDE_HIDDEN (__fini_array_start = .);
        KEEP (*(.fini_array))
        KEEP (*(SORT(.fini_array.*)))
        PROVIDE_HIDDEN (__fini_array_end = .);

        . = ALIGN(4);
    } >flash-app

     /* .ARM.exidx is sorted, so has to go in its own output section.  */
    .ARM.exidx : {
        __exidx_start = .;
        *(.ARM.exidx* .gnu.linkonce.armexidx.*)
        __exidx_end = .;
    } >flash-app

    _etext = .;

    /* Initialized .data sections go into RAM. */ 
    .data : 
    {
        _data = .;                      /* create a global symbol marking the start of the .data section (RAM) */
        *(.ramsection .ramsection.*)
        . = ALIGN(4);
        *(.data .data.* .gnu.linkonce.d.*)
        . = ALIGN(4);
        _edata = .;                     /* define a global symbol marking the end of the .data section  */
    } >ram AT>flash-app                         /* put all the above into RAM */


    /* Uninitialized .bss sections go into RAM. */
    .bss (NOLOAD):                      
    {
        __bss_start__ = .;              /* define a global symbol marking the start of the .bss section */
        *(.bss .bss.* .gnu.linkonce.b.*)
        *(COMMON)
        . = ALIGN(4);
    } > ram                             /* put all the above in RAM (it will be cleared in the startup code */

    _bss_end        = . ;               
    __bss_end__     = . ;               /* define a global symbol marking the end of the .bss section */    



    . = ALIGN(4);                       /* advance location counter to the next 32-bit boundary */
    _end = .;                           /* define a global symbol marking the end of application RAM */
    PROVIDE (end = .);


    /* DWARF debug sections.
    * Symbols in the DWARF debugging sections are relative to the beginning
    * of the section so we begin them at 0.
    */
    /* DWARF 1 */
    .debug          0 : { *(.debug) }
    .line           0 : { *(.line) }
    /* GNU DWARF 1 extensions */
    .debug_srcinfo  0 : { *(.debug_srcinfo) }
    .debug_sfnames  0 : { *(.debug_sfnames) }
    /* DWARF 1.1 and DWARF 2 */
    .debug_aranges  0 : { *(.debug_aranges) }
    .debug_pubnames 0 : { *(.debug_pubnames) }
    /* DWARF 2 */
    .debug_info     0 : { *(.debug_info .gnu.linkonce.wi.*) }
    .debug_abbrev   0 : { *(.debug_abbrev) }
    .debug_line     0 : { *(.debug_line) }
    .debug_frame    0 : { *(.debug_frame) }
    .debug_str      0 : { *(.debug_str) }
    .debug_loc      0 : { *(.debug_loc) }
    .debug_macinfo  0 : { *(.debug_macinfo) }
    /* SGI/MIPS DWARF 2 extensions */
    .debug_weaknames 0 : { *(.debug_weaknames) }
    .debug_funcnames 0 : { *(.debug_funcnames) }
    .debug_typenames 0 : { *(.debug_typenames) }
    .debug_varnames  0 : { *(.debug_varnames) }
    .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) }
    .ARM.attributes 0 : { KEEP (*(.ARM.attributes)) }
    /DISCARD/ : { *(.note.GNU-stack)  }

}

任何人都可以在链接器文件中发现错误或给我一个提示,在哪里查看下一步?

感谢您的阅读, PAULE

PS:这是ELF文件部分标题的一些输出,因此很明显没有重叠的部分。

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .startup      0000033c  00100000  00100000  00008000  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .ramvect      00000040  00200000  00200000  00030000  2**0
                  ALLOC
  2 .bootloader   000001cc  00200040  0010033c  00010040  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  3 .text         0000ce08  00104000  00104000  00014000  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  4 .ARM.exidx    000000f0  00110e08  00110e08  00020e08  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  5 .data         0000129c  00200210  00110ef8  00028210  2**3
                  CONTENTS, ALLOC, LOAD, DATA
  6 .bss          000008c8  002014ac  00112194  000294ac  2**2
                  ALLOC
  7 .debug_aranges 000009b8  00000000  00000000  000294b0  2**3
                  CONTENTS, READONLY, DEBUGGING
  8 .debug_info   0002166d  00000000  00000000  00029e68  2**0
                  CONTENTS, READONLY, DEBUGGING
  9 .debug_abbrev 00006cb4  00000000  00000000  0004b4d5  2**0
                  CONTENTS, READONLY, DEBUGGING
 10 .debug_line   00007db7  00000000  00000000  00052189  2**0
                  CONTENTS, READONLY, DEBUGGING
 11 .debug_frame  0000232c  00000000  00000000  00059f40  2**2
                  CONTENTS, READONLY, DEBUGGING
 12 .debug_str    0000682a  00000000  00000000  0005c26c  2**0
                  CONTENTS, READONLY, DEBUGGING
 13 .debug_loc    00016421  00000000  00000000  00062a96  2**0
                  CONTENTS, READONLY, DEBUGGING
 14 .comment      00000011  00000000  00000000  00078eb7  2**0
                  CONTENTS, READONLY
 15 .ARM.attributes 0000002e  00000000  00000000  00078ec8  2**0
                  CONTENTS, READONLY
 16 .debug_ranges 00000968  00000000  00000000  00078ef6  2**0
                  CONTENTS, READONLY, DEBUGGING

1 个答案:

答案 0 :(得分:0)

看来,错误的反汇编代码是反汇编程序的问题,它无法区分混合目标文件中的ARMThumb编译代码。

方法EXHANDLER_printHex()已在ARM模式下编译,但被错误地解译为Thumb代码。

结论:DisASM的代码无法解决问题。