Skip to content

Commit

Permalink
reloc overrides need addends pushed through as well
Browse files Browse the repository at this point in the history
  • Loading branch information
pchickey committed Dec 6, 2017
1 parent bb53414 commit 66eb3c8
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 14 deletions.
12 changes: 9 additions & 3 deletions src/artifact.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,13 @@ use std::collections::BTreeSet;

use {Target, Data};

type Relocation = (String, String, usize, Option<u32>);
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Copy, Clone)]
pub struct RelocOverride {
pub elftype: u32,
pub addend: u32,
}

type Relocation = (String, String, usize, Option<RelocOverride>);

/// The kinds of errors that can befall someone creating an Artifact
#[derive(Fail, Debug)]
Expand Down Expand Up @@ -90,7 +96,7 @@ pub(crate) struct LinkAndDecl<'a> {
pub from: Binding<'a>,
pub to: Binding<'a>,
pub at: usize,
pub reloc: Option<u32>,
pub reloc: Option<RelocOverride>,
}

/// A definition of a symbol with its properties the various backends receive
Expand Down Expand Up @@ -120,7 +126,7 @@ pub struct Link<'a> {
/// The byte offset _relative_ to `from` where the relocation should be performed
pub at: usize,
/// Relocation type:
pub reloc: Option<u32>,
pub reloc: Option<RelocOverride>,
}

/// The kind of import this is - either a function, or a copy relocation of data from a shared library
Expand Down
30 changes: 20 additions & 10 deletions src/elf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
use goblin;
use failure::Error;
use {artifact, Artifact, Decl, Object, Target, Ctx, ImportKind};
use {artifact, Artifact, Decl, Object, Target, Ctx, ImportKind, RelocOverride};

use std::collections::HashMap;
use std::fmt;
Expand Down Expand Up @@ -437,7 +437,7 @@ impl<'a> Elf<'a> {
self.imports.insert(idx, kind.clone());
self.symbols.insert(idx, symbol);
}
pub fn link(&mut self, from: &str, to: &str, offset: usize, to_type: &Decl, reloctype: Option<u32>) {
pub fn link(&mut self, from: &str, to: &str, offset: usize, to_type: &Decl, reloctype: Option<RelocOverride>) {
let (from_idx, to_idx) = {
let to_idx = self.strings.intern(to).unwrap();
let from_idx = self.strings.intern(from).unwrap();
Expand All @@ -446,16 +446,26 @@ impl<'a> Elf<'a> {
(from_idx, to_idx)
};

let overridable = { |r| if let Some(o) = reloctype { o } else { r } };
let (reloc, addend, sym_idx) = match *to_type {
// NB: this now forces _all_ function references, whether local or not, through the PLT
// although we're not in the worst company here: https://github.com/ocaml/ocaml/pull/1330
Decl::Function {..} => (overridable(reloc::R_X86_64_PLT32), -4, to_idx + 2), // +2 for NOTYPE and FILE symbols
Decl::Data {..} => (overridable(reloc::R_X86_64_PC32), 0, to_idx + 2),
let (reloc, addend) = if let Some(ovr) = reloctype {
(ovr.elftype, ovr.addend as isize)
} else {
match *to_type {
// NB: this now forces _all_ function references, whether local or not, through the PLT
// although we're not in the worst company here: https://github.com/ocaml/ocaml/pull/1330
Decl::Function {..} => (reloc::R_X86_64_PLT32, -4),
Decl::Data {..} => (reloc::R_X86_64_PC32, 0),
Decl::FunctionImport => (reloc::R_X86_64_PLT32, -4),
Decl::DataImport => (reloc::R_X86_64_GOTPCREL, -4),
}
};

let sym_idx = match *to_type {
Decl::Function {..} | Decl::Data {..} => to_idx + 2,
// +2 for NOTYPE and FILE symbols
Decl::FunctionImport | Decl::DataImport => to_idx + self.section_symbols.len(),
// + section_symbols.len() because this is where the import symbols begin
Decl::FunctionImport => (overridable(reloc::R_X86_64_PLT32), -4, to_idx + self.section_symbols.len()),
Decl::DataImport => (overridable(reloc::R_X86_64_GOTPCREL), -4, to_idx + self.section_symbols.len()),
};

let reloc = RelocationBuilder::new(reloc).sym(sym_idx).offset(offset).addend(addend).create();
self.add_reloc(from, reloc, from_idx)
}
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ pub mod mach;
pub use mach::Mach;

pub mod artifact;
pub use artifact::{Object, Artifact, ArtifactBuilder, Link, ImportKind, Decl};
pub use artifact::{Object, Artifact, ArtifactBuilder, Link, ImportKind, Decl, RelocOverride};

#[cfg(test)]
mod tests {
Expand Down

0 comments on commit 66eb3c8

Please sign in to comment.