fix code padding

This commit is contained in:
Jean-Marie 'Histausse' Mineau 2024-01-27 01:05:49 +01:00
parent a3e9364aa0
commit 2e639fbcee
Signed by: histausse
GPG key ID: B66AEEDA9B645AD2

View file

@ -152,16 +152,25 @@ impl Serializable for CodeItem {
self.outs_size.serialize(output)?;
self.tries_size_field().serialize(output)?;
self.debug_info_off.serialize(output)?;
(self.insns.iter().map(|i| i.size() as u32).sum::<u32>() / 2).serialize(output)?;
let insns_size = self.insns.iter().map(|i| i.size() as u32).sum::<u32>() / 2;
insns_size.serialize(output)?;
for insn in &self.insns {
insn.serialize(output)?;
}
if !self.tries.is_empty() && self.insns.len() % 2 == 1 {
if !self.tries.is_empty() && insns_size % 2 == 1 {
println!("padding");
0u16.serialize(output)?;
}
for item in &self.tries {
item.serialize(output)?;
}
let mut tries = vec![];
for item in &self.tries {
for c in item.serialize_to_vec().unwrap().into_iter() {
tries.push(c);
}
}
println!("tries: {tries:02x?}");
if let Some(ref handlers) = self.handlers {
handlers.serialize(output)?;
}
@ -200,6 +209,18 @@ impl Serializable for CodeItem {
insns.push(ins);
}
if serialized_insns_size != insns_size {
println!(
"{:#?}",
Self {
registers_size,
ins_size,
outs_size,
debug_info_off,
insns,
tries: vec![],
handlers: None,
}
);
return Err(Error::DeserializationError(format!(
"Failed to deserialize instructions, expected size of {insns_size} code \
units (16 bits), found at least {serialized_insns_size}"
@ -228,14 +249,15 @@ impl Serializable for CodeItem {
})
}
fn size(&self) -> usize {
let insns_size = self.insns.iter().map(|i| i.size() as u32).sum::<u32>() / 2;
self.registers_size.size()
+ self.ins_size.size()
+ self.outs_size.size()
+ self.tries_size_field().size()
+ self.debug_info_off.size()
+ 0u32.size()
+ insns_size.size()
+ self.insns.iter().map(|val| val.size()).sum::<usize>()
+ if !self.tries.is_empty() && self.insns.len() % 2 == 1 {
+ if !self.tries.is_empty() && insns_size % 2 == 1 {
2
} else {
0
@ -1217,4 +1239,721 @@ mod test {
assert_eq!(code, CodeItem::deserialize_from_slice(&raw).unwrap());
assert_eq!(code.size(), raw.len());
}
#[test]
fn test_code_with_handler() {
let code = CodeItem {
registers_size: 6,
ins_size: 0,
outs_size: 1,
debug_info_off: 27,
insns: vec![
Format35C {
a: 0,
vg: 0,
op: 113,
b: 4,
vf: 0,
ve: 0,
vd: 0,
vc: 0,
},
Format11X { va: 0, op: 12 },
Format12X {
vb: 0,
va: 0,
op: 33,
},
Format22C {
vb: 0,
va: 0,
op: 35,
c: 27,
},
Format21C {
va: 0,
op: 105,
b: 10,
},
Format11N {
b: 1,
va: 1,
op: 18,
},
Format21C {
va: 2,
op: 98,
b: 11,
},
Format35C {
a: 1,
vg: 0,
op: 110,
b: 3,
vf: 0,
ve: 0,
vd: 0,
vc: 2,
},
Format11X { va: 2, op: 10 },
Format23X {
va: 1,
op: 75,
vc: 2,
vb: 0,
},
Format11N {
b: 2,
va: 0,
op: 18,
},
Format21C {
va: 2,
op: 98,
b: 10,
},
Format21C {
va: 3,
op: 98,
b: 14,
},
Format35C {
a: 1,
vg: 0,
op: 110,
b: 3,
vf: 0,
ve: 0,
vd: 0,
vc: 3,
},
Format11X { va: 3, op: 10 },
Format23X {
va: 0,
op: 75,
vc: 3,
vb: 2,
},
Format11N {
b: 3,
va: 2,
op: 18,
},
Format21C {
va: 3,
op: 98,
b: 10,
},
Format21C {
va: 4,
op: 98,
b: 13,
},
Format35C {
a: 1,
vg: 0,
op: 110,
b: 3,
vf: 0,
ve: 0,
vd: 0,
vc: 4,
},
Format11X { va: 4, op: 10 },
Format23X {
va: 2,
op: 75,
vc: 4,
vb: 3,
},
Format11N {
b: 4,
va: 3,
op: 18,
},
Format21C {
va: 4,
op: 98,
b: 10,
},
Format21C {
va: 5,
op: 98,
b: 12,
},
Format35C {
a: 1,
vg: 0,
op: 110,
b: 3,
vf: 0,
ve: 0,
vd: 0,
vc: 5,
},
Format11X { va: 5, op: 10 },
Format23X {
va: 3,
op: 75,
vc: 5,
vb: 4,
},
Format35C {
a: 0,
vg: 0,
op: 113,
b: 1,
vf: 0,
ve: 0,
vd: 0,
vc: 0,
},
Format11X { va: 4, op: 12 },
Format12X {
vb: 4,
va: 4,
op: 33,
},
Format22C {
vb: 4,
va: 4,
op: 35,
c: 27,
},
Format21C {
va: 4,
op: 105,
b: 9,
},
Format21C {
va: 5,
op: 98,
b: 5,
},
Format35C {
a: 1,
vg: 0,
op: 110,
b: 0,
vf: 0,
ve: 0,
vd: 0,
vc: 5,
},
Format11X { va: 5, op: 10 },
Format23X {
va: 1,
op: 75,
vc: 5,
vb: 4,
},
Format21C {
va: 1,
op: 98,
b: 9,
},
Format21C {
va: 4,
op: 98,
b: 8,
},
Format35C {
a: 1,
vg: 0,
op: 110,
b: 0,
vf: 0,
ve: 0,
vd: 0,
vc: 4,
},
Format11X { va: 4, op: 10 },
Format23X {
va: 0,
op: 75,
vc: 4,
vb: 1,
},
Format21C {
va: 0,
op: 98,
b: 9,
},
Format21C {
va: 1,
op: 98,
b: 7,
},
Format35C {
a: 1,
vg: 0,
op: 110,
b: 0,
vf: 0,
ve: 0,
vd: 0,
vc: 1,
},
Format11X { va: 1, op: 10 },
Format23X {
va: 2,
op: 75,
vc: 1,
vb: 0,
},
Format21C {
va: 0,
op: 98,
b: 9,
},
Format21C {
va: 1,
op: 98,
b: 1,
},
Format35C {
a: 1,
vg: 0,
op: 110,
b: 0,
vf: 0,
ve: 0,
vd: 0,
vc: 1,
},
Format11X { va: 1, op: 10 },
Format23X {
va: 3,
op: 75,
vc: 1,
vb: 0,
},
Format21C {
va: 0,
op: 98,
b: 9,
},
Format21C {
va: 1,
op: 98,
b: 0,
},
Format35C {
a: 1,
vg: 0,
op: 110,
b: 0,
vf: 0,
ve: 0,
vd: 0,
vc: 1,
},
Format11X { va: 1, op: 10 },
Format11N {
b: 5,
va: 2,
op: 18,
},
Format23X {
va: 2,
op: 75,
vc: 1,
vb: 0,
},
Format21C {
va: 0,
op: 98,
b: 9,
},
Format21C {
va: 1,
op: 98,
b: 2,
},
Format35C {
a: 1,
vg: 0,
op: 110,
b: 0,
vf: 0,
ve: 0,
vd: 0,
vc: 1,
},
Format11X { va: 1, op: 10 },
Format11N {
b: 6,
va: 2,
op: 18,
},
Format23X {
va: 2,
op: 75,
vc: 1,
vb: 0,
},
Format21C {
va: 0,
op: 98,
b: 9,
},
Format21C {
va: 1,
op: 98,
b: 3,
},
Format35C {
a: 1,
vg: 0,
op: 110,
b: 0,
vf: 0,
ve: 0,
vd: 0,
vc: 1,
},
Format11X { va: 1, op: 10 },
Format11N {
b: 7,
va: 2,
op: 18,
},
Format23X {
va: 2,
op: 75,
vc: 1,
vb: 0,
},
Format21C {
va: 0,
op: 98,
b: 9,
},
Format21C {
va: 1,
op: 98,
b: 4,
},
Format35C {
a: 1,
vg: 0,
op: 110,
b: 0,
vf: 0,
ve: 0,
vd: 0,
vc: 1,
},
Format11X { va: 1, op: 10 },
Format21S {
va: 2,
op: 19,
b: 8,
},
Format23X {
va: 2,
op: 75,
vc: 1,
vb: 0,
},
Format21C {
va: 0,
op: 98,
b: 9,
},
Format21C {
va: 1,
op: 98,
b: 6,
},
Format35C {
a: 1,
vg: 0,
op: 110,
b: 0,
vf: 0,
ve: 0,
vd: 0,
vc: 1,
},
Format11X { va: 1, op: 10 },
Format21S {
va: 2,
op: 19,
b: 9,
},
Format23X {
va: 2,
op: 75,
vc: 1,
vb: 0,
},
Format10X { op: 14 },
],
tries: vec![
TryItem {
start_addr: 10,
insn_count: 8,
handler_off: 1,
},
TryItem {
start_addr: 19,
insn_count: 10,
handler_off: 4,
},
TryItem {
start_addr: 30,
insn_count: 10,
handler_off: 7,
},
TryItem {
start_addr: 41,
insn_count: 10,
handler_off: 10,
},
TryItem {
start_addr: 60,
insn_count: 8,
handler_off: 13,
},
TryItem {
start_addr: 68,
insn_count: 10,
handler_off: 16,
},
TryItem {
start_addr: 78,
insn_count: 10,
handler_off: 19,
},
TryItem {
start_addr: 88,
insn_count: 10,
handler_off: 22,
},
TryItem {
start_addr: 98,
insn_count: 11,
handler_off: 25,
},
TryItem {
start_addr: 109,
insn_count: 11,
handler_off: 28,
},
TryItem {
start_addr: 120,
insn_count: 11,
handler_off: 31,
},
TryItem {
start_addr: 131,
insn_count: 12,
handler_off: 35,
},
TryItem {
start_addr: 143,
insn_count: 12,
handler_off: 39,
},
],
handlers: Some(EncodedCatchHandlerList {
list: vec![
EncodedCatchHandler {
handlers: vec![EncodedTypeAddrPair {
type_idx: Uleb128(19),
addr: Uleb128(18),
}],
catch_all_addr: None,
},
EncodedCatchHandler {
handlers: vec![EncodedTypeAddrPair {
type_idx: Uleb128(19),
addr: Uleb128(29),
}],
catch_all_addr: None,
},
EncodedCatchHandler {
handlers: vec![EncodedTypeAddrPair {
type_idx: Uleb128(19),
addr: Uleb128(40),
}],
catch_all_addr: None,
},
EncodedCatchHandler {
handlers: vec![EncodedTypeAddrPair {
type_idx: Uleb128(19),
addr: Uleb128(51),
}],
catch_all_addr: None,
},
EncodedCatchHandler {
handlers: vec![EncodedTypeAddrPair {
type_idx: Uleb128(19),
addr: Uleb128(68),
}],
catch_all_addr: None,
},
EncodedCatchHandler {
handlers: vec![EncodedTypeAddrPair {
type_idx: Uleb128(19),
addr: Uleb128(78),
}],
catch_all_addr: None,
},
EncodedCatchHandler {
handlers: vec![EncodedTypeAddrPair {
type_idx: Uleb128(19),
addr: Uleb128(88),
}],
catch_all_addr: None,
},
EncodedCatchHandler {
handlers: vec![EncodedTypeAddrPair {
type_idx: Uleb128(19),
addr: Uleb128(98),
}],
catch_all_addr: None,
},
EncodedCatchHandler {
handlers: vec![EncodedTypeAddrPair {
type_idx: Uleb128(19),
addr: Uleb128(109),
}],
catch_all_addr: None,
},
EncodedCatchHandler {
handlers: vec![EncodedTypeAddrPair {
type_idx: Uleb128(19),
addr: Uleb128(120),
}],
catch_all_addr: None,
},
EncodedCatchHandler {
handlers: vec![EncodedTypeAddrPair {
type_idx: Uleb128(19),
addr: Uleb128(131),
}],
catch_all_addr: None,
},
EncodedCatchHandler {
handlers: vec![EncodedTypeAddrPair {
type_idx: Uleb128(19),
addr: Uleb128(143),
}],
catch_all_addr: None,
},
EncodedCatchHandler {
handlers: vec![EncodedTypeAddrPair {
type_idx: Uleb128(19),
addr: Uleb128(155),
}],
catch_all_addr: None,
},
],
}),
};
let raw = vec![
0x06, 0x00, // registers_size
0x00, 0x00, // ins_size
0x01, 0x00, // outs_size
0x0d, 0x00, // tries_size
0x1b, 0x00, 0x00, 0x00, // debug_info_off
0x9c, 0x00, 0x00, 0x00, // insns_size
0x71, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x21, 0x00, 0x23, 0x00, 0x1b, 0x00,
0x69, 0x00, 0x0a, 0x00, 0x12, 0x11, 0x62, 0x02, 0x0b, 0x00, 0x6e, 0x10, 0x03, 0x00,
0x02, 0x00, 0x0a, 0x02, 0x4b, 0x01, 0x00, 0x02, 0x12, 0x20, 0x62, 0x02, 0x0a, 0x00,
0x62, 0x03, 0x0e, 0x00, 0x6e, 0x10, 0x03, 0x00, 0x03, 0x00, 0x0a, 0x03, 0x4b, 0x00,
0x02, 0x03, 0x12, 0x32, 0x62, 0x03, 0x0a, 0x00, 0x62, 0x04, 0x0d, 0x00, 0x6e, 0x10,
0x03, 0x00, 0x04, 0x00, 0x0a, 0x04, 0x4b, 0x02, 0x03, 0x04, 0x12, 0x43, 0x62, 0x04,
0x0a, 0x00, 0x62, 0x05, 0x0c, 0x00, 0x6e, 0x10, 0x03, 0x00, 0x05, 0x00, 0x0a, 0x05,
0x4b, 0x03, 0x04, 0x05, 0x71, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0c, 0x04, 0x21, 0x44,
0x23, 0x44, 0x1b, 0x00, 0x69, 0x04, 0x09, 0x00, 0x62, 0x05, 0x05, 0x00, 0x6e, 0x10,
0x00, 0x00, 0x05, 0x00, 0x0a, 0x05, 0x4b, 0x01, 0x04, 0x05, 0x62, 0x01, 0x09, 0x00,
0x62, 0x04, 0x08, 0x00, 0x6e, 0x10, 0x00, 0x00, 0x04, 0x00, 0x0a, 0x04, 0x4b, 0x00,
0x01, 0x04, 0x62, 0x00, 0x09, 0x00, 0x62, 0x01, 0x07, 0x00, 0x6e, 0x10, 0x00, 0x00,
0x01, 0x00, 0x0a, 0x01, 0x4b, 0x02, 0x00, 0x01, 0x62, 0x00, 0x09, 0x00, 0x62, 0x01,
0x01, 0x00, 0x6e, 0x10, 0x00, 0x00, 0x01, 0x00, 0x0a, 0x01, 0x4b, 0x03, 0x00, 0x01,
0x62, 0x00, 0x09, 0x00, 0x62, 0x01, 0x00, 0x00, 0x6e, 0x10, 0x00, 0x00, 0x01, 0x00,
0x0a, 0x01, 0x12, 0x52, 0x4b, 0x02, 0x00, 0x01, 0x62, 0x00, 0x09, 0x00, 0x62, 0x01,
0x02, 0x00, 0x6e, 0x10, 0x00, 0x00, 0x01, 0x00, 0x0a, 0x01, 0x12, 0x62, 0x4b, 0x02,
0x00, 0x01, 0x62, 0x00, 0x09, 0x00, 0x62, 0x01, 0x03, 0x00, 0x6e, 0x10, 0x00, 0x00,
0x01, 0x00, 0x0a, 0x01, 0x12, 0x72, 0x4b, 0x02, 0x00, 0x01, 0x62, 0x00, 0x09, 0x00,
0x62, 0x01, 0x04, 0x00, 0x6e, 0x10, 0x00, 0x00, 0x01, 0x00, 0x0a, 0x01, 0x13, 0x02,
0x08, 0x00, 0x4b, 0x02, 0x00, 0x01, 0x62, 0x00, 0x09, 0x00, 0x62, 0x01, 0x06, 0x00,
0x6e, 0x10, 0x00, 0x00, 0x01, 0x00, 0x0a, 0x01, 0x13, 0x02, 0x09, 0x00, 0x4b, 0x02,
0x00, 0x01, 0x0e, 0x00, // insns
// no padding: insns_size % 2 == 0
//try_item 0x00
0x0a, 0x00, 0x00, 0x00, // start_addr
0x08, 0x00, // insn_count
0x01, 0x00, // handler_off
//try_item 0x01
0x13, 0x00, 0x00, 0x00, // start_addr
0x0a, 0x00, // insn_count
0x04, 0x00, // handler_off
//try_item 0x02
0x1e, 0x00, 0x00, 0x00, // start_addr
0x0a, 0x00, // insn_count
0x07, 0x00, // handler_off
//try_item 0x03
0x29, 0x00, 0x00, 0x00, // start_addr
0x0a, 0x00, // insn_count
0x0a, 0x00, // handler_off
//try_item 0x04
0x3c, 0x00, 0x00, 0x00, // start_addr
0x08, 0x00, // insn_count
0x0d, 0x00, // handler_off
//try_item 0x05
0x44, 0x00, 0x00, 0x00, // start_addr
0x0a, 0x00, // insn_count
0x10, 0x00, // handler_off
//try_item 0x06
0x4e, 0x00, 0x00, 0x00, // start_addr
0x0a, 0x00, // insn_count
0x13, 0x00, // handler_off
//try_item 0x07
0x58, 0x00, 0x00, 0x00, // start_addr
0x0a, 0x00, // insn_count
0x16, 0x00, // handler_off
//try_item 0x08
0x62, 0x00, 0x00, 0x00, // start_addr
0x0b, 0x00, // insn_count
0x19, 0x00, // handler_off
//try_item 0x09
0x6d, 0x00, 0x00, 0x00, // start_addr
0x0b, 0x00, // insn_count
0x1c, 0x00, // handler_off
//try_item 0x0a
0x78, 0x00, 0x00, 0x00, // start_addr
0x0b, 0x00, // insn_count
0x1f, 0x00, // handler_off
//try_item 0x0b
0x83, 0x00, 0x00, 0x00, // start_addr
0x0c, 0x00, // insn_count
0x23, 0x00, // handler_off
//try_item 0x0c
0x8f, 0x00, 0x00, 0x00, // start_addr
0x0c, 0x00, // insn_count
0x27, 0x00, // handler_off
// encoded_catch_handler_list
0x0d, // size
0x01, 0x13, 0x12, // encoded_catch_handler 0x00
0x01, 0x13, 0x1d, // encoded_catch_handler 0x01
0x01, 0x13, 0x28, // encoded_catch_handler 0x02
0x01, 0x13, 0x33, // encoded_catch_handler 0x03
0x01, 0x13, 0x44, // encoded_catch_handler 0x04
0x01, 0x13, 0x4e, // encoded_catch_handler 0x05
0x01, 0x13, 0x58, // encoded_catch_handler 0x06
0x01, 0x13, 0x62, // encoded_catch_handler 0x07
0x01, 0x13, 0x6d, // encoded_catch_handler 0x08
0x01, 0x13, 0x78, // encoded_catch_handler 0x09
0x01, 0x13, 0x83, 0x01, // encoded_catch_handler 0x0a
0x01, 0x13, 0x8f, 0x01, // encoded_catch_handler 0x0b
0x01, 0x13, 0x9b, 0x01, // encoded_catch_handler 0x0c
];
assert_eq!(raw, code.serialize_to_vec().unwrap());
assert_eq!(code, CodeItem::deserialize_from_slice(&raw).unwrap());
assert_eq!(code.size(), raw.len());
}
}