On Mon, 7 Nov 2016, Paul Burton wrote: > When building a kernel targeting a microMIPS ISA, recent GNU linkers > will fail the link if they cannot determine that the target of a branch > or jump is microMIPS code, with errors such as the following: > > mips-img-linux-gnu-ld: arch/mips/built-in.o: .text+0x542c: > Unsupported jump between ISA modes; consider recompiling with > interlinking enabled. > mips-img-linux-gnu-ld: final link failed: Bad value > > or: > > ./arch/mips/include/asm/uaccess.h:1017: warning: JALX to a > non-word-aligned address For the record: branch checks have been tightened as we plan to make use of branches to external symbols in generated code, making them more common than they have been so far. The checks ensure an accidental attempt to assemble or link (as applicable) a branch between a function compiled for the regular ISA and one built for a compressed ISA will trigger at the build time rather than making the program go astray at the run time, which would be harder, perhaps much harder to debug. > Placing anything other than an instruction at the start of a function > written in assembly appears to trigger such errors. In order to prepare > for allowing us to follow function prologue macros with an EXPORT_SYMBOL > invocation, end the prologue macros (LEAD, NESTED & FEXPORT) with a > .insn directive. This ensures that the start of the function is marked > as code, which always makes sense for functions & safely prevents us > from hitting the link errors described above. GAS has a known and accepted deficiency of being unable to see through a section switch. So even though there is indeed a real instruction that follows a given code label once the section has been restored, the switch makes the assembler lose it from the view and the symbol produced by the label does not get the expected function type and consequently the ISA mode annotation. Using an explicit `.insn' annotation sets the symbol type correctly along with the ISA mode. The `.insn' pseudo-op itself has been there since the beginning of MIPS16 support in the toolchain, and has also been noted in the microMIPS architecture specification as required for code labels placed at non-instructions. As these macros can be used at such places too I think it makes sense to imply `.insn' with the macro itself so that it's semantically consistent rather than requiring people to explicitly place the pseudo-op at macro expansion sites as required. I'm not sure if I indeed like the idea of placing EXPORT_SYMBOL in the middle of a code block, as I find it inconsistent with C usage where, by convention, it only comes at the end of a function's body. That is a separate matter though, so for this change only: Reviewed-by: Maciej W. Rozycki <macro@xxxxxxxxxx> Thank you for your work in this area! Maciej