Ozone script: Resolving vector address from elf file fails with GCC 5.0

    This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

    • Ozone script: Resolving vector address from elf file fails with GCC 5.0

      Hello,

      I'm having an issue debugging using an elf file compiled and linked with GNU ARM Embedded toolchain using GCC >= 5 (). The issue is not present in GNU ARM toolchain using GCC 4.9.

      I'm not sure if this is the right forum, but at least I can share my findings with you.

      Our flash layout reserves 0x8000 bytes at the start of the flash (0x08000000) for a bootloader.

      Source Code

      1. ...
      2. bootloader (NOLOAD) :
      3. {
      4. _bootloader_start = .;
      5. /* Bootloader reservation */
      6. . = ORIGIN(flash) + _application_offset;
      7. } >flash
      8. .vectors :
      9. {
      10. . = ALIGN(0x100);
      11. _applicationBegin = .;
      12. KEEP(*(.vectors)) /* Startup code */
      13. } >flash
      14. ...
      Display All

      When debugging the application directly (ie. the bootloader is not executed) we expect the PC to be set to the application Reset_Handler function in the Ozone Event handler AfterTargetDownload()

      Source Code

      1. void AfterTargetDownload (void) {
      2. unsigned int SP;
      3. unsigned int PC;
      4. unsigned int VectorTableAddr;
      5. VectorTableAddr = Elf.GetBaseAddr();
      6. if (VectorTableAddr == 0xFFFFFFFF) {
      7. Util.Log("Project file error: failed to get program base");
      8. } else {
      9. SP = Target.ReadU32(VectorTableAddr);
      10. Target.SetReg("SP", SP);
      11. PC = Target.ReadU32(VectorTableAddr + 4);
      12. Target.SetReg("PC", PC);
      13. }
      14. }
      Display All
      However, both PC and SP is set to zero.

      Ozone console:
      Elf.GetBaseAddr();
      Target.SetReg ("SP", 0x0);
      Target.SetReg ("PC", 0x0);

      Here's a dump from readelf()

      Source Code

      1. arm-none-eabi-readelf -h artifacts\app_gcc_5.2.elf
      2. ELF Header:
      3. Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
      4. Class: ELF32
      5. Data: 2's complement, little endian
      6. Version: 1 (current)
      7. OS/ABI: UNIX - System V
      8. ABI Version: 0
      9. Type: EXEC (Executable file)
      10. Machine: ARM
      11. Version: 0x1
      12. Entry point address: 0x803e859
      13. Start of program headers: 52 (bytes into file)
      14. Start of section headers: 15229296 (bytes into file)
      15. Flags: 0x5000400, Version5 EABI, hard-float ABI
      16. Size of this header: 52 (bytes)
      17. Size of program headers: 32 (bytes)
      18. Number of program headers: 7
      19. Size of section headers: 40 (bytes)
      20. Number of section headers: 41
      21. Section header string table index: 38
      Display All
      I'm no expert on elf files, but it seems that "Flags" is missing the "has entry point" (Flags should have been 0x5000402) which might cause Elf.GetBaseAddr() to return 0. When using GCC 4.9 using the same source/linker script "has entry point" is set.

      As a workaround, I hardcoded VectorTableAddr to 0x08008000 in the Ozone project file, but it would be nice to know if I am doing anything wrong or missing an obvious gotcha.
    • Hello,

      Thank you for your inquiry.
      It is possible that some markers are missing from the elf files depending on the compiler version.
      Could you provide the elf file for reproduction?

      Best regards,
      Nino
      Please read the forum rules before posting: Forum Rules

      Keep in mind, this is not a support forum. Its main purpose is user to user interaction.
      Our engineers will try to answer your questions between their projects if possible but this can be delayed by longer periods of time.
      Should you be entitled to support contact us per e-mail.
      Alternatively our support system can be used as well: segger.com/ticket/
    • Hello,

      Thank you for providing the elf file.
      There seems to be a misconception on how the Elf.GetBaseAddr(); command works. We have addressed this in the next revision of the manual so it is more clear.
      Esentially GetBaseAddr will simply return the lowest address of your elf image. This can be the beginning of a vector table but can also be some kind of bootloader or other data.

      To get the value of the Reset_Handler PC you can use ELF.GetEntryPointPC instead.

      I hope this is more clear now.

      Best regards,
      Nino
      Please read the forum rules before posting: Forum Rules

      Keep in mind, this is not a support forum. Its main purpose is user to user interaction.
      Our engineers will try to answer your questions between their projects if possible but this can be delayed by longer periods of time.
      Should you be entitled to support contact us per e-mail.
      Alternatively our support system can be used as well: segger.com/ticket/