Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LoongArch: add new relocs introduced by LoongArch psABI v2 #450

Merged
merged 4 commits into from
Aug 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions crates/examples/src/readobj/elf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3020,6 +3020,43 @@ static FLAGS_R_LOONGARCH: &[Flag<u32>] = &flags!(
R_LARCH_SUB64,
R_LARCH_GNU_VTINHERIT,
R_LARCH_GNU_VTENTRY,
R_LARCH_B16,
R_LARCH_B21,
R_LARCH_B26,
R_LARCH_ABS_HI20,
R_LARCH_ABS_LO12,
R_LARCH_ABS64_LO20,
R_LARCH_ABS64_HI12,
R_LARCH_PCALA_HI20,
R_LARCH_PCALA_LO12,
R_LARCH_PCALA64_LO20,
R_LARCH_PCALA64_HI12,
R_LARCH_GOT_PC_HI20,
R_LARCH_GOT_PC_LO12,
R_LARCH_GOT64_PC_LO20,
R_LARCH_GOT64_PC_HI12,
R_LARCH_GOT_HI20,
R_LARCH_GOT_LO12,
R_LARCH_GOT64_LO20,
R_LARCH_GOT64_HI12,
R_LARCH_TLS_LE_HI20,
R_LARCH_TLS_LE_LO12,
R_LARCH_TLS_LE64_LO20,
R_LARCH_TLS_LE64_HI12,
R_LARCH_TLS_IE_PC_HI20,
R_LARCH_TLS_IE_PC_LO12,
R_LARCH_TLS_IE64_PC_LO20,
R_LARCH_TLS_IE64_PC_HI12,
R_LARCH_TLS_IE_HI20,
R_LARCH_TLS_IE_LO12,
R_LARCH_TLS_IE64_LO20,
R_LARCH_TLS_IE64_HI12,
R_LARCH_TLS_LD_PC_HI20,
R_LARCH_TLS_LD_HI20,
R_LARCH_TLS_GD_PC_HI20,
R_LARCH_TLS_GD_HI20,
R_LARCH_32_PCREL,
R_LARCH_RELAX,
);
static FLAGS_NT_CORE: &[Flag<u32>] = &flags!(
NT_PRSTATUS,
Expand Down
5 changes: 5 additions & 0 deletions src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,11 @@ pub enum RelocationEncoding {
///
/// The `RelocationKind` must be PC relative.
AArch64Call,

/// LoongArch branch offset with two trailing zeros.
///
/// The `RelocationKind` must be PC relative.
LoongArchBranch,
}

/// File flags that are specific to each file format.
Expand Down
88 changes: 88 additions & 0 deletions src/elf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6372,6 +6372,94 @@ pub const R_LARCH_SUB64: u32 = 56;
pub const R_LARCH_GNU_VTINHERIT: u32 = 57;
/// GNU C++ vtable member usage
pub const R_LARCH_GNU_VTENTRY: u32 = 58;
/// 18-bit PC-relative jump offset with two trailing zeros
pub const R_LARCH_B16: u32 = 64;
/// 23-bit PC-relative jump offset with two trailing zeros
pub const R_LARCH_B21: u32 = 65;
/// 28-bit PC-relative jump offset with two trailing zeros
pub const R_LARCH_B26: u32 = 66;
/// 12..=31 bits of 32/64-bit absolute address
pub const R_LARCH_ABS_HI20: u32 = 67;
/// 0..=11 bits of 32/64-bit absolute address
pub const R_LARCH_ABS_LO12: u32 = 68;
/// 32..=51 bits of 64-bit absolute address
pub const R_LARCH_ABS64_LO20: u32 = 69;
/// 52..=63 bits of 64-bit absolute address
pub const R_LARCH_ABS64_HI12: u32 = 70;
/// 12..=31 bits of the 32/64-bit PC-relative offset to the PC-relative
/// anchor, calculated as the 12..=31 bits of the distance between
/// `PC & ~0xfff` and `(S + A + 0x800)`.
pub const R_LARCH_PCALA_HI20: u32 = 71;
/// Same as R_LARCH_ABS_LO12. 0..=11 bits of the 32/64-bit offset from
/// the PC relative anchor.
pub const R_LARCH_PCALA_LO12: u32 = 72;
/// 32..=51 bits of the 64-bit offset from the PC relative anchor.
pub const R_LARCH_PCALA64_LO20: u32 = 73;
/// 52..=63 bits of the 64-bit offset from the PC relative anchor.
pub const R_LARCH_PCALA64_HI12: u32 = 74;
/// 12..=31 bits of the 32/64-bit PC-relative offset to the PC-relative
/// anchor for the GOT entry.
pub const R_LARCH_GOT_PC_HI20: u32 = 75;
/// 0..=11 bits of the 32/64-bit offset from the PC relative anchor to the
/// GOT entry.
pub const R_LARCH_GOT_PC_LO12: u32 = 76;
/// 32..=51 bits of the 64-bit offset from the PC relative anchor to the
/// GOT entry.
pub const R_LARCH_GOT64_PC_LO20: u32 = 77;
/// 52..=63 bits of the 64-bit offset from the PC relative anchor to the
/// GOT entry.
pub const R_LARCH_GOT64_PC_HI12: u32 = 78;
/// 12..=31 bits of 32/64-bit GOT entry absolute address
pub const R_LARCH_GOT_HI20: u32 = 79;
/// 0..=11 bits of 32/64-bit GOT entry absolute address
pub const R_LARCH_GOT_LO12: u32 = 80;
/// 32..=51 bits of 64-bit GOT entry absolute address
pub const R_LARCH_GOT64_LO20: u32 = 81;
/// 52..=63 bits of 64-bit GOT entry absolute address
pub const R_LARCH_GOT64_HI12: u32 = 82;
/// 12..=31 bits of TLS LE 32/64-bit offset from thread pointer
pub const R_LARCH_TLS_LE_HI20: u32 = 83;
/// 0..=11 bits of TLS LE 32/64-bit offset from thread pointer
pub const R_LARCH_TLS_LE_LO12: u32 = 84;
/// 32..=51 bits of TLS LE 64-bit offset from thread pointer
pub const R_LARCH_TLS_LE64_LO20: u32 = 85;
/// 52..=63 bits of TLS LE 64-bit offset from thread pointer
pub const R_LARCH_TLS_LE64_HI12: u32 = 86;
/// 12..=31 bits of the 32/64-bit PC-relative offset to the PC-relative
/// anchor for the TLE IE GOT entry.
pub const R_LARCH_TLS_IE_PC_HI20: u32 = 87;
/// 0..=12 bits of the 32/64-bit offset from the PC-relative anchor to the
/// TLS IE GOT entry.
pub const R_LARCH_TLS_IE_PC_LO12: u32 = 88;
/// 32..=51 bits of the 64-bit offset from the PC-relative anchor to the
/// TLS IE GOT entry.
pub const R_LARCH_TLS_IE64_PC_LO20: u32 = 89;
/// 52..=63 bits of the 64-bit offset from the PC-relative anchor to the
/// TLS IE GOT entry.
pub const R_LARCH_TLS_IE64_PC_HI12: u32 = 90;
/// 12..=31 bits of TLS IE GOT entry 32/64-bit absolute address
pub const R_LARCH_TLS_IE_HI20: u32 = 91;
/// 0..=11 bits of TLS IE GOT entry 32/64-bit absolute address
pub const R_LARCH_TLS_IE_LO12: u32 = 92;
/// 32..=51 bits of TLS IE GOT entry 64-bit absolute address
pub const R_LARCH_TLS_IE64_LO20: u32 = 93;
/// 51..=63 bits of TLS IE GOT entry 64-bit absolute address
pub const R_LARCH_TLS_IE64_HI12: u32 = 94;
/// 12..=31 bits of the 32/64-bit PC-relative offset to the PC-relative
/// anchor for the TLE LD GOT entry.
pub const R_LARCH_TLS_LD_PC_HI20: u32 = 95;
/// 12..=31 bits of TLS LD GOT entry 32/64-bit absolute address
pub const R_LARCH_TLS_LD_HI20: u32 = 96;
/// 12..=31 bits of the 32/64-bit PC-relative offset to the PC-relative
/// anchor for the TLE GD GOT entry.
pub const R_LARCH_TLS_GD_PC_HI20: u32 = 97;
/// 12..=31 bits of TLS GD GOT entry 32/64-bit absolute address
pub const R_LARCH_TLS_GD_HI20: u32 = 98;
/// 32-bit PC relative
pub const R_LARCH_32_PCREL: u32 = 99;
/// Paired with a normal relocation at the same address to indicate the
/// insturction can be relaxed
pub const R_LARCH_RELAX: u32 = 100;

unsafe_impl_endian_pod!(
FileHeader32,
Expand Down
13 changes: 13 additions & 0 deletions src/read/elf/relocation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,19 @@ fn parse_relocation<Elf: FileHeader>(
elf::EM_LOONGARCH => match reloc.r_type(endian, false) {
elf::R_LARCH_32 => (RelocationKind::Absolute, 32),
elf::R_LARCH_64 => (RelocationKind::Absolute, 64),
elf::R_LARCH_32_PCREL => (RelocationKind::Relative, 32),
elf::R_LARCH_B16 => {
encoding = RelocationEncoding::LoongArchBranch;
(RelocationKind::Relative, 16)
}
elf::R_LARCH_B21 => {
encoding = RelocationEncoding::LoongArchBranch;
(RelocationKind::Relative, 21)
}
elf::R_LARCH_B26 => {
encoding = RelocationEncoding::LoongArchBranch;
(RelocationKind::Relative, 26)
}
r_type => (RelocationKind::Elf(r_type), 0),
},
elf::EM_MIPS => match reloc.r_type(endian, is_mips64el) {
Expand Down
19 changes: 19 additions & 0 deletions src/write/elf/object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -528,6 +528,25 @@ impl<'a> Object<'a> {
{
(RelocationKind::Absolute, _, 32) => elf::R_LARCH_32,
(RelocationKind::Absolute, _, 64) => elf::R_LARCH_64,
(RelocationKind::Relative, _, 32) => elf::R_LARCH_32_PCREL,
(RelocationKind::Relative, RelocationEncoding::LoongArchBranch, 16)
| (
RelocationKind::PltRelative,
RelocationEncoding::LoongArchBranch,
16,
) => elf::R_LARCH_B16,
(RelocationKind::Relative, RelocationEncoding::LoongArchBranch, 21)
| (
RelocationKind::PltRelative,
RelocationEncoding::LoongArchBranch,
21,
) => elf::R_LARCH_B21,
(RelocationKind::Relative, RelocationEncoding::LoongArchBranch, 26)
| (
RelocationKind::PltRelative,
RelocationEncoding::LoongArchBranch,
26,
) => elf::R_LARCH_B26,
(RelocationKind::Elf(x), _, _) => x,
_ => {
return Err(Error(format!("unimplemented relocation {:?}", reloc)));
Expand Down