Relocation truncated to fit

Hi there,

I get an error message when I try to build my program:

E:\Temp\ccIyLSlA.ltrans0.ltrans.o: In function main': <artificial>:(.text.startup+0x738): relocation truncated to fit: R_AVR_7_PCREL against no symbol’
collect2.exe: error: ld returned 1 exit status
*** [.pio\build\megaatmega2560\firmware.elf] Error 1

I’ve found a “solution” but I don’t know if it’s applicable to PlatformIO !

I’m with an Arduino Mega 2560.
I got this error when I run this:

for(int i = 2; i >= 0; i --)
{
receivedChar = HC12.read();
if(isDigit(receivedChar))
{
module_id += (receivedChar-‘0’) * pow(10, i);
}
else
{
//Serial.print(“This character is not a digit: “);
//Serial.print(receivedChar);
//Serial.print(” (0x”);
//Serial.print(receivedChar, HEX);
//Serial.println(“)”);
isWrongFormat = true;
}
}

But it compiles fine when I uncoment Serial.print lines :thinking:
It’s not the full program because my program has 400 lines, and I don’t know if we can reproduce it with a little script…

Thanks !

(Another request: Will you support Debugging for Arduino Mega 2560 ?)

So have you tried build_flags = -mrelax in the platformio.ini?

Same behaviour !

But thanks for the reply :slight_smile:

The problem is that you’re calling in lib-math code with the pow() function which cause the linker to take some symbols from libgcc and not libm, and that code exhibits the error.

See AVR relocation truncations workaround - Wikistix

The presented workaround is to change the order of the linker flags to make libm be loaded first after libgcc.

Why -mrelax doesn’t work is beyond me. Maybe it’s a really old compiler version and you need

build_unflags = -mshort-calls

Anyway for your code I would highly suggest to not call into pow(). Since i only every has values from 2 to 0, you can just hardcode the result of the pow() call to 100, 10 and 1.

const int pow_res[3] = { 1, 10, 100};
for(int i = 2; i >= 0; i --)
{
receivedChar = HC12.read();
if(isDigit(receivedChar))
{
module_id += (receivedChar-'0') * pow_res[i];
}
else
{
//Serial.print(“This character is not a digit: “);
//Serial.print(receivedChar);
//Serial.print(” (0x”);
//Serial.print(receivedChar, HEX);
//Serial.println(")");
isWrongFormat = true;
}
}
1 Like

I didn’t understood all, but your solution is working !

Thanks :slight_smile: