diff --git a/src/common.rs b/src/common.rs index 0e6af091..37ccb4b9 100644 --- a/src/common.rs +++ b/src/common.rs @@ -26,6 +26,7 @@ pub enum Architecture { Riscv64, S390x, Sbf, + Sharc, Sparc64, Wasm32, Wasm64, @@ -59,6 +60,7 @@ impl Architecture { Architecture::Riscv64 => Some(AddressSize::U64), Architecture::S390x => Some(AddressSize::U64), Architecture::Sbf => Some(AddressSize::U64), + Architecture::Sharc => Some(AddressSize::U32), Architecture::Sparc64 => Some(AddressSize::U64), Architecture::Wasm32 => Some(AddressSize::U32), Architecture::Wasm64 => Some(AddressSize::U64), @@ -367,6 +369,30 @@ pub enum RelocationEncoding { /// /// The `RelocationKind` must be PC relative. LoongArchBranch, + + /// SHARC+ 48-bit Type A instruction + /// + /// Represents these possible variants, each with a corresponding + /// `R_SHARC_*` constant: + /// + /// * 24-bit absolute address + /// * 32-bit absolute address + /// * 6-bit relative address + /// * 24-bit relative address + /// * 6-bit absolute address in the immediate value field + /// * 16-bit absolute address in the immediate value field + SharcTypeA, + + /// SHARC+ 32-bit Type B instruction + /// + /// Represents these possible variants, each with a corresponding + /// `R_SHARC_*` constant: + /// + /// * 6-bit absolute address in the immediate value field + /// * 7-bit absolute address in the immediate value field + /// * 16-bit absolute address + /// * 6-bit relative address + SharcTypeB, } /// File flags that are specific to each file format. diff --git a/src/elf.rs b/src/elf.rs index f202c598..87cc499d 100644 --- a/src/elf.rs +++ b/src/elf.rs @@ -2207,6 +2207,114 @@ pub const R_386_IRELATIVE: u32 = 42; /// Load from 32 bit GOT entry, relaxable. pub const R_386_GOT32X: u32 = 43; +// ADI SHARC specific definitions + +// SHARC values for `Rel*::r_type` + +/// 24-bit absolute address in bits 23:0 of a 48-bit instr +/// +/// Targets: +/// +/// * Type 25a (PC_DIRECT) +pub const R_SHARC_ADDR24_V3: u32 = 0x0b; + +/// 32-bit absolute address in bits 31:0 of a 48-bit instr +/// +/// Targets: +/// +/// * Type 14a +/// * Type 14d +/// * Type 15a +/// * Type 16a +/// * Type 17a +/// * Type 18a +/// * Type 19a +pub const R_SHARC_ADDR32_V3: u32 = 0x0c; + +/// 32-bit absolute address in bits 31:0 of a 32-bit data location +/// +/// Represented with `RelocationEncoding::Generic` +pub const R_SHARC_ADDR_VAR_V3: u32 = 0x0d; + +/// 6-bit PC-relative address in bits 32:27 of a 48-bit instr +/// +/// Targets: +/// +/// * Type 9a +/// * Type 10a +pub const R_SHARC_PCRSHORT_V3: u32 = 0x0e; + +/// 24-bit PC-relative address in bits 23:0 of a 48-bit instr +/// +/// Targets: +/// +/// * Type 8a +/// * Type 12a (truncated to 23 bits after relocation) +/// * Type 13a (truncated to 23 bits after relocation) +/// * Type 25a (PC Relative) +pub const R_SHARC_PCRLONG_V3: u32 = 0x0f; + +/// 6-bit absolute address in bits 32:27 of a 48-bit instr +/// +/// Targets: +/// +/// * Type 4a +/// * Type 4b +/// * Type 4d +pub const R_SHARC_DATA6_V3: u32 = 0x10; + +/// 16-bit absolute address in bits 39:24 of a 48-bit instr +/// +/// Targets: +/// +/// * Type 12a +pub const R_SHARC_DATA16_V3: u32 = 0x11; + +/// 6-bit absolute address into bits 16:11 of a 32-bit instr +/// +/// Targets: +/// +/// * Type 4b +pub const R_SHARC_DATA6_VISA_V3: u32 = 0x12; + +/// 7-bit absolute address into bits 6:0 of a 32-bit instr +pub const R_SHARC_DATA7_VISA_V3: u32 = 0x13; + +/// 16-bit absolute address into bits 15:0 of a 32-bit instr +pub const R_SHARC_DATA16_VISA_V3: u32 = 0x14; + +/// 6-bit PC-relative address into bits 16:11 of a Type B +/// +/// Targets: +/// +/// * Type 9b +pub const R_SHARC_PCR6_VISA_V3: u32 = 0x17; + +/// 16-bit absolute address into bits 15:0 of a 16-bit location. +/// +/// Represented with `RelocationEncoding::Generic` +pub const R_SHARC_ADDR_VAR16_V3: u32 = 0x19; + +pub const R_SHARC_CALC_PUSH_ADDR: u32 = 0xe0; +pub const R_SHARC_CALC_PUSH_ADDEND: u32 = 0xe1; +pub const R_SHARC_CALC_ADD: u32 = 0xe2; +pub const R_SHARC_CALC_SUB: u32 = 0xe3; +pub const R_SHARC_CALC_MUL: u32 = 0xe4; +pub const R_SHARC_CALC_DIV: u32 = 0xe5; +pub const R_SHARC_CALC_MOD: u32 = 0xe6; +pub const R_SHARC_CALC_LSHIFT: u32 = 0xe7; +pub const R_SHARC_CALC_RSHIFT: u32 = 0xe8; +pub const R_SHARC_CALC_AND: u32 = 0xe9; +pub const R_SHARC_CALC_OR: u32 = 0xea; +pub const R_SHARC_CALC_XOR: u32 = 0xeb; +pub const R_SHARC_CALC_PUSH_LEN: u32 = 0xec; +pub const R_SHARC_CALC_NOT: u32 = 0xf6; + +// SHARC values for `SectionHeader*::sh_type`. + +/// .adi.attributes +pub const SHT_SHARC_ADI_ATTRIBUTES: u32 = SHT_LOPROC + 0x2; + // SUN SPARC specific definitions. // SPARC values for `st_type` component of `Sym*::st_info`. diff --git a/src/read/elf/file.rs b/src/read/elf/file.rs index 67be37e2..39c8ef38 100644 --- a/src/read/elf/file.rs +++ b/src/read/elf/file.rs @@ -178,6 +178,7 @@ where // We only support the 64-bit variant s390x here. (elf::EM_S390, true) => Architecture::S390x, (elf::EM_SBF, _) => Architecture::Sbf, + (elf::EM_SHARC, false) => Architecture::Sharc, (elf::EM_SPARCV9, true) => Architecture::Sparc64, (elf::EM_XTENSA, false) => Architecture::Xtensa, _ => Architecture::Unknown, diff --git a/src/read/elf/relocation.rs b/src/read/elf/relocation.rs index 78032dfd..a337218d 100644 --- a/src/read/elf/relocation.rs +++ b/src/read/elf/relocation.rs @@ -404,6 +404,57 @@ fn parse_relocation( elf::R_SBF_64_32 => (RelocationKind::Absolute, 32), r_type => (RelocationKind::Elf(r_type), 0), }, + elf::EM_SHARC => match reloc.r_type(endian, false) { + elf::R_SHARC_ADDR24_V3 => { + encoding = RelocationEncoding::SharcTypeA; + (RelocationKind::Absolute, 24) + } + elf::R_SHARC_ADDR32_V3 => { + encoding = RelocationEncoding::SharcTypeA; + (RelocationKind::Absolute, 32) + } + elf::R_SHARC_ADDR_VAR_V3 => { + encoding = RelocationEncoding::Generic; + (RelocationKind::Absolute, 32) + } + elf::R_SHARC_PCRSHORT_V3 => { + encoding = RelocationEncoding::SharcTypeA; + (RelocationKind::Relative, 6) + } + elf::R_SHARC_PCRLONG_V3 => { + encoding = RelocationEncoding::SharcTypeA; + (RelocationKind::Relative, 24) + } + elf::R_SHARC_DATA6_V3 => { + encoding = RelocationEncoding::SharcTypeA; + (RelocationKind::Absolute, 6) + } + elf::R_SHARC_DATA16_V3 => { + encoding = RelocationEncoding::SharcTypeA; + (RelocationKind::Absolute, 16) + } + elf::R_SHARC_DATA6_VISA_V3 => { + encoding = RelocationEncoding::SharcTypeB; + (RelocationKind::Absolute, 6) + } + elf::R_SHARC_DATA7_VISA_V3 => { + encoding = RelocationEncoding::SharcTypeB; + (RelocationKind::Absolute, 7) + } + elf::R_SHARC_DATA16_VISA_V3 => { + encoding = RelocationEncoding::SharcTypeB; + (RelocationKind::Absolute, 16) + } + elf::R_SHARC_PCR6_VISA_V3 => { + encoding = RelocationEncoding::SharcTypeB; + (RelocationKind::Relative, 16) + } + elf::R_SHARC_ADDR_VAR16_V3 => { + encoding = RelocationEncoding::Generic; + (RelocationKind::Absolute, 16) + } + r_type => (RelocationKind::Elf(r_type), 0), + }, elf::EM_SPARC | elf::EM_SPARC32PLUS | elf::EM_SPARCV9 => { match reloc.r_type(endian, false) { elf::R_SPARC_32 | elf::R_SPARC_UA32 => (RelocationKind::Absolute, 32), diff --git a/src/write/elf/object.rs b/src/write/elf/object.rs index 421d23a8..c0ad3252 100644 --- a/src/write/elf/object.rs +++ b/src/write/elf/object.rs @@ -141,6 +141,7 @@ impl<'a> Object<'a> { Architecture::Riscv32 => true, Architecture::S390x => true, Architecture::Sbf => false, + Architecture::Sharc => true, Architecture::Sparc64 => true, Architecture::Xtensa => true, _ => { @@ -345,6 +346,7 @@ impl<'a> Object<'a> { Architecture::Riscv64 => elf::EM_RISCV, Architecture::S390x => elf::EM_S390, Architecture::Sbf => elf::EM_SBF, + Architecture::Sharc => elf::EM_SHARC, Architecture::Sparc64 => elf::EM_SPARCV9, Architecture::Xtensa => elf::EM_XTENSA, _ => { @@ -766,6 +768,48 @@ impl<'a> Object<'a> { return Err(Error(format!("unimplemented relocation {:?}", reloc))); } }, + Architecture::Sharc => match (reloc.kind, reloc.encoding, reloc.size) { + (RelocationKind::Absolute, RelocationEncoding::SharcTypeA, 32) => { + elf::R_SHARC_ADDR32_V3 + } + (RelocationKind::Absolute, RelocationEncoding::Generic, 32) => { + elf::R_SHARC_ADDR_VAR_V3 + } + (RelocationKind::Relative, RelocationEncoding::SharcTypeA, 24) => { + elf::R_SHARC_PCRLONG_V3 + } + (RelocationKind::Relative, RelocationEncoding::SharcTypeA, 6) => { + elf::R_SHARC_PCRSHORT_V3 + } + (RelocationKind::Relative, RelocationEncoding::SharcTypeB, 6) => { + elf::R_SHARC_PCRSHORT_V3 + } + (RelocationKind::Absolute, RelocationEncoding::Generic, 16) => { + elf::R_SHARC_ADDR_VAR16_V3 + } + (RelocationKind::Absolute, RelocationEncoding::SharcTypeA, 16) => { + elf::R_SHARC_DATA16_V3 + } + (RelocationKind::Absolute, RelocationEncoding::SharcTypeB, 16) => { + elf::R_SHARC_DATA16_VISA_V3 + } + (RelocationKind::Absolute, RelocationEncoding::SharcTypeA, 24) => { + elf::R_SHARC_ADDR24_V3 + } + (RelocationKind::Absolute, RelocationEncoding::SharcTypeA, 6) => { + elf::R_SHARC_DATA6_V3 + } + (RelocationKind::Absolute, RelocationEncoding::SharcTypeB, 6) => { + elf::R_SHARC_DATA6_VISA_V3 + } + (RelocationKind::Absolute, RelocationEncoding::SharcTypeB, 7) => { + elf::R_SHARC_DATA7_VISA_V3 + } + (RelocationKind::Elf(x), _, _) => x, + _ => { + return Err(Error(format!("unimplemented relocation {:?}", reloc))); + } + }, Architecture::Sparc64 => match (reloc.kind, reloc.encoding, reloc.size) { // TODO: use R_SPARC_32/R_SPARC_64 if aligned. (RelocationKind::Absolute, _, 32) => elf::R_SPARC_UA32,