Skip to content

Commit

Permalink
add alignment from decl through to elf
Browse files Browse the repository at this point in the history
  • Loading branch information
Pat Hickey committed Feb 21, 2019
1 parent 89c83d3 commit d59a348
Show file tree
Hide file tree
Showing 2 changed files with 145 additions and 118 deletions.
219 changes: 123 additions & 96 deletions src/artifact/decl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,39 @@ pub enum Scope {
Weak,
}

macro_rules! scope_methods {
() => {
/// Set scope to global
pub fn global(self) -> Self {
self.with_scope(Scope::Global)
}
/// Set scope to local
pub fn local(self) -> Self {
self.with_scope(Scope::Local)
}
/// Set scope to weak
pub fn weak(self) -> Self {
self.with_scope(Scope::Weak)
}
/// Builder for scope
pub fn with_scope(mut self, scope: Scope) -> Self {
self.scope = scope;
self
}
/// Gst scope
pub fn get_scope(&self) -> Scope {
self.scope
}
/// Set scope
pub fn set_scope(&mut self, scope: Scope) {
self.scope = scope;
}
/// Check if scope is `Scope::Global`
pub fn is_global(&self) -> bool {
self.scope == Scope::Global
}
}}

#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
/// Linker visibility of a definition
pub enum Visibility {
Expand All @@ -54,6 +87,80 @@ pub enum Visibility {
Hidden,
}

macro_rules! visibility_methods {
() => {
/// Set visibility to default
pub fn default_visibility(self) -> Self {
self.with_visibility(Visibility::Default)
}
/// Set visibility to protected
pub fn protected(self) -> Self {
self.with_visibility(Visibility::Protected)
}
/// Set visibility to hidden
pub fn hidden(self) -> Self {
self.with_visibility(Visibility::Hidden)
}
/// Builder for visibility
pub fn with_visibility(mut self, visibility: Visibility) -> Self {
self.visibility =visibility;
self
}
/// Get visibility
pub fn get_visibility(&self) -> Visibility {
self.visibility
}
/// Set visibility
pub fn set_visibility(&mut self, visibility: Visibility) {
self.visibility = visibility;
}
}}

#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
/// Type of data declared
pub enum DataType {
/// Ordinary raw bytes
Bytes,
/// 0-terminated ascii string
String,
}

macro_rules! datatype_methods {
() => {
/// Build datatype
pub fn with_datatype(mut self, datatype: DataType) -> Self {
self.datatype = datatype;
self
}
/// Set datatype
pub fn set_datatype(&mut self, datatype: DataType) {
self.datatype = datatype;
}
/// Get datatype
pub fn get_datatype(&self) -> DataType {
self.datatype
}
}
}

macro_rules! align_methods {
() => {
/// Build alignment
pub fn with_align(mut self, align: Option<usize>) -> Self {
self.align = align;
self
}
/// Set alignment
pub fn set_align(&mut self, align: Option<usize>) {
self.align = align;
}
/// Get alignment
pub fn get_align(&self) -> Option<usize> {
self.align
}
}
}

#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
/// A declaration that is defined inside this artifact
pub enum DefinedDecl {
Expand Down Expand Up @@ -103,9 +210,7 @@ impl DefinedDecl {
pub fn is_writable(&self) -> bool {
match self {
DefinedDecl::Data(a) => a.is_writable(),
DefinedDecl::Function(_) | DefinedDecl::DebugSection(_) => {
false
}
DefinedDecl::Function(_) | DefinedDecl::DebugSection(_) => false,
}
}
}
Expand Down Expand Up @@ -275,87 +380,28 @@ impl Into<Decl> for DataImportDecl {
}
}

macro_rules! scope_methods {
() => {
/// Set scope to global
pub fn global(self) -> Self {
self.with_scope(Scope::Global)
}
/// Set scope to local
pub fn local(self) -> Self {
self.with_scope(Scope::Local)
}
/// Set scope to weak
pub fn weak(self) -> Self {
self.with_scope(Scope::Weak)
}
/// Builder for scope
pub fn with_scope(mut self, scope: Scope) -> Self {
self.scope = scope;
self
}
/// Gst scope
pub fn get_scope(&self) -> Scope {
self.scope
}
/// Set scope
pub fn set_scope(&mut self, scope: Scope) {
self.scope = scope;
}
/// Check if scope is `Scope::Global`
pub fn is_global(&self) -> bool {
self.scope == Scope::Global
}
}}

macro_rules! visibility_methods {
() => {
/// Set visibility to default
pub fn default_visibility(self) -> Self {
self.with_visibility(Visibility::Default)
}
/// Set visibility to protected
pub fn protected(self) -> Self {
self.with_visibility(Visibility::Protected)
}
/// Set visibility to hidden
pub fn hidden(self) -> Self {
self.with_visibility(Visibility::Hidden)
}
/// Builder for visibility
pub fn with_visibility(mut self, visibility: Visibility) -> Self {
self.visibility =visibility;
self
}
/// Get visibility
pub fn get_visibility(&self) -> Visibility {
self.visibility
}
/// Set visibility
pub fn set_visibility(&mut self, visibility: Visibility) {
self.visibility = visibility;
}
}}

#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
/// Builder for function declarations
pub struct FunctionDecl {
scope: Scope,
visibility: Visibility,
align: Option<usize>,
}

impl Default for FunctionDecl {
fn default() -> Self {
FunctionDecl {
scope: Scope::Local,
visibility: Visibility::Default,
align: None,
}
}
}

impl FunctionDecl {
scope_methods!();
visibility_methods!();
align_methods!();
}

impl Into<Decl> for FunctionDecl {
Expand All @@ -364,40 +410,14 @@ impl Into<Decl> for FunctionDecl {
}
}

#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
/// Type of data declared
pub enum DataType {
/// Ordinary raw bytes
Bytes,
/// 0-terminated ascii string
String,
}

#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
/// Builder for data declarations
pub struct DataDecl {
scope: Scope,
visibility: Visibility,
writable: bool,
datatype: DataType,
}

macro_rules! datatype_methods {
() => {
/// Build datatype
pub fn with_datatype(mut self, datatype: DataType) -> Self {
self.datatype = datatype;
self
}
/// Set datatype
pub fn set_datatype(&mut self, datatype: DataType) {
self.datatype = datatype;
}
/// Get datatype
pub fn get_datatype(&self) -> DataType {
self.datatype
}
}
align: Option<usize>,
}

impl Default for DataDecl {
Expand All @@ -407,6 +427,7 @@ impl Default for DataDecl {
visibility: Visibility::Default,
writable: false,
datatype: DataType::Bytes,
align: None,
}
}
}
Expand All @@ -415,6 +436,7 @@ impl DataDecl {
scope_methods!();
visibility_methods!();
datatype_methods!();
align_methods!();
/// Set mutability to writable
pub fn writable(mut self) -> Self {
self.writable = true;
Expand All @@ -429,7 +451,6 @@ impl DataDecl {
pub fn is_writable(&self) -> bool {
self.writable
}

}

impl Into<Decl> for DataDecl {
Expand All @@ -438,13 +459,16 @@ impl Into<Decl> for DataDecl {
}
}


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

impl DebugSectionDecl {
datatype_methods!();
align_methods!();
/// Debug sections are never global, but we have an accessor
/// for symmetry with other section declarations
pub fn is_global(&self) -> bool {
Expand All @@ -454,7 +478,10 @@ impl DebugSectionDecl {

impl Default for DebugSectionDecl {
fn default() -> Self {
DebugSectionDecl { datatype: DataType::Bytes }
DebugSectionDecl {
datatype: DataType::Bytes,
align: None,
}
}
}

Expand Down
44 changes: 22 additions & 22 deletions src/elf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ struct SectionBuilder {
alloc: bool,
size: u64,
name_offset: usize,
align: Option<usize>,
}

impl SectionBuilder {
Expand All @@ -213,6 +214,7 @@ impl SectionBuilder {
alloc: false,
name_offset: 0,
size,
align: None,
}
}
/// Make this section executable
Expand All @@ -230,6 +232,11 @@ impl SectionBuilder {
self.write = writable;
self
}
/// Specify section alignment
pub fn align(mut self, align: Option<usize>) -> Self {
self.align = align;
self
}

/// Set the byte offset of this section's name in the corresponding strtab
pub fn name_offset(mut self, name_offset: usize) -> Self {
Expand Down Expand Up @@ -257,36 +264,29 @@ impl SectionBuilder {
if self.alloc {
shdr.sh_flags |= SHF_ALLOC as u64
}

let align = if let Some(align) = self.align {
align as u64
} else if self.exec {
0x10
} else if self.write {
0x8
} else {
1
};

match self.typ {
SectionType::Bits => {
shdr.sh_addralign = if self.exec {
0x10
} else if self.write {
0x8
} else {
1
};
shdr.sh_type = SHT_PROGBITS
shdr.sh_addralign = align;
shdr.sh_type = SHT_PROGBITS;
}
SectionType::String => {
shdr.sh_addralign = if self.exec {
0x10
} else if self.write {
0x8
} else {
1
};
shdr.sh_addralign = align;
shdr.sh_type = SHT_PROGBITS;
shdr.sh_flags |= (SHF_MERGE | SHF_STRINGS) as u64;
}
SectionType::Data => {
shdr.sh_addralign = if self.exec {
0x10
} else if self.write {
0x8
} else {
1
};
shdr.sh_addralign = align;
shdr.sh_type = SHT_PROGBITS;
}
SectionType::StrTab => {
Expand Down

0 comments on commit d59a348

Please sign in to comment.