pussuw commented on PR #11322: URL: https://github.com/apache/nuttx/pull/11322#issuecomment-1846916845
> Not sure if this is related, but recently I faced an issue of relocation truncation (with static linking of course) for RV64 arch when referenced symbol address had "sign bit" set (`0x80000000` bit set), so RV64 compiler populates the sign bit and address starts looking `0xffffffff80000000`. To overcome this I had to use a trick of masking sign bit from symbol label at compile time and then adding assembly instructions to restore it back after `%pcrel_hi(symbol-0x80000000)` value loaded to the register. Sorry for spamming here, but I spent fair amount of time to actually understand this non-logical behaviour of RV64 ISA that does not have instruction to say that I want to load `%pcrel_hi(symbol)` value as unsigned. The compiler is mandated to do sign extension for short addresses. It is a valid address, it being negative should not have any impact. This is not really related to this PR. Like I described, the hi/lo relocations must be done in pairs. The current implementation assumes that the hi/lo relocations follow each other as two contiguous instructions. This assumption is wrong, and thus when a pcrel_lo relocation is encountered, the matching pcrel_hi must be found from the relocation entries, and it is found via the symbol "label". This is why they have the form: ``` label: auipc a0, %pcrel_hi(symbol) // R_RISCV_PCREL_HI20 /* Whatever goes here */ load/store a0, %pcrel_lo(label)(a0) // R_RISCV_PCREL_LO12_I/S ``` Having the label: is not optional, it is _mandatory_, otherwise the pcrel_hi part cannot be found by the linker! -- 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