forked from mtahmed/rust.ko
-
Notifications
You must be signed in to change notification settings - Fork 0
/
fixup.rs
executable file
·70 lines (61 loc) · 1.91 KB
/
fixup.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
extern crate core;
use core::fmt::Display;
use std::fs::File;
use std::os;
use std::path::Path;
use std::process::Command;
use std::io::Read;
use std::io::Write;
use std::num::from_str_radix;
use std::str::{from_utf8};
// argument: name of a .ko-file containing 'rust_main'
// result: relocation section attributes (entries, offset)
fn readelf(file: &Path) -> (uint, uint) {
let filename = file.to_str().unwrap();
match Command::new("readelf").arg("-r").arg(filename).output() {
Err(e) => panic!("failed to execute readelf: {}", e),
Ok (out) => from_utf8(out.stdout.as_slice()).map(parse).unwrap()
}
}
fn print_vec<T: Display>(v: &[T]) {
for i in v.iter() {
println!("{}", i)
}
}
fn parse(s: &str) -> (uint, uint) {
for line in s.lines() {
if line.starts_with("Relocation section '.rela.text.rust_main'") {
let x1 : Vec<&str> = line.words().collect();
print_vec(x1.as_slice());
let ent: uint = from_str_radix(x1[7], 10).unwrap();
let off: uint = from_str_radix(x1[5].slice_from(2), 16).unwrap();
return (ent, off);
}
}
return (0, 0);
}
fn patch(ent: uint, off: uint, buf: &mut [u8]) {
for i in range (0, ent) {
let rel = off + 24*i + 8;
if buf[rel] == 0x4 {
println!("Fixup: 0x{}", rel);
buf[rel] = 0x2;
}
}
}
fn main() {
let args = os::args();
if args.len() != 2 {
println!("[usage] fixup [ko]");
return;
}
let filepath = &Path::new(args[1].as_slice());
let mut buf: Vec<u8> = Vec::new();
if File::open(filepath).unwrap().read_to_end(&mut buf).is_err() {
panic!("failed to open or read file: {}", filepath.to_str().unwrap());
}
let (ent, off) = readelf(filepath);
patch(ent, off, buf.as_mut_slice());
let mut file = File::create(filepath).unwrap();
file.write(buf.as_slice()).unwrap();
}