a possible issue in relaxing call to zcmt instruction
Created by: JoshCafe
hi,
https://github.com/openhwgroup/corev-binutils-gdb/blob/development/bfd/elfnn-riscv.c
For R_RISCV_CALL and R_RISCV_CALL_PLT, in relax_pass 0 and relax_trip 2 of _bfd_riscv_relax_section, if benifical the auipc is replaced by zcmt instruction in _bfd_riscv_table_jump_mark.
But in relax_pass 1 of _bfd_riscv_relax_call, it seems the marked instruction fails to be relaxed to a zcmt insntruction if auipc+jalr could not be shortened to jal or jalr(near zero) due to the following condition check:
/* See if this function call can be shortened. */
if (!VALID_JTYPE_IMM (foff) && !(!bfd_link_pic (link_info) && near_zero)
&& link_info->relax_pass != 0)
return true;
Seems we need to move the following codes to the top of function to avoid being blocked by the condition above.
/* Relax a table jump instruction that is marked. */
if (link_info->relax_pass == 1
&& ((auipc ^ MATCH_TABLE_JUMP) & MASK_CM_JALT) == 0)
{
rel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel->r_info), R_RISCV_TABLE_JUMP);
*again = true;
return riscv_relax_delete_bytes (abfd, sec, rel->r_offset + 2, 6, link_info, pcgp_relocs);
}
BR Joshcafe