When the range between the source and target of a V7PILongThunk exceeded an int32 we would trigger a relocation out of range error for the R_ARM_MOVT_PREL or R_ARM_THM_MOVT_PREL relocation. This case can happen when linking the linux kernel as it is loaded above 0xf0000000.
There are two parts to the fix.
- Remove the overflow check for R_ARM_MOVT_PREL or R_ARM_THM_MOVT_PREL. The ELF for the ARM Architecture document defines these relocations as having no overflow checking so the overflow check was spurious anyway.
- Use int64_t for the offset calculation, in line with similar thunks so that PC + (S - P) < 32-bits. This results in less surprising disassembly.
References: ELF for the ARM Architecture table 4-11 Static ARM instruction relocations
http://infocenter.arm.com/help/topic/com.arm.doc.ihi0044f/IHI0044F_aaelf.pdf
nit: I prefer to use multiple echo commands instead of using line concatenation, because with line concatenation all lines are concatenated to a single very long line, and if something goes wrong, this test would print out a very long line to the terminal.
Thus, I usually do something like this: