bintutils 2.23 is releasing soon.
After some investigations it appears that the libc.so is generated with a .interp section size of 0x2000 bytes with the dynamic linker path starting at at offset 0x1000. When the final binary is linked, the linker script will set the .interp size to 0x1000, hence the "cannot move location counter backwards" error. I ran a git bisect on the binutils repo and found that the commit triggering the issue is: d60ea88bc909c45c0542d9fb055eb5fc1102f422 I will investigate it further.
The issue appeared because the .interp section in partial linked objects was set to 0x1000 even though it contained no data. So, when the final linking was done, the linker script for the executable set the .interp section size to 0x1000 too. Hence, the linker couldn't fit all the data in various .interp sections in one final 0x1000 bytes section. Since we need the .interp section to have 0x1000 bytes only for the final binary, we can safely ignore setting an .interp section size for the partial linked objects (those linked with -r or -rU). I did some more investigations on why it works on binutils 2.22 and it turns out that the 2.22 linker created the .interp section in the final binary correctly but it was missing the dynamic loader path. Due to the fact that the relocate_sdk.py script went through all the binaries writing the new path to the dynamic loader, the issue remained hidden. Binutils 2.23 change I mentioned triggered the issue. Patch under review on the mailing list.
Bitbake now uses the binutils 2.23.1 (according to "bitbake -g binutils") Verified in master: 5b658729eff73963262dda4d6c683fdd023b8d04