Skip to content

Commit

Permalink
elf: Add support for SHARC+ relocations
Browse files Browse the repository at this point in the history
  • Loading branch information
joshchngs committed Nov 12, 2023
1 parent 70d07b4 commit 727a50c
Show file tree
Hide file tree
Showing 4 changed files with 220 additions and 0 deletions.
48 changes: 48 additions & 0 deletions src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,54 @@ pub enum RelocationEncoding {
///
/// The `RelocationKind` must be PC relative.
LoongArchBranch,

/// SHARC+ 24-bit absolute address in a Type A instruction
///
/// Used with `RelocationKind::Absolute`.
/// See [elf::R_SHARC_ADDR24_v3]
SharcAbs24TypeA,

/// SHARC+ 32-bit absolute address in a Type A instruction
///
/// Used with `RelocationKind::Absolute`.
/// See [elf::R_SHARC_ADDR32_v3]
SharcAbs32TypeA,

/// SHARC+ 32-bit absolute address in a 32-bit STT_OBJECT location
///
/// See [elf::R_SHARC_ADDRVAR_V3]
SharcAbs32Data,

/// SHARC+ 6-bit relative address in a Type A instruction
///
/// The `RelocationKind` must be PC relative.
SharcPcr6TypeA,

/// SHARC+ 24-bit relative address in a Type A instruction
///
/// The `RelocationKind` must be PC relative.
SharcPcr24TypeA,

/// SHARC+ 6-bit absolute address in the immediate value field of a Type A instruction
SharcAbs6TypeA,

/// SHARC+ 16-bit absolute address in the immediate value field of a Type A instruction
SharcAbs16TypeA,

/// SHARC+ 6-bit absolute address in the immediate value field of a Type B instruction
SharcAbs6TypeB,

/// SHARC+ 7-bit absolute address in the immediate value field of a Type B instruction
SharcAbs7TypeB,

/// SHARC+ 16-bit absolute address in a Type B instruction
SharcAbs16TypeB,

/// SHARC+ 6-bit relative address in a Type B instruction
SharcPcr6TypeB,

/// SHARC+ 16-bit absolute address in a 16-bit STT_OBJECT location
SharcAbs16Data,
}

/// File flags that are specific to each file format.
Expand Down
100 changes: 100 additions & 0 deletions src/elf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2207,6 +2207,106 @@ 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
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.
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;


// SUN SPARC specific definitions.

// SPARC values for `st_type` component of `Sym*::st_info`.
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 @@ -404,6 +404,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::SharcAbs24TypeA;
(RelocationKind::Absolute, 48)
}
elf::R_SHARC_ADDR32_V3 => {
encoding = RelocationEncoding::SharcAbs32TypeA;
(RelocationKind::Absolute, 48)
}
elf::R_SHARC_ADDR_VAR_V3 => {
encoding = RelocationEncoding::SharcAbs32Data;
(RelocationKind::Absolute, 32)
}
elf::R_SHARC_PCRSHORT_V3 => {
encoding = RelocationEncoding::SharcPcr6TypeA;
(RelocationKind::Relative, 48)
}
elf::R_SHARC_PCRLONG_V3 => {
encoding = RelocationEncoding::SharcPcr24TypeA;
(RelocationKind::Relative, 48)
}
elf::R_SHARC_DATA6_V3 => {
encoding = RelocationEncoding::SharcAbs6TypeA;
(RelocationKind::Absolute, 48)
}
elf::R_SHARC_DATA16_V3 => {
encoding = RelocationEncoding::SharcAbs16TypeA;
(RelocationKind::Absolute, 48)
}
elf::R_SHARC_DATA6_VISA_V3 => {
encoding = RelocationEncoding::SharcAbs6TypeB;
(RelocationKind::Absolute, 32)
}
elf::R_SHARC_DATA7_VISA_V3 => {
encoding = RelocationEncoding::SharcAbs7TypeB;
(RelocationKind::Absolute, 32)
}
elf::R_SHARC_DATA16_VISA_V3 => {
encoding = RelocationEncoding::SharcAbs16TypeB;
(RelocationKind::Absolute, 32)
}
elf::R_SHARC_PCR6_VISA_V3 => {
encoding = RelocationEncoding::SharcPcr6TypeB;
(RelocationKind::Relative, 32)
}
elf::R_SHARC_ADDR_VAR16_V3 => {
encoding = RelocationEncoding::SharcAbs16Data;
(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
21 changes: 21 additions & 0 deletions src/write/elf/object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -768,6 +768,27 @@ impl<'a> Object<'a> {
return Err(Error(format!("unimplemented relocation {:?}", reloc)));
}
},
Architecture::Sharc => match (reloc.kind, reloc.encoding, reloc.size) {
(RelocationKind::Absolute, RelocationEncoding::SharcAbs32TypeA, 48) => elf::R_SHARC_ADDR32_V3,
(RelocationKind::Absolute, RelocationEncoding::SharcAbs32Data, 32) => elf::R_SHARC_ADDR_VAR_V3,
(RelocationKind::Relative, RelocationEncoding::SharcPcr24TypeA, 48) => elf::R_SHARC_PCRLONG_V3,
(RelocationKind::Relative, RelocationEncoding::SharcPcr6TypeA, 48) => elf::R_SHARC_PCRSHORT_V3,
(RelocationKind::Relative, RelocationEncoding::SharcPcr6TypeB, 32) => elf::R_SHARC_PCRSHORT_V3,
(RelocationKind::Absolute, RelocationEncoding::SharcAbs16Data, 16) => elf::R_SHARC_ADDR_VAR16_V3,
(RelocationKind::Absolute, RelocationEncoding::SharcAbs16TypeA, 48) => elf::R_SHARC_DATA16_V3,
(RelocationKind::Absolute, RelocationEncoding::SharcAbs16TypeB, 32) => elf::R_SHARC_DATA16_VISA_V3,
(RelocationKind::Absolute, RelocationEncoding::SharcAbs24TypeA, 48) => elf::R_SHARC_ADDR24_V3,
(RelocationKind::Absolute, RelocationEncoding::SharcAbs6TypeA, 48) => elf::R_SHARC_DATA6_V3,
(RelocationKind::Absolute, RelocationEncoding::SharcAbs6TypeB, 32) => elf::R_SHARC_DATA6_VISA_V3,
(RelocationKind::Absolute, RelocationEncoding::SharcAbs7TypeB, 32) => elf::R_SHARC_DATA7_VISA_V3,
(_, RelocationEncoding::Generic, _) => {
return Err(Error(format!("SHARC+ ISA does not have a generic relocation encoding")));
},
(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 727a50c

Please sign in to comment.