[lld][Xtensa] Apply the in-place addend for R_XTENSA_32#130
Conversation
R_XTENSA_32 is a partial_inplace relocation: the GNU Xtensa assembler stores the addend in the relocated word and leaves the RELA addend at 0. A plain write32le(loc, val) dropped that addend, miscomputing every R_XTENSA_32 with a nonzero addend -- e.g. the switch jump tables in the precompiled Espressif Wi-Fi blobs, which collapsed to a section base and crashed at runtime. GNU ld links the same objects correctly. Add the existing contents back. Objects from the LLVM Xtensa backend keep the addend in the RELA entry and zero the field, so this adds 0 for them.
|
There is upstream PR for fixing relocations problems in Could you try that? If it works for you I think we can pickup it and ping the author if he is going to finish with it. |
Agreed. |
|
Not sure when I can get to this, I'll likely use this patch until I can test the upstream one. |
Ok. We will ping the author or maybe try to finish it ourselves |
R_XTENSA_32is a partial_inplace relocation — the GNU Xtensa assembler stores the addend in the relocated word and leaves the RELA addend at 0. LLD'swrite32le(loc, val)dropped it, so everyR_XTENSA_32with a nonzero addend resolved wrong.This surfaced linking the precompiled Espressif Wi-Fi blobs:
ppTask's switch jump table is 30R_XTENSA_32relocations against the.wifi0iram.8section symbol with the addends stored in-place. LLD collapsed all 30 to the section base, so the wifi task jumped into a literal pool and hit an illegal instruction on first dispatch; GNUldlinks the same objects fine.Adding the in-place contents back fixes it (verified by relinking — the jump table now holds the correct in-section targets and the device boots wifi). Objects from the LLVM Xtensa backend keep the addend in the RELA entry and zero the field, so this is a no-op for them.