rw elf
This commit is contained in:
parent
f4cbd3ca54
commit
42ea48b97f
8 changed files with 132 additions and 31 deletions
7
Cargo.lock
generated
7
Cargo.lock
generated
|
@ -34,6 +34,12 @@ version = "1.2.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "2.33.3"
|
||||
|
@ -126,6 +132,7 @@ name = "rsld"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"byteorder",
|
||||
"structopt",
|
||||
]
|
||||
|
||||
|
|
|
@ -5,4 +5,5 @@ edition = "2018"
|
|||
|
||||
[dependencies]
|
||||
anyhow = "1.0.41"
|
||||
byteorder = "1.4.3"
|
||||
structopt = "0.3.21"
|
||||
|
|
1
ctest/.gitignore
vendored
Normal file
1
ctest/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
bin
|
|
@ -1,13 +1,13 @@
|
|||
CC := clang
|
||||
|
||||
SOURCES := $(shell find -type f -name "*.c")
|
||||
OBJECTS := $(patsubst %.c, bin/%.bin, $(SOURCES))
|
||||
OBJECTS := $(patsubst %.c, bin/%, $(SOURCES))
|
||||
|
||||
CFLAGS := -v -static -fuse-ld=$(shell pwd)/../target/debug/rsld
|
||||
|
||||
all: $(OBJECTS)
|
||||
|
||||
bin/%.bin: %.c bin
|
||||
bin/%: %.c bin
|
||||
$(CC) $(CFLAGS) -o $@ $<
|
||||
|
||||
bin:
|
||||
|
|
47
src/elf.rs
Normal file
47
src/elf.rs
Normal file
|
@ -0,0 +1,47 @@
|
|||
use std::io::{Read, Write};
|
||||
use std::mem::MaybeUninit;
|
||||
|
||||
use anyhow::Result;
|
||||
use byteorder::{LittleEndian, ReadBytesExt};
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct Elf {
|
||||
header: Header,
|
||||
program_header: Option<ProgramHeader>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Header {
|
||||
e_ident: [u8; 16],
|
||||
e_type: u16,
|
||||
e_machine: u16,
|
||||
e_version: u32,
|
||||
}
|
||||
|
||||
impl Default for Header {
|
||||
fn default() -> Self {
|
||||
let mut header: Self = unsafe { MaybeUninit::zeroed().assume_init() };
|
||||
header.e_ident[0] = 0x7f;
|
||||
header.e_ident[1] = b'E';
|
||||
header.e_ident[2] = b'L';
|
||||
header.e_ident[3] = b'F';
|
||||
header
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct ProgramHeader {}
|
||||
|
||||
impl Elf {
|
||||
pub fn read<R: Read>(mut r: R) -> Result<Elf> {
|
||||
let mut elf = Elf::default();
|
||||
|
||||
// header
|
||||
r.read_exact(&mut elf.header.e_ident)?;
|
||||
elf.header.e_type = r.read_u16::<LittleEndian>()?;
|
||||
|
||||
Ok(elf)
|
||||
}
|
||||
|
||||
pub fn write<W: Write>(&self, mut w: W) {}
|
||||
}
|
33
src/link.rs
33
src/link.rs
|
@ -1,5 +1,34 @@
|
|||
use crate::Opt;
|
||||
use std::fs::{File, OpenOptions};
|
||||
use std::os::unix::fs::OpenOptionsExt;
|
||||
|
||||
pub(crate) fn link(opt: &Opt) {
|
||||
use anyhow::{Context, Result};
|
||||
|
||||
use crate::elf::Elf;
|
||||
use crate::{LinkUnit, Opt};
|
||||
|
||||
pub(crate) fn link(opt: &Opt) -> Result<()> {
|
||||
for unit in &opt.units {
|
||||
match unit {
|
||||
LinkUnit::Path(path) => {
|
||||
let file = File::open(path)?;
|
||||
let elf = Elf::read(&file)?;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
let res = Elf::default();
|
||||
if let Some(path) = &opt.out {
|
||||
let path = crate::utils::normalize_path(path);
|
||||
let file = OpenOptions::new()
|
||||
.create(true)
|
||||
.write(true)
|
||||
.mode(0o755)
|
||||
.open(&path)
|
||||
.with_context(|| format!("could not create output file {:?}", path))?;
|
||||
res.write(file);
|
||||
println!("wrote to {:?}", path);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
42
src/main.rs
42
src/main.rs
|
@ -1,8 +1,12 @@
|
|||
mod elf;
|
||||
mod link;
|
||||
mod utils;
|
||||
|
||||
use std::env;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use anyhow::Result;
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
struct Opt {
|
||||
eh_frame_hdr: bool,
|
||||
|
@ -20,7 +24,7 @@ enum LinkUnit {
|
|||
Group(Vec<PathBuf>),
|
||||
}
|
||||
|
||||
fn main() {
|
||||
fn main() -> Result<()> {
|
||||
let mut opt = Opt::default();
|
||||
let mut it = env::args();
|
||||
let mut curr_group = None;
|
||||
|
@ -31,44 +35,28 @@ fn main() {
|
|||
while let Some(arg) = it.next() {
|
||||
if arg == "-static" {
|
||||
opt.is_static = true;
|
||||
}
|
||||
|
||||
else if arg == "--eh-frame-hdr" {
|
||||
} else if arg == "--eh-frame-hdr" {
|
||||
opt.eh_frame_hdr = true;
|
||||
}
|
||||
|
||||
else if arg == "-m" {
|
||||
} else if arg == "-m" {
|
||||
let next = it.next().unwrap();
|
||||
opt.emulate = next;
|
||||
}
|
||||
|
||||
else if arg == "-o" {
|
||||
} else if arg == "-o" {
|
||||
let next = it.next().unwrap();
|
||||
opt.out = Some(PathBuf::from(next));
|
||||
}
|
||||
|
||||
else if arg == "--start-group" {
|
||||
} else if arg == "--start-group" {
|
||||
curr_group = Some(Vec::new());
|
||||
}
|
||||
|
||||
else if arg == "--end-group" {
|
||||
} else if arg == "--end-group" {
|
||||
if let Some(curr_group) = curr_group.take() {
|
||||
if !curr_group.is_empty() {
|
||||
opt.units.push(LinkUnit::Group(curr_group));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if arg.starts_with("-L") {
|
||||
} else if arg.starts_with("-L") {
|
||||
let path = PathBuf::from(arg.trim_start_matches("-L"));
|
||||
opt.link_includes.push(path);
|
||||
}
|
||||
|
||||
else if arg.starts_with("-l") {
|
||||
} else if arg.starts_with("-l") {
|
||||
opt.link_to.push(arg.trim_start_matches("-l").to_owned());
|
||||
}
|
||||
|
||||
else {
|
||||
} else {
|
||||
let path = PathBuf::from(&arg);
|
||||
if let Some(curr_group) = curr_group.as_mut() {
|
||||
curr_group.push(path);
|
||||
|
@ -78,7 +66,7 @@ fn main() {
|
|||
}
|
||||
}
|
||||
|
||||
link::link(&opt);
|
||||
link::link(&opt)?;
|
||||
|
||||
println!("opt: {:?}", opt);
|
||||
Ok(())
|
||||
}
|
||||
|
|
28
src/utils.rs
Normal file
28
src/utils.rs
Normal file
|
@ -0,0 +1,28 @@
|
|||
use std::path::{Path, PathBuf, Component};
|
||||
|
||||
pub fn normalize_path(path: &Path) -> PathBuf {
|
||||
let mut components = path.components().peekable();
|
||||
let mut ret = if let Some(c @ Component::Prefix(..)) = components.peek().cloned() {
|
||||
components.next();
|
||||
PathBuf::from(c.as_os_str())
|
||||
} else {
|
||||
PathBuf::new()
|
||||
};
|
||||
|
||||
for component in components {
|
||||
match component {
|
||||
Component::Prefix(..) => unreachable!(),
|
||||
Component::RootDir => {
|
||||
ret.push(component.as_os_str());
|
||||
}
|
||||
Component::CurDir => {}
|
||||
Component::ParentDir => {
|
||||
ret.pop();
|
||||
}
|
||||
Component::Normal(c) => {
|
||||
ret.push(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
ret
|
||||
}
|
Loading…
Reference in a new issue