[MIPS] Handle cross-mode (regular <-> microMIPS) jumps
The patch solves two tasks:
- MIPS ABI allows to mix regular and microMIPS code and perform cross-mode jumps. Linker needs to detect such cases and replace jump/branch instructions by their cross-mode equivalents.
- Other tools like dunamic linkers need to recognize cases when dynamic table entries, e_entry field of an ELF header etc point to microMIPS symbol. Linker should provide such information.
The first task is implemented in the MIPS<ELFT>::relocateOne() method. New routine fixupCrossModeJump detects ISA mode change, checks and replaces an instruction.
The main problem is how to recognize that relocation target is microMIPS symbol. For absolute and section symbols compiler or assembler set the less-significant bit of the symbol's value or sum of the symbol's value and addend. And this bit signals to linker about microMIPS code. For global symbols compiler cannot do the same trick because other tools like, for example, disassembler want to know an actual position of the symbol. So compiler sets STO_MIPS_MICROMIPS flag in the st_other field.
We set the less-significant bit for symbols with the STO_MIPS_MICROMIPS flag in the following places:
To provide all necessary information for setup the bit this patch starts to pass a pointer to the relocated symbol to the relocateOne methods.