Skip to content
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
4 changes: 3 additions & 1 deletion src/artifact.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ use std::io::Write;
use crate::{elf, mach};

pub(crate) mod decl;
pub use crate::artifact::decl::{DataType, Decl, DefinedDecl, ImportKind, Scope, Visibility};
pub use crate::artifact::decl::{
DataType, Decl, DefinedDecl, ImportKind, Scope, SectionKind, Visibility,
};

/// A blob of binary bytes, representing a function body, or data object
pub type Data = Vec<u8>;
Expand Down
76 changes: 53 additions & 23 deletions src/artifact/decl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,8 +169,8 @@ pub enum DefinedDecl {
Function(FunctionDecl),
/// A data object defined in this artifact
Data(DataDecl),
/// A DWARF debug section defined in this artifact
DebugSection(DebugSectionDecl),
/// A section defined in this artifact
Section(SectionDecl),
}

impl DefinedDecl {
Expand All @@ -190,10 +190,10 @@ impl DefinedDecl {
}
}

/// Accessor to determine whether variant is DebugSection
pub fn is_debug_section(&self) -> bool {
/// Accessor to determine whether variant is Section
pub fn is_section(&self) -> bool {
match self {
DefinedDecl::DebugSection { .. } => true,
DefinedDecl::Section(_) => true,
_ => false,
}
}
Expand All @@ -203,15 +203,16 @@ impl DefinedDecl {
match self {
DefinedDecl::Function(a) => a.is_global(),
DefinedDecl::Data(a) => a.is_global(),
DefinedDecl::DebugSection(a) => a.is_global(),
DefinedDecl::Section(a) => a.is_global(),
}
}

/// Accessor to determine whether contents are writable
pub fn is_writable(&self) -> bool {
match self {
DefinedDecl::Data(a) => a.is_writable(),
DefinedDecl::Function(_) | DefinedDecl::DebugSection(_) => false,
DefinedDecl::Function(_) => false,
DefinedDecl::Section(a) => a.is_writable(),
}
}
}
Expand All @@ -237,9 +238,9 @@ impl Decl {
pub fn cstring() -> DataDecl {
DataDecl::default().with_datatype(DataType::String)
}
/// A DWARF debug section defined in this artifact
pub fn debug_section() -> DebugSectionDecl {
DebugSectionDecl::default()
/// A section defined in this artifact
pub fn section(kind: SectionKind) -> SectionDecl {
SectionDecl::new(kind)
}

/// If it is compatible, absorb the new declaration (`other`) into the old (`self`); otherwise returns an error.
Expand Down Expand Up @@ -343,7 +344,7 @@ impl Decl {
/// Is this a section?
pub fn is_section(&self) -> bool {
match *self {
Decl::Defined(DefinedDecl::DebugSection { .. }) => true,
Decl::Defined(DefinedDecl::Section { .. }) => true,
_ => false,
}
}
Expand Down Expand Up @@ -438,6 +439,7 @@ impl DataDecl {
visibility_methods!();
datatype_methods!();
align_methods!();

/// Builder for writability
pub fn with_writable(mut self, writable: bool) -> Self {
self.writable = writable;
Expand Down Expand Up @@ -468,33 +470,61 @@ impl Into<Decl> for DataDecl {
}

#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
/// Builder for a debug section declaration
pub struct DebugSectionDecl {
/// The kind of this section
pub enum SectionKind {
/// Mutable data
Data,

/// DWARF debug info
Debug,

/// Code or read-only data
Text,
}

#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
/// Builder for a section declaration
pub struct SectionDecl {
kind: SectionKind,
datatype: DataType,
align: Option<usize>,
}

impl DebugSectionDecl {
impl SectionDecl {
datatype_methods!();
align_methods!();
/// Debug sections are never global, but we have an accessor

/// Create a `SectionDecl` of the given kind
pub fn new(kind: SectionKind) -> Self {
SectionDecl {
kind,
datatype: DataType::Bytes,
align: None,
}
}

/// Sections are never global, but we have an accessor
/// for symmetry with other section declarations
pub fn is_global(&self) -> bool {
false
}
}

impl Default for DebugSectionDecl {
fn default() -> Self {
DebugSectionDecl {
datatype: DataType::Bytes,
align: None,
/// Accessor to determine whether contents are writable
pub fn is_writable(&self) -> bool {
match self.kind {
SectionKind::Data => true,
SectionKind::Debug | SectionKind::Text => false,
}
}

/// Get the kind for this `SectionDecl`
pub fn kind(&self) -> SectionKind {
self.kind
}
}

impl Into<Decl> for DebugSectionDecl {
impl Into<Decl> for SectionDecl {
fn into(self) -> Decl {
Decl::Defined(DefinedDecl::DebugSection(self))
Decl::Defined(DefinedDecl::Section(self))
}
}
12 changes: 8 additions & 4 deletions src/bin/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use failure::Error;
use structopt::StructOpt;
use target_lexicon::{Architecture, BinaryFormat, Environment, OperatingSystem, Triple, Vendor};

use faerie::{ArtifactBuilder, Decl, Link, Reloc};
use faerie::{ArtifactBuilder, Decl, Link, Reloc, SectionKind};
use std::env;
use std::fs::File;
use std::path::Path;
Expand Down Expand Up @@ -159,6 +159,10 @@ fn run (args: Args) -> Result<(), Error> {
// .data static references need to be zero'd out explicitly for now.
obj.define("STATIC_REF", vec![0; 8])?;

// define a custom section
obj.declare(".faerie", Decl::section(SectionKind::Data))?;
obj.define(".faerie", b"some data".to_vec())?;

// Next, we declare our relocations,
// which are _always_ relative to the `from` symbol
// -- main relocations --
Expand Down Expand Up @@ -209,9 +213,9 @@ fn deadbeef (args: Args) -> Result<(), Error> {

if args.dwarf {
// DWARF sections
obj.declare(".debug_abbrev", Decl::debug_section())?;
obj.declare(".debug_info", Decl::debug_section())?;
obj.declare(".debug_str", Decl::debug_section())?;
obj.declare(".debug_abbrev", Decl::section(SectionKind::Debug))?;
obj.declare(".debug_info", Decl::section(SectionKind::Debug))?;
obj.declare(".debug_str", Decl::section(SectionKind::Debug))?;

obj.define(".debug_str",
concat![
Expand Down
10 changes: 5 additions & 5 deletions src/elf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ impl<'a> SymbolBuilder<'a> {
st_info = STT_NOTYPE;
st_info |= STB_GLOBAL << 4;
}
SymbolType::Decl(DefinedDecl::DebugSection(_)) | SymbolType::Section => {
SymbolType::Decl(DefinedDecl::Section(_)) | SymbolType::Section => {
st_info |= STT_SECTION;
st_info |= STB_LOCAL << 4;
}
Expand Down Expand Up @@ -479,7 +479,7 @@ impl<'a> Elf<'a> {
if d.is_writable() { "data" } else { "rodata" },
name
),
DefinedDecl::DebugSection(_) => name.to_owned(),
DefinedDecl::Section(_) => name.to_owned(),
};

let section = match decl {
Expand All @@ -498,7 +498,7 @@ impl<'a> Elf<'a> {
.writable(d.is_writable())
.exec(false)
.align(d.get_align()),
DefinedDecl::DebugSection(d) => SectionBuilder::new(def_size as u64)
DefinedDecl::Section(d) => SectionBuilder::new(def_size as u64)
.section_type(
// TODO: this behavior should be deprecated, but we need to warn users!
if name == ".debug_str" || name == ".debug_line_str" {
Expand Down Expand Up @@ -537,8 +537,8 @@ impl<'a> Elf<'a> {
self.nlocals += 1;
}
}
DefinedDecl::DebugSection(_) => {
// No symbols in debug sections, yet...
DefinedDecl::Section(_) => {
// No symbols in custom sections, yet...
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ mod target;
pub mod artifact;
pub use crate::artifact::{
decl::{
DataDecl, DataImportDecl, DataType, DebugSectionDecl, Decl, FunctionDecl,
FunctionImportDecl, Scope, Visibility,
DataDecl, DataImportDecl, DataType, Decl, FunctionDecl, FunctionImportDecl, Scope,
SectionDecl, SectionKind, Visibility,
},
Artifact, ArtifactBuilder, ArtifactError, ImportKind, Link, Reloc,
};
Loading