IAR 重定位失败错误

Posted

技术标签:

【中文标题】IAR 重定位失败错误【英文标题】:IAR Relocation failed error 【发布时间】:2012-10-25 22:33:42 【问题描述】:

有一个编译成功的项目链接并在设备上运行。 但是在告诉链接器它应该将应用程序代码的一部分放到 ROM 内存而不是 SDRAM 之后,我在链接步骤中收到以下错误:

错误[Lp002]:重定位失败:值超出范围或非法: 0x60000545 种类:R_ARM_PREL31[0x2a] 位置:0xa0000030 模块:I:\Project\Debug\Obj\fileOper.o 部分:128(.ARM.exidx) 偏移量:0x0 目标:0x00000574 “SECTION_FILEOP_87” 模块:I:\Project\Debug\Obj\fileOper.o 部分:104(SECTION_FILEOP) 偏移量:0x4f4

我已阅读 IAR 的 C/C++ 指南。但它没有提供关于这个错误的足够好的解释。所以即使阅读手册我也无法得到这个错误的原因。任何人都可以帮助解决这个问题吗? 实际上 IAR C/C++ 开发人员指南说:

对于每条不能正确重定位的指令,ILINK 将 产生重定位错误。这可能发生在指令中 目标遥不可及或属于不兼容的类型,或者对于许多人来说 其他原因。 然后它提供了一个错误作为示例,这与我的情况不同。

编辑 1:我创建了一个重现相同错误的小项目,它仅包含 fileOper.cpp 和 main.cpp 文件。

ICF 文件用于告诉链接器如何将节放入内存:

定义符号 intvec_start = 0x10000000;

/-内存区域-/

/-FLASH ROM-/

定义符号FLASH_ROM_start = 0x00000000;

定义符号FLASH_ROM_end = 0x0007FFFF;

/*内部内存*/

定义符号 RAM_start = 0x10000000;

定义符号 RAM_end = 0x10017FFF;

/*SDRAM*/

定义符号 SDRAM_start = 0xA0000000;

定义符号 SDRAM_end = 0xA1FFFFFF;

/-尺寸-/

定义符号 size_stack = 0x4000;

定义符号 size_heap = 0x2000;

定义内存mem size = 4G;

define region FLASH_region = mem:[从FLASH_ROM_start到 FLASH_ROM_end];

define region RAM_region = mem:[从 RAM_start 到 RAM_end];

define region SDRAM_region = mem:[从 SDRAM_start 到 SDRAM_end];

定义块 CSTACK 对齐 = 8, size = size_stack ;

定义块 HEAP 对齐 = 8, size = size_heap ;

使用打包复制初始化 = zeros readwrite ;

不要初始化 section .noinit ;

地址 mem: intvec_start section .intvec ;

放置在 FLASH_region readonly section .cstartup 的开头;

放置在 RAM_region block CSTACK ;

放置在 SDRAM_region 只读

除了readonly section FILEOP;

放置在 SDRAM_region 读写 ;

放置在 SDRAM_region 块 HEAP;

放在 FLASH_region readonly section FILEOP ;

fileOper.cpp: 我已经更改了它,但它仍然重现相同的错误。

#include "fileOperbug.h"
#include <string>

char *fgets( char *str, int num, std::string *stream ) 

  char *pointer = 0;
  return pointer;


std::string *fopen(const char *name, const char *mode) 
  std::string *str = new std::string();
  str->assign("");
  return str;

【问题讨论】:

这个***问题的接受答案是否有帮助:[如何修复“[Lp002]:IAR ARM工具重定位失败?][1] [1]:***.com/questions/1208312/… 我已经看过了。它没有帮助。原因不同,但错误是一样的。 您能否发布您所做的更改的详细信息以告诉链接器它应该将部分应用程序代码放入 ROM 中?或许你也可以贴出fileOper.c的相关部分? @MichaelBurr 我已经更新了这个问题。 fileOper.cpp 文件被标记为 FILEOP 部分。 【参考方案1】:

我已经解决了这个问题。 使用 IAR Embedded Workbench 时: 项目选项 -> C/C++ 编译器 -> 语言 1 选项卡。 在“C++ 方言”中,有一个名为“有例外”的复选框被选中。 选中“有例外”复选框时,会发生链接阶段的错误。 所有使用异常的代码都必须加载到 ROM。否则“有例外”应该被取消选中。

【讨论】:

以上是关于IAR 重定位失败错误的主要内容,如果未能解决你的问题,请参考以下文章

运行时 gcc 重定位错误

“kernelUD 中的错误:至少需要 5 次重定位才能适应主范围”,但每组的重定位数超过 5 次

使用 extern 时 gcc 的重定位错误

第16章:基址重定位

QT“重定位错误”/“没有可用的版本信息”运行时错误

“重定位 R_X86_64_32S 反对”链接错误