|
|
@ -24,12 +24,13 @@ use super::ElfObject;
|
|
|
|
|
|
|
|
|
|
|
|
pub struct ElfOutput<'data> {
|
|
|
|
pub struct ElfOutput<'data> {
|
|
|
|
destination: PathBuf,
|
|
|
|
destination: PathBuf,
|
|
|
|
file: ELF64,
|
|
|
|
file: ELF64,
|
|
|
|
input_data: InputData<'data>,
|
|
|
|
input_data: InputData<'data>,
|
|
|
|
|
|
|
|
writer: BufWriter<File>,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl<'data> ElfOutput<'data> {
|
|
|
|
impl<'data> ElfOutput<'data> {
|
|
|
|
pub fn new(destination: PathBuf) -> Self {
|
|
|
|
pub fn new(destination: PathBuf) -> Result<Self, Error> {
|
|
|
|
use elf_utilities::header::{Class, Data, Machine, Type, Version, OSABI};
|
|
|
|
use elf_utilities::header::{Class, Data, Machine, Type, Version, OSABI};
|
|
|
|
|
|
|
|
|
|
|
|
let mut elf = ELF64::default();
|
|
|
|
let mut elf = ELF64::default();
|
|
|
@ -41,21 +42,33 @@ impl<'data> ElfOutput<'data> {
|
|
|
|
elf.ehdr.set_osabi(OSABI::Linux);
|
|
|
|
elf.ehdr.set_osabi(OSABI::Linux);
|
|
|
|
elf.ehdr.set_data(Data::LSB2);
|
|
|
|
elf.ehdr.set_data(Data::LSB2);
|
|
|
|
|
|
|
|
|
|
|
|
Self {
|
|
|
|
let str_path = expand_path(&destination)?;
|
|
|
|
|
|
|
|
let writer = file_writer(str_path, 0o755)?;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let result = Self {
|
|
|
|
destination,
|
|
|
|
destination,
|
|
|
|
file: elf,
|
|
|
|
file: elf,
|
|
|
|
input_data: InputData::new(),
|
|
|
|
input_data: InputData::new(),
|
|
|
|
}
|
|
|
|
writer,
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Ok(result)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub fn from_object(object: &ElfObject, destination: PathBuf) -> Self {
|
|
|
|
pub fn from_object(object: &ElfObject, destination: PathBuf) -> Result<Self, Error> {
|
|
|
|
let other = object.elf();
|
|
|
|
let other = object.elf();
|
|
|
|
|
|
|
|
|
|
|
|
Self {
|
|
|
|
let str_path = expand_path(&destination)?;
|
|
|
|
|
|
|
|
let writer = file_writer(str_path, 0o755)?;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let result = Self {
|
|
|
|
destination,
|
|
|
|
destination,
|
|
|
|
file: elf_bin_from_object(other),
|
|
|
|
file: elf_bin_from_object(other),
|
|
|
|
input_data: InputData::new(),
|
|
|
|
input_data: InputData::new(),
|
|
|
|
}
|
|
|
|
writer,
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Ok(result)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn populate_sections(&mut self) -> Result<(), Error> {
|
|
|
|
fn populate_sections(&mut self) -> Result<(), Error> {
|
|
|
@ -172,18 +185,15 @@ impl<'data> Output<'data> for ElfOutput<'data> {
|
|
|
|
self.file.ehdr.e_phoff = EHS;
|
|
|
|
self.file.ehdr.e_phoff = EHS;
|
|
|
|
self.file.ehdr.e_shoff = self.file.ehdr.e_phoff + (usize::from(self.file.ehdr.e_phentsize) * self.file.segments.len()) as u64;
|
|
|
|
self.file.ehdr.e_shoff = self.file.ehdr.e_phoff + (usize::from(self.file.ehdr.e_phentsize) * self.file.segments.len()) as u64;
|
|
|
|
|
|
|
|
|
|
|
|
let str_path = expand_path(&self.destination)?;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let mut writer = file_writer(str_path, 0o755)?;
|
|
|
|
|
|
|
|
let mut offset = 0;
|
|
|
|
let mut offset = 0;
|
|
|
|
|
|
|
|
|
|
|
|
// write ELF header
|
|
|
|
// write ELF header
|
|
|
|
offset += writer.write(&self.file.ehdr.to_le_bytes())?;
|
|
|
|
offset += self.writer.write(&self.file.ehdr.to_le_bytes())?;
|
|
|
|
|
|
|
|
|
|
|
|
// write program header table
|
|
|
|
// write program header table
|
|
|
|
for seg in self.file.segments.iter_mut() {
|
|
|
|
for seg in self.file.segments.iter_mut() {
|
|
|
|
seg.header.p_offset = offset as u64;
|
|
|
|
seg.header.p_offset = offset as u64;
|
|
|
|
offset += writer.write(&seg.header.to_le_bytes())?;
|
|
|
|
offset += self.writer.write(&seg.header.to_le_bytes())?;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
eprintln!("SH start: {}", offset);
|
|
|
|
eprintln!("SH start: {}", offset);
|
|
|
@ -192,27 +202,27 @@ impl<'data> Output<'data> for ElfOutput<'data> {
|
|
|
|
if sec.header.get_type() == ShType::StrTab {
|
|
|
|
if sec.header.get_type() == ShType::StrTab {
|
|
|
|
sec.header.sh_offset = offset as u64 + u64::from(SHS);
|
|
|
|
sec.header.sh_offset = offset as u64 + u64::from(SHS);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
offset += writer.write(&sec.header.to_le_bytes())?;
|
|
|
|
offset += self.writer.write(&sec.header.to_le_bytes())?;
|
|
|
|
if sec.header.get_type() == ShType::StrTab {
|
|
|
|
if sec.header.get_type() == ShType::StrTab {
|
|
|
|
offset += writer.write(&sec.to_le_bytes())?;
|
|
|
|
offset += self.writer.write(&sec.to_le_bytes())?;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// program data (segments)
|
|
|
|
// program data (segments)
|
|
|
|
offset += pad_to_next_page(&mut writer, offset)?;
|
|
|
|
offset += pad_to_next_page(&mut self.writer, offset)?;
|
|
|
|
eprintln!("Prog start: {}", offset);
|
|
|
|
eprintln!("Prog start: {}", offset);
|
|
|
|
// write section/segment data
|
|
|
|
// write section/segment data
|
|
|
|
for bytes in self.input_data.program_bytes() {
|
|
|
|
for bytes in self.input_data.program_bytes() {
|
|
|
|
offset += writer.write(bytes)?;
|
|
|
|
offset += self.writer.write(bytes)?;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
offset += pad_to_next_page(&mut writer, offset)?;
|
|
|
|
offset += pad_to_next_page(&mut self.writer, offset)?;
|
|
|
|
|
|
|
|
|
|
|
|
eprintln!("Data start: {}", offset);
|
|
|
|
eprintln!("Data start: {}", offset);
|
|
|
|
for bytes in self.input_data.data_bytes() {
|
|
|
|
for bytes in self.input_data.data_bytes() {
|
|
|
|
offset += writer.write(bytes)?;
|
|
|
|
offset += self.writer.write(bytes)?;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
writer.flush()?;
|
|
|
|
self.writer.flush()?;
|
|
|
|
|
|
|
|
|
|
|
|
Ok(self.destination)
|
|
|
|
Ok(self.destination)
|
|
|
|
}
|
|
|
|
}
|
|
|
|