Encode `tail symbol` -> `auipc t1, %pcrel_hi(symbol); jalr x0, t1, %pcrel_lo(symbol)`.
(
sec: &mut SectionData,
symbol: &str,
current_addr: u64,
symbols: &super::symbol_table::SymbolTable,
section_bases: &std::collections::HashMap<SectionKind, u64>,
relocations:
| 370 | fn pcrel_split(offset: i64) -> (i32, i32) { |
| 371 | let lo12 = ((offset & 0xFFF) as i32).wrapping_sub(if offset & 0x800 != 0 { 0x1000 } else { 0 }); |
| 372 | let hi20 = ((offset - lo12 as i64) >> 12) as i32; |
| 373 | (hi20, lo12) |
| 374 | } |
| 375 | |
| 376 | fn resolve_absolute_symbol( |
| 377 | symbol: &str, |
| 378 | symbols: &super::symbol_table::SymbolTable, |
| 379 | section_bases: &std::collections::HashMap<SectionKind, u64>, |
| 380 | ) -> Option<u64> { |
| 381 | if let Some(&addr) = symbols.all().get(symbol) { |
| 382 | for (section_kind, base) in section_bases { |
| 383 | let qualified_name = format!("{}@{}", symbol, section_kind.name()); |
| 384 | if let Some(&offset) = symbols.all().get(&qualified_name) { |
| 385 | return Some(*base + offset); |
| 386 | } |
| 387 | } |
| 388 | return Some(addr); |
| 389 | } |
| 390 | None |
| 391 | } |
| 392 | |
| 393 | // Compute PC-relative (hi20, lo12) for a target address relative to `current_addr`. |
| 394 | fn pcrel_offsets(target_addr: u64, current_addr: u64) -> (i32, i32) { |
| 395 | pcrel_split((target_addr as i64) - (current_addr as i64)) |
| 396 | } |
| 397 | |
| 398 | // Encode `call symbol` -> `auipc ra, %pcrel_hi(symbol); jalr ra, ra, %pcrel_lo(symbol)`. |
| 399 | fn encode_call( |
| 400 | sec: &mut SectionData, |
no test coverage detected