s390x: Enable object backend (#4680)
This enables the object backend for s390x, in particular the processing of all required relocations. This uncovered a bug: we need to use PLT relocations for the target of calls, which we currently do not. Fixed by adding a new S390xPLTRel32Dbl reloc type and using it where needed.
This commit is contained in:
@@ -43,6 +43,8 @@ pub enum Reloc {
|
|||||||
Arm64Call,
|
Arm64Call,
|
||||||
/// s390x PC-relative 4-byte offset
|
/// s390x PC-relative 4-byte offset
|
||||||
S390xPCRel32Dbl,
|
S390xPCRel32Dbl,
|
||||||
|
/// s390x PC-relative 4-byte offset to PLT
|
||||||
|
S390xPLTRel32Dbl,
|
||||||
|
|
||||||
/// Elf x86_64 32 bit signed PC relative offset to two GOT entries for GD symbol.
|
/// Elf x86_64 32 bit signed PC relative offset to two GOT entries for GD symbol.
|
||||||
ElfX86_64TlsGd,
|
ElfX86_64TlsGd,
|
||||||
@@ -74,6 +76,7 @@ impl fmt::Display for Reloc {
|
|||||||
Self::Abs4 => write!(f, "Abs4"),
|
Self::Abs4 => write!(f, "Abs4"),
|
||||||
Self::Abs8 => write!(f, "Abs8"),
|
Self::Abs8 => write!(f, "Abs8"),
|
||||||
Self::S390xPCRel32Dbl => write!(f, "PCRel32Dbl"),
|
Self::S390xPCRel32Dbl => write!(f, "PCRel32Dbl"),
|
||||||
|
Self::S390xPLTRel32Dbl => write!(f, "PLTRel32Dbl"),
|
||||||
Self::X86PCRel4 => write!(f, "PCRel4"),
|
Self::X86PCRel4 => write!(f, "PCRel4"),
|
||||||
Self::X86CallPCRel4 => write!(f, "CallPCRel4"),
|
Self::X86CallPCRel4 => write!(f, "CallPCRel4"),
|
||||||
Self::X86CallPLTRel4 => write!(f, "CallPLTRel4"),
|
Self::X86CallPLTRel4 => write!(f, "CallPLTRel4"),
|
||||||
|
|||||||
@@ -3216,7 +3216,7 @@ impl MachInstEmit for Inst {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let opcode = 0xc05; // BRASL
|
let opcode = 0xc05; // BRASL
|
||||||
let reloc = Reloc::S390xPCRel32Dbl;
|
let reloc = Reloc::S390xPLTRel32Dbl;
|
||||||
if let Some(s) = state.take_stack_map() {
|
if let Some(s) = state.take_stack_map() {
|
||||||
sink.add_stack_map(StackMapExtent::UpcomingBytes(6), s);
|
sink.add_stack_map(StackMapExtent::UpcomingBytes(6), s);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3077,6 +3077,7 @@ impl MachInstLabelUse for LabelUse {
|
|||||||
fn from_reloc(reloc: Reloc, addend: Addend) -> Option<Self> {
|
fn from_reloc(reloc: Reloc, addend: Addend) -> Option<Self> {
|
||||||
match (reloc, addend) {
|
match (reloc, addend) {
|
||||||
(Reloc::S390xPCRel32Dbl, 2) => Some(LabelUse::PCRel32Dbl),
|
(Reloc::S390xPCRel32Dbl, 2) => Some(LabelUse::PCRel32Dbl),
|
||||||
|
(Reloc::S390xPLTRel32Dbl, 2) => Some(LabelUse::PCRel32Dbl),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ impl CompiledBlob {
|
|||||||
write_unaligned(at as *mut i32, pcrel)
|
write_unaligned(at as *mut i32, pcrel)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
Reloc::S390xPCRel32Dbl => {
|
Reloc::S390xPCRel32Dbl | Reloc::S390xPLTRel32Dbl => {
|
||||||
let base = get_address(name);
|
let base = get_address(name);
|
||||||
let what = unsafe { base.offset(isize::try_from(addend).unwrap()) };
|
let what = unsafe { base.offset(isize::try_from(addend).unwrap()) };
|
||||||
let pcrel = i32::try_from(((what as isize) - (at as isize)) >> 1).unwrap();
|
let pcrel = i32::try_from(((what as isize) - (at as isize)) >> 1).unwrap();
|
||||||
|
|||||||
@@ -73,6 +73,7 @@ impl ObjectBuilder {
|
|||||||
target_lexicon::Architecture::X86_64 => object::Architecture::X86_64,
|
target_lexicon::Architecture::X86_64 => object::Architecture::X86_64,
|
||||||
target_lexicon::Architecture::Arm(_) => object::Architecture::Arm,
|
target_lexicon::Architecture::Arm(_) => object::Architecture::Arm,
|
||||||
target_lexicon::Architecture::Aarch64(_) => object::Architecture::Aarch64,
|
target_lexicon::Architecture::Aarch64(_) => object::Architecture::Aarch64,
|
||||||
|
target_lexicon::Architecture::S390x => object::Architecture::S390x,
|
||||||
architecture => {
|
architecture => {
|
||||||
return Err(ModuleError::Backend(anyhow!(
|
return Err(ModuleError::Backend(anyhow!(
|
||||||
"target architecture {:?} is unsupported",
|
"target architecture {:?} is unsupported",
|
||||||
@@ -647,6 +648,36 @@ impl ObjectModule {
|
|||||||
12,
|
12,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
Reloc::S390xPCRel32Dbl => (RelocationKind::Relative, RelocationEncoding::S390xDbl, 32),
|
||||||
|
Reloc::S390xPLTRel32Dbl => (
|
||||||
|
RelocationKind::PltRelative,
|
||||||
|
RelocationEncoding::S390xDbl,
|
||||||
|
32,
|
||||||
|
),
|
||||||
|
Reloc::S390xTlsGd64 => {
|
||||||
|
assert_eq!(
|
||||||
|
self.object.format(),
|
||||||
|
object::BinaryFormat::Elf,
|
||||||
|
"S390xTlsGd64 is not supported for this file format"
|
||||||
|
);
|
||||||
|
(
|
||||||
|
RelocationKind::Elf(object::elf::R_390_TLS_GD64),
|
||||||
|
RelocationEncoding::Generic,
|
||||||
|
64,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Reloc::S390xTlsGdCall => {
|
||||||
|
assert_eq!(
|
||||||
|
self.object.format(),
|
||||||
|
object::BinaryFormat::Elf,
|
||||||
|
"S390xTlsGdCall is not supported for this file format"
|
||||||
|
);
|
||||||
|
(
|
||||||
|
RelocationKind::Elf(object::elf::R_390_TLS_GDCALL),
|
||||||
|
RelocationEncoding::Generic,
|
||||||
|
0,
|
||||||
|
)
|
||||||
|
}
|
||||||
// FIXME
|
// FIXME
|
||||||
reloc => unimplemented!("{:?}", reloc),
|
reloc => unimplemented!("{:?}", reloc),
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user