Encode `la rd, symbol` -> `auipc rd, %pcrel_hi(symbol); addi rd, rd, %pcrel_lo(symbol)`. Always emits a relocation since section merging may change cross-section distances.
(
sec: &mut SectionData,
rd: u8,
symbol: &str,
current_addr: u64,
symbols: &super::symbol_table::SymbolTable,
section_bases: &std::collections::HashMap<SectionKind, u64>,
r
| 399 | fn encode_call( |
| 400 | sec: &mut SectionData, |
| 401 | symbol: &str, |
| 402 | current_addr: u64, |
| 403 | symbols: &super::symbol_table::SymbolTable, |
| 404 | section_bases: &std::collections::HashMap<SectionKind, u64>, |
| 405 | relocations: &mut Vec<RelocationRecord>, |
| 406 | section_name: &str, |
| 407 | ) { |
| 408 | if let Some(target_addr) = resolve_absolute_symbol(symbol, symbols, section_bases) { |
| 409 | let (hi20, lo12) = pcrel_offsets(target_addr, current_addr); |
| 410 | sec.push_u32_le(Auipc::new(1, hi20 << 12).encode()); |
| 411 | sec.push_u32_le(Jalr::new(1, 1, lo12).encode()); |
| 412 | return; |
| 413 | } |
| 414 | // Emit relocation when the target is in a different object. |
| 415 | let reloc_offset = sec.current_offset(); |
| 416 | sec.push_u32_le(Auipc::new(1, 0).encode()); |
| 417 | sec.push_u32_le(Jalr::new(1, 1, 0).encode()); |
| 418 | relocations.push(RelocationRecord { |
| 419 | section: section_name.to_owned(), |
| 420 | offset: reloc_offset, |
| 421 | symbol: symbol.to_owned(), |
| 422 | kind: RelocationKind::CallPlt, |
| 423 | addend: 0, |
| 424 | }); |
| 425 | } |
| 426 | |
| 427 | // Encode `tail symbol` -> `auipc t1, %pcrel_hi(symbol); jalr x0, t1, %pcrel_lo(symbol)`. |
no test coverage detected