1a71a7f2a4
This was .. an interesting headache. There are two halves: * The earlier IRIX stuff (yes, early) occasionally would do dead code removal and generate multiple consecutive LO16 entries. If this is done for REL entries then it's fine - there's no state kept between them. But gcc 5.x seems to do this for RELA entries. eg: HI1 LO1 HI2 LO2 LO3 HI4 LO4 .. in this instance, LO2 should affect HI2, but LO3 doesn't at all affect anything. The matching HI3 was in code that was deleted as "dead code". Then, the next one: * A "GCC extension" allows for multiple HI entries before a LO entry; and all of those HI entries use the first LO entry as their basis for RELA offset calculations. It does this so GCC can also do dead code deletion without necessarily having to geneate fake relocation entries for balanced HI/LO RELA entries. eg: HI1 LO1 HI2 HI3 HI4 LO4 LO5 HI6 LO6 LO7 in this instance, HI{2,3,4} are the same relocation as LO4 (eg .bss) and need to be buffered until LO4 - then the RELA offset is applied from LO4 to HI{2,3,4} calculations. /And/, the AHL from HI4 is used during the LO4 relocation calculation, just like in the normal (ie, before this commit) implementation. Then, LO5 doesn't trigger anything - the HI "buffer" is empty, so there are no HI relocations to flush out. HI6/LO6 are normal, and LO7 doesn't trigger any HI updates. Tested: * AR9344 SoC, kernel modules, using gcc-5.3 (mips-gcc-5.3.0 package) Notes: * Yes, I do feel dirty having written this code. Reviewed by: imp (after a handful of "this should be on fire" moments wrt gcc and this code) |
||
---|---|---|
.. | ||
adm5120 | ||
alchemy | ||
atheros | ||
beri | ||
broadcom | ||
cavium | ||
conf | ||
gxemul | ||
idt | ||
include | ||
malta | ||
mediatek | ||
mips | ||
nlm | ||
rmi | ||
rt305x | ||
sibyte |