Error: relocation truncated to fit

Go To Last Post
11 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Just for the record.

When I compile my project I get an error in the assembler file:
relocation truncated to fit: R_AVR_7_PCREL against 'no symbol'

I get the error in two different parts of the assembler code, and it is always on a brne instruction.

	cpi R30, RECEIVE
	brne Check_State_Is_IDLE	; this line causes the error
State_RECEIVE:
	...
	ldi R16, 8
	cp BitCounter, R16
	brne INT1_vect_End	; this line causes the error
State_RECEIVE_Store_byte:
	...

Yes the lables State_RECEIVE and INT1_vect_End exists, I use them in other parts of the assembler code and they work when replacing the brne. I have also tried to rename the lables but it didn't work. The problem is that the branch instructions can only branch a maximum of +/- 64 words.

The solution is to use rjmp instead which can jump +/-2k words (or jmp if rjmp is not enough):

	cpi R30, RECEIVE
	;brne Check_State_Is_IDLE	; this line causes the error
	breq State_RECEIVE
	rjmp Check_State_Is_IDLE
State_RECEIVE:
	...
	ldi R16, 8
	cp BitCounter, R16
	;brne INT1_vect_End	; this line causes the error
	breq State_RECEIVE_Store_byte
	rjmp INT1_vect_End
State_RECEIVE_Store_byte:
	...

I hope this will save some headache for someone.

/COLA

Last Edited: Tue. Jul 31, 2007 - 01:47 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

In this case it may not actually a GCC bug at all, but rather a limitation of the AVR architecture. (Albeit, the error message you're getting is somewhat cryptic.)

How many words of code separate the BRNE instruction from the target label? The BRNE instruction (like all of the AVR's conditional branching instructions) can only branch a maximum of +/-64 words.

The bug report you've referenced is actually another example of a similar limitation in the AVR architecture -- a portion of avr-libc was blindly using RJMPs and RCALLs to navigate to other library functions, although the actual targets' relative offsets were not fixed until link time. At that point, the destination address occasionally turned out to be beyond the +/-2048 limits of the RJMP/RCALL instructions.

[edit: 2048, not 4096, dummy!]

Last Edited: Tue. Jul 31, 2007 - 01:56 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You are correct, it is the limitation in the branch that causes the error. I'll edit my first post with this new information.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello,

I'm trying to compile some assembler code that uses the AES engine of the XMEGA256A3U, using something like the following:

aes_encrypt:
   // do something ...

   // Z points to data to be used by AES
   ld r22, Z+
   sts AES_STATE, r22
   ... // repeat the above two instructions many times

   // some more code here...

   jmp aes_encrypt

What I observed is that for a short number of repetitions of the two ld/sts instructions, the code compiles fine. However, when I use a larger number (16) of repetitions, I get the error:

Quote:

In function `aes_encrypt':
(.text+0xd2): relocation truncated to fit: R_AVR_7_PCREL against `no symbol'
collect2: ld returned 1 exit status

I'm using avr-gcc 4.5.1 (AVR_8_bit_GNU_Toolchain_3.3.2_485).

The error appears when using both jmp and rjmp and is very easy to reproduce by adding/removing ld/sts instructions.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

I'm using avr-gcc 4.5.1 (AVR_8_bit_GNU_Toolchain_3.3.2_485).

Any reason for using such old tools?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

That's what I had installed from last year and did not bother updating as they have been working fine until now.

Is there any known issue with those tools?

Do you have any idea what could be the problem?

Thanks.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Do you have any idea what could be the problem?


Perhaps show the full failing loop.

If I had to guess, there are some conditional jumps of some type in "do something" and "more code" that don't reach any more.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ok, so I've tried avr-gcc 4.8.1 (I took the .tar.gz toolchain for 8bit AVRs from the AVR website):

avr-gcc --version
avr-gcc (AVR_8_bit_GNU_Toolchain_3.4.4_1229) 4.8.1

However, I still get the same error:

In function `aes_encrypt':
(.text+0xd2): relocation truncated to fit: R_AVR_7_PCREL against `no symbol'
collect2: error: ld returned 1 exit status
make: *** [xmega_pa.elf] Error 1

Here is a longer version of the loop, which basically reads data from RAM (in the hope of perform an encryption), then loops back for more data
(r20,r21 contain data length, r26,r27 is a counter).

.global asm_aes
asm_aes:
    // ... some code here to save/clear registers,
    // and to copy key bytes from memory to r0-r15

aes_encrypt:
    // check if we have loaded all the data, if so end
    cp r20, r26
    cpc r21, r27
    brcs aes_end

    // Reset control: set mode to encryption, disable XOR, stop any encryption
    sts AES_CTRL, r0

    // Reset AES state ready interrupt flag
    lds r22, AES_STATUS
    sbr r22, AES_SRIF_bm
    sts AES_STATUS, r22

    // reset AES registers / counters
    lds r22, AES_CTRL
    sbr r22, AES_RESET_bm
    sts AES_CTRL, r22
wait_aes_reset:
    lds r22, AES_CTRL
    sbrc r22, AES_RESET_bp
    jmp wait_aes_reset

    // load AES key into KEY register
    sts AES_KEY, r0
    sts AES_KEY, r1
    sts AES_KEY, r2
    // ... more sts AES_KEY here for 16 bytes

    // below are the trouble makers
    // having more than 3-4 pairs of ld/sts
    // produces the error
    ld r22, Z+
    sts AES_STATE, r22
    ld r22, Z+
    sts AES_STATE, r22
    ld r22, Z+
    sts AES_STATE, r22
    ld r22, Z+
    sts AES_STATE, r22
    // more of these pairs here, to load 16 bytes

    // normally there are some instructions here
    // to actually perform the encryption and
    // store the results, but I commented that out
    // to identify the bug.
    // So the program is as shown here

    // increment data count by 16
    // note that I get same error
    // regardless of use of jmp or rjmp here
    adiw r26, 16
    jmp aes_encrypt

aes_end:
    // pop r15
    // ... more pops here
    
    out _SFR_IO_ADDR(SREG), r18
    pop r18
    ret
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

brcs aes_end


So, how far is it to the destination? Does that distance change when the loop is unrolled further? [rhetorical question]

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Dear theusch,

You got it right, thank you very much. Indeed, that line was the problem. Looking again at the first post in this thread it is clear that I had the exact same issue, but I was focusing on the wrong instruction.
As a feedback, I think it would be great if avr-gcc could actually point to the trouble line, in this case the "brcs aes_end", rather than the overall assembly function.

In any case, I rewrote that part of code as follows, and now compiles fine (as I said, very similar issue to the one in the first post):

.global asm_aes 
asm_aes: 
    // ... some code here to save/clear registers, 
    // and to copy key bytes from memory to r0-r15 
aes_encrypt:
    // check if we have loaded all the data, if so end
    cp r20, r26
    cpc r21, r27
    brcc aes_reset_control
    rjmp aes_end

aes_reset_control:
    sts AES_CTRL, r0    ; 2 clock cycles
    // .. rest of code here ...

Thanks again.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I will try to make it clear there is nothing wrong but

Quote:
relocation truncated to fit: R_AVR_7_PCREL against 'no symbol'
Is not the best error text!

But if you look at it from the compiler/linker point of view it does, it will only look after a label it can reach, and in that view there is 'no symbol' with the correct name.