Skip to content

Commit

Permalink
ADI SHARC Architecture support (gimli-rs#593)
Browse files Browse the repository at this point in the history
* Add Architecture::Sharc
* elf: Add support for SHARC+ relocations
* elf: sharc: add SHT_SHARC_ADI_ATTRIBUTES
  • Loading branch information
joshchngs committed Nov 30, 2023
1 parent b3dbfab commit 378ee69
Show file tree
Hide file tree
Showing 5 changed files with 230 additions and 0 deletions.
26 changes: 26 additions & 0 deletions src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ pub enum Architecture {
Riscv64,
S390x,
Sbf,
Sharc,
Sparc64,
Wasm32,
Wasm64,
Expand Down Expand Up @@ -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),
Expand Down Expand Up @@ -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.
Expand Down
108 changes: 108 additions & 0 deletions src/elf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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`.
Expand Down
1 change: 1 addition & 0 deletions src/read/elf/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
51 changes: 51 additions & 0 deletions src/read/elf/relocation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,57 @@ fn parse_relocation<Elf: FileHeader>(
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),
Expand Down
44 changes: 44 additions & 0 deletions src/write/elf/object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
_ => {
Expand Down Expand Up @@ -301,6 +302,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,
_ => {
Expand Down Expand Up @@ -726,6 +728,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,
Expand Down

0 comments on commit 378ee69

Please sign in to comment.