Skip to content

Commit 92bfdcc

Browse files
authored
elf: fix elf conversion script (#399)
1 parent 6861316 commit 92bfdcc

File tree

2 files changed

+94
-23
lines changed

2 files changed

+94
-23
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@ test/self_test
77
dump
88
protosol
99
env/
10+
opt/

src/bin/convert_elf.rs

Lines changed: 93 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,57 +2,127 @@ use flatbuffers::FlatBufferBuilder;
22
use prost::Message;
33
use solfuzz_agave::context_generated as fbs_ctx;
44
use solfuzz_agave::elf_generated as fbs_elf;
5+
use solfuzz_agave::metadata_generated as fbs_meta;
56
use solfuzz_agave::proto as pb;
7+
use solfuzz_agave::utils::fd_hash::{fd_hash_u64_without_seed, fd_hash_without_seed};
68
use std::env;
79
use std::fs;
810
use std::io;
911
use std::path::PathBuf;
1012

11-
fn convert_ctx_proto_to_flatbuf(input: &pb::ElfLoaderCtx) -> Vec<u8> {
12-
let mut fbb = FlatBufferBuilder::new();
13+
fn convert_fixture_proto_to_flatbuf(input: &pb::ElfLoaderFixture) -> Vec<u8> {
14+
let mut fbb: FlatBufferBuilder<'_> = FlatBufferBuilder::new();
15+
16+
// metadata
17+
let fn_entrypoint = input
18+
.metadata
19+
.as_ref()
20+
.map(|m| m.fn_entrypoint.as_str())
21+
.unwrap_or("");
22+
let fn_entrypoint_off = fbb.create_string(fn_entrypoint);
23+
let metadata_off = fbs_meta::FixtureMetadata::create(
24+
&mut fbb,
25+
&fbs_meta::FixtureMetadataArgs {
26+
fn_entrypoint: Some(fn_entrypoint_off),
27+
},
28+
);
1329

1430
// input ctx
15-
let features_off = input.features.as_ref().map(|features| {
16-
let vec_off = fbb.create_vector(&features.features);
17-
fbs_ctx::FeatureSet::create(
18-
&mut fbb,
19-
&fbs_ctx::FeatureSetArgs {
20-
features: Some(vec_off),
21-
},
22-
)
23-
});
31+
let ctx = input.input.as_ref();
32+
let feature_values: &[u64] = ctx
33+
.and_then(|c| c.features.as_ref())
34+
.map(|features| features.features.as_slice())
35+
.unwrap_or(&[]);
36+
let features_vec = fbb.create_vector(feature_values);
37+
let features_off = Some(fbs_ctx::FeatureSet::create(
38+
&mut fbb,
39+
&fbs_ctx::FeatureSetArgs {
40+
features: Some(features_vec),
41+
},
42+
));
2443

25-
let elf_off = input
26-
.elf
27-
.as_ref()
28-
.map(|elf| fbb.create_vector(elf.data.as_slice()));
44+
let elf_bytes: &[u8] = ctx
45+
.and_then(|c| c.elf.as_ref())
46+
.map(|elf| elf.data.as_slice())
47+
.unwrap_or(&[]);
48+
let elf_off = Some(fbb.create_vector(elf_bytes));
2949

50+
let deploy_checks = ctx.map(|c| c.deploy_checks).unwrap_or(false);
3051
let ctx_off = fbs_elf::ELFLoaderCtx::create(
3152
&mut fbb,
3253
&fbs_elf::ELFLoaderCtxArgs {
3354
elf_data: elf_off,
3455
features: features_off,
35-
deploy_checks: input.deploy_checks,
56+
deploy_checks,
57+
},
58+
);
59+
60+
// output effects
61+
let output = input.output.as_ref();
62+
let error = output.map(|o| o.error).unwrap_or(0) as u8;
63+
let text_cnt = output.map(|o| o.text_cnt).unwrap_or(0);
64+
let text_off = output.map(|o| o.text_off).unwrap_or(0);
65+
let entry_pc = output.map(|o| o.entry_pc).unwrap_or(0);
66+
67+
// Compute rodata hash
68+
let rodata_hash = output.and_then(|o| {
69+
if !o.rodata.is_empty() {
70+
let hash_u64 = fd_hash_without_seed(&o.rodata);
71+
Some(fbs_ctx::XXHash::new(&hash_u64.to_le_bytes()))
72+
} else {
73+
None
74+
}
75+
});
76+
77+
// Compute calldests hash
78+
let calldests_hash = output.and_then(|o| {
79+
if !o.calldests.is_empty() {
80+
let hash_u64 = unsafe { fd_hash_u64_without_seed(o.calldests.as_slice()) };
81+
Some(fbs_ctx::XXHash::new(&hash_u64.to_le_bytes()))
82+
} else {
83+
None
84+
}
85+
});
86+
87+
let effects_off = fbs_elf::ELFLoaderEffects::create(
88+
&mut fbb,
89+
&fbs_elf::ELFLoaderEffectsArgs {
90+
err_code: error,
91+
rodata_hash: rodata_hash.as_ref(),
92+
text_cnt,
93+
text_off,
94+
entry_pc,
95+
calldests_hash: calldests_hash.as_ref(),
96+
},
97+
);
98+
99+
// fixture
100+
let fixture_off = fbs_elf::ELFLoaderFixture::create(
101+
&mut fbb,
102+
&fbs_elf::ELFLoaderFixtureArgs {
103+
metadata: Some(metadata_off),
104+
input: Some(ctx_off),
105+
output: Some(effects_off),
36106
},
37107
);
38108

39-
fbb.finish(ctx_off, None);
109+
fbb.finish(fixture_off, None);
40110
fbb.finished_data().to_vec()
41111
}
42112

43113
fn read_file(path: &PathBuf) -> io::Result<Vec<u8>> {
44114
fs::read(path)
45115
}
46116

47-
fn decode_ctx(bytes: &[u8]) -> Result<pb::ElfLoaderCtx, prost::DecodeError> {
48-
pb::ElfLoaderCtx::decode(bytes)
117+
fn decode_fixture(bytes: &[u8]) -> Result<pb::ElfLoaderFixture, prost::DecodeError> {
118+
pb::ElfLoaderFixture::decode(bytes)
49119
}
50120

51121
fn process_file(path: &PathBuf, out_dir: &PathBuf) -> i32 {
52122
match read_file(path) {
53-
Ok(bytes) => match decode_ctx(&bytes) {
54-
Ok(ctx) => {
55-
let out = convert_ctx_proto_to_flatbuf(&ctx);
123+
Ok(bytes) => match decode_fixture(&bytes) {
124+
Ok(fixture) => {
125+
let out = convert_fixture_proto_to_flatbuf(&fixture);
56126
// Write to output directory with same filename
57127
if let Err(e) = fs::create_dir_all(out_dir) {
58128
eprintln!(
@@ -83,7 +153,7 @@ fn process_file(path: &PathBuf, out_dir: &PathBuf) -> i32 {
83153
}
84154
Err(e) => {
85155
eprintln!(
86-
"{}: failed to decode protobuf ElfLoaderCtx: {}",
156+
"{}: failed to decode protobuf ElfLoaderFixture: {}",
87157
path.display(),
88158
e
89159
);

0 commit comments

Comments
 (0)