We are trying to link a 3rd party library compiled using the ARM/IAR compiler into our project, which we compile using the GNU arm-elf toolchain. ld fails to link the 3rd party library, and spits out warnings: "warning: internal error: unsupported relocation error" The ld appears to be complaining because the IAR compiler produces instructions which must be relocated using R_ARM_THM_PC8, but it appears that R_ARM_THM_PC8 isn't implemented in binutils. I was able to confirm this by recompiling binutils with some printf statements describing the unsupported relocation method.
Created attachment 3898 [details] Add support for reloc #8
Hi Owen, I have uploaded a possible patch to fix this problem - please could you try it out for me ? Not having any binaries containing the R_ARM_THM_PC8 reloc makes testing locally impossible, but I think that I have implemented it correctly. Cheers Nick
Hi Nick, I tried out the patch, but it doesn't appear to work correctly. GNU ld still outputs warnings when attempting to link the two libraries. We get the following warnings: libecc.a(tk-aes-e.obj): In function `tkAesSetupEnc': c:\IAR_work\mce_release\src\aes\tk-aes-e.c:(.text+0x98): relocation truncated to fit: R_ARM_THM_PC8 against `.text_9' libecc.a(tk-aes-e.obj): In function `aesEnc': c:\IAR_work\mce_release\src\aes\tk-aes-e.c:(.text+0x416): relocation truncated to fit: R_ARM_THM_PC8 against `.text_11' I downloded a copy of the ARM/ELF specification, and it shows that the R_ARM_THM_PC8 appears to be a special case for computing the initial addend. I'm not sure if the submitted patch takes this into account. Thanks, Owen (In reply to comment #2) > Hi Owen, > > I have uploaded a possible patch to fix this problem - please could you try it > out for me ? > > Not having any binaries containing the R_ARM_THM_PC8 reloc makes testing > locally impossible, but I think that I have implemented it correctly. > > Cheers > Nick >
Subject: RE: R_ARM_THM_PC8 Relocation Not Implemented in elf32-arm.c Owen, Nick, et. al., I've been working towards the same objective and stumbled across your post. I tried Nick's fix of 4/21 and had similar results. I believe that there is an additional problem. If you go to the HOWTO() macro for R_ARM_THM_PC8 (elf32-arm.c, line 235), it shows a shift count of one. ARM's documentation shows that the R_ARM_THM_PC8 relocation is only used for an LDR(3) instruction, which uses a shift count of two: Syntax LDR <Rd>, [PC, #<immed_8> * 4] where: <Rd> Is the destination register for the word loaded from memory. PC Is the program counter. Its value is used to calculate the memory address. Bit 1 of the PC value is forced to zero for the purpose of this calculation, so the address is always word-aligned. <immed_8> Is an 8-bit value that is multiplied by 4 and added to the value of the PC to form the memory address. I haven't had a chance to rebuild and test it with a shift count of two. I don't subscribe to the mailing list, but if you are interested in how it comes out, email me at jays at spectralogic dot com and I will let you know. I'd ask that you do the same if you find anything out. Thanks for the suggestions so far, and good luck. Jay
Subject: R_ARM_THM_PC8 Relocation Not Implemented in elf32-arm.c Some thoughts: I'm now linking an IAR object file that used to produce the same type of errors that Owen had. I made my own changes to the "case" handler that seem logical to me, but I didn't try very hard to use the version that Nick posted, so I can't say whether or not his version would work. It looks like there were at least two distinct problems, and likely more. The first, of course, is that the linker didn't handle the R_ARM_THM_PC8 case. The second is the handling of overflows. Also (as mentioned above), I'm not sure that the way shifts were handled was correct. The IAR compiler apparently generates "signed" offsets in the instructions, even though the offset used by ldr(3) is specified as unsigned. Their object files typically contain an offset of 0xff to start with, and to which the relocation displacement is added. This always results in an overflow when interpreted by arm32-elf ld. They may do this for convenience, so that the relocation entry is relative to the beginning of the instruction, not the pc register at the time of execution. I'm not sure what, if any, side effects may result from this practice. There may be none. It still looks scary. I think that they may also do this with other relocations. I also get overflow errors with the R_ARM_THM_CALL relocation. I've disabled these with a "#if 0" in my build, and it now builds code that looks like it will run okay. The case statement for R_ARM_THM_PC8 relocation now reads: case R_ARM_THM_PC8: /* XXXjs 5/04/2009 Support thumb ldr(3) instruction, ignore overflow. */ { bfd_vma insn; bfd_signed_vma relocation; insn = bfd_get_16 (input_bfd, hit_data); if (globals->use_rel) addend = (insn & 0x00ff) << 2; signed_addend = addend; relocation = value + signed_addend; relocation -= (input_section->output_section->vma + input_section->output_offset + rel->r_offset); value = abs (relocation); insn = (insn & 0xff00) | (value >> 2); bfd_put_16 (input_bfd, insn, hit_data); return bfd_reloc_ok; } Also, I disable testing and setting the overflow flag in the handler for R_ARM_THM_XPC22, R_ARM_THM_CALL and R_ARM_THM_JUMP24. I presume that the errors that I've seen in R_ARM_THM_CALL are caused by the same situation as R_ARM_THM_PC8, although I haven't put the effort into dumping these out in detail. Jay
Created attachment 3924 [details] revised form of previous patch
Hi Owen, OK, I have uploaded a revised patch based Jay's suggestion. Please give it a go and let me know if it works this time. I am not comfortable with suppressing the overflow warnings for the other relocations however. The checks are correct and those relocs are being processed in the way that ARM specifies. I think that it would be better to find out exactly why the overflows are occurring an then determine if the IAR compiler is at fault or if there is some kind of gcc specific assumption in the linker. Would it be possible for you to post a simple IAR compiled object file that generates these overflowing relocs ? Cheers Nick
Created attachment 3926 [details] IAR object producing error. I've uploaded some sample code that can be used to reproduce the bug and to test the fix. The object file (test-pc8.o) was compiled using an evaluation copy of IAR's C compiler.
Hi Owen, Thanks for the test case, and sorry for the long delay in getting back to this bug. Using that test case and the second version of the patch I created I get a working executable (which prints 0x00000000) and no linker warnings about relocation overflows. So I am going to check in the patch and close this PR. If you find that there is still a problem, please feel free to reopen the PR and upload a new test. Cheers Nick