pkarashchenko commented on code in PR #11322: URL: https://github.com/apache/nuttx/pull/11322#discussion_r1424584855
########## libs/libc/machine/risc-v/arch_elf.c: ########## @@ -317,58 +396,101 @@ int up_relocateadd(const Elf_Rela *rel, const Elf_Sym *sym, break; case R_RISCV_PCREL_LO12_I: - case R_RISCV_PCREL_LO12_S: { + long imm_hi; + long imm_lo; + binfo("%s at %08" PRIxPTR " [%08" PRIx32 "] " "to sym=%p st_value=%08lx\n", _get_rname(relotype), addr, _get_val((uint16_t *)addr), sym, sym->st_value); - /* NOTE: imm value for mv has been adjusted in previous HI20 */ + offset = _find_hi20(arch_data, sym->st_value); + + /* Adjust imm for MV(ADDI) / JR (JALR) : I-type */ + + _calc_imm(offset, &imm_hi, &imm_lo); + + _add_val((uint16_t *)addr, (int32_t)imm_lo << 20); } break; - case R_RISCV_PCREL_HI20: - case R_RISCV_CALL: - case R_RISCV_CALL_PLT: + case R_RISCV_PCREL_LO12_S: { + uint32_t val; + long imm_hi; + long imm_lo; + binfo("%s at %08" PRIxPTR " [%08" PRIx32 "] " "to sym=%p st_value=%08lx\n", _get_rname(relotype), addr, _get_val((uint16_t *)addr), sym, sym->st_value); - offset = (long)sym->st_value + (long)rel->r_addend - (long)addr; + offset = _find_hi20(arch_data, sym->st_value); + + /* Adjust imm for SW : S-type */ + + _calc_imm(offset, &imm_hi, &imm_lo); + + val = (((int32_t)imm_lo >> 5) << 25) + + (((int32_t)imm_lo & 0x1f) << 7); + binfo("imm_lo=%ld (%lx), val=%" PRIx32 "\n", imm_lo, imm_lo, val); + + _add_val((uint16_t *)addr, val); + } + break; + + case R_RISCV_PCREL_HI20: + { long imm_hi; long imm_lo; + binfo("%s at %08" PRIxPTR " [%08" PRIx32 "] " + "to sym=%p st_value=%08lx\n", + _get_rname(relotype), + addr, _get_val((uint16_t *)addr), + sym, sym->st_value); + + offset = (long)sym->st_value + (long)rel->r_addend - (long)addr; + _calc_imm(offset, &imm_hi, &imm_lo); /* Adjust auipc (add upper immediate to pc) : 20bit */ - _add_val((uint16_t *)addr, (imm_hi << 12)); + _add_val((uint16_t *)addr, imm_hi << 12); Review Comment: Yes, returning error seems to be reasonable. Lets merge the patch and the rest can be improved as a next step. I met similar error when I was working with RV64 based SoC that had SRAM mapped starting from `0xb0000000` address while my initial loader code was executing from XIP mapped starting from `0x30000000`, so I had a linker defined symbol (defined in the linker script) that was a jump point for the next level SW that was `0xb0000XXX`, so as soon as I used that linker defined symbol in my C code (that was executed from XIP) to cast it to function pointer and make a jump the linker was generating a relocation truncation error even with `medany` variant. I started my experiments and did many attempts in order to overcome this issue. I would disagree with your statement about assembly code no relation to `medany` as https://github.com/riscv-collab/riscv-gnu-toolchain/issues/733 description clearly states used cmodel `// in c, compile with -mcmodel=medany`. I think that is exactly to show that issue is not `medlow` specific. Usually compiler will generate a PC relative instructions and that I agree, but I also tried to overcome issue in my case (that by default was `auipc`+pair) by changing it to inline assembly of `lui`+pair and both variants lead to relocation error at link time because both `auipc` and `lui` have the same nature of sign bit propagation with `prcel_hi(symbol)`/`hi(symbol)`. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: commits-unsubscr...@nuttx.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org