Skip to content

Commit f263e49

Browse files
authored
Combine data/text sections: Pad sections to alignment (#197)
* Combine data/text sections: Pad all sections to 4-byte minimum alignment * Update x86 test snapshot * Read and store object section alignment * Combine data/text sections: Pad sections to more than 4-byte alignment if they have alignment specified
1 parent d0e6c5c commit f263e49

14 files changed

+431
-65
lines changed

objdiff-core/src/obj/mod.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@ use alloc::{
99
vec,
1010
vec::Vec,
1111
};
12-
use core::{fmt, num::NonZeroU32};
12+
use core::{
13+
fmt,
14+
num::{NonZeroU32, NonZeroU64},
15+
};
1316

1417
use flagset::{FlagSet, flags};
1518

@@ -70,6 +73,7 @@ pub struct Section {
7073
pub kind: SectionKind,
7174
pub data: SectionData,
7275
pub flags: SectionFlagSet,
76+
pub align: Option<NonZeroU64>,
7377
pub relocations: Vec<Relocation>,
7478
/// Line number info (.line or .debug_line section)
7579
pub line_info: BTreeMap<u64, u32>,
@@ -105,6 +109,12 @@ impl Section {
105109
}
106110
}
107111

112+
// The alignment to use when "Combine data/text sections" is enabled.
113+
pub fn combined_alignment(&self) -> u64 {
114+
const MIN_ALIGNMENT: u64 = 4;
115+
self.align.map(|align| align.get().max(MIN_ALIGNMENT)).unwrap_or(MIN_ALIGNMENT)
116+
}
117+
108118
pub fn relocation_at<'obj>(
109119
&'obj self,
110120
obj: &'obj Object,
@@ -363,6 +373,7 @@ static DUMMY_SECTION: Section = Section {
363373
kind: SectionKind::Unknown,
364374
data: SectionData(Vec::new()),
365375
flags: SectionFlagSet::empty(),
376+
align: None,
366377
relocations: Vec::new(),
367378
line_info: BTreeMap::new(),
368379
virtual_address: None,

objdiff-core/src/obj/read.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use alloc::{
44
string::{String, ToString},
55
vec::Vec,
66
};
7-
use core::cmp::Ordering;
7+
use core::{cmp::Ordering, num::NonZeroU64};
88

99
use anyhow::{Context, Result, anyhow, bail, ensure};
1010
use object::{Object as _, ObjectSection as _, ObjectSymbol as _};
@@ -17,7 +17,7 @@ use crate::{
1717
Symbol, SymbolFlag, SymbolKind,
1818
split_meta::{SPLITMETA_SECTION, SplitMeta},
1919
},
20-
util::{read_u16, read_u32},
20+
util::{align_data_slice_to, align_u64_to, read_u16, read_u32},
2121
};
2222

2323
fn map_section_kind(section: &object::Section) -> SectionKind {
@@ -257,6 +257,7 @@ fn map_sections(
257257
kind,
258258
data: SectionData(data),
259259
flags: Default::default(),
260+
align: NonZeroU64::new(section.align()),
260261
relocations: Default::default(),
261262
virtual_address,
262263
line_info: Default::default(),
@@ -739,7 +740,10 @@ fn do_combine_sections(
739740
}
740741
offsets.push(current_offset);
741742
current_offset += section.size;
743+
let align = section.combined_alignment();
744+
current_offset = align_u64_to(current_offset, align);
742745
data_size += section.data.len();
746+
data_size = align_u64_to(data_size as u64, align) as usize;
743747
num_relocations += section.relocations.len();
744748
}
745749
if data_size > 0 {
@@ -754,6 +758,7 @@ fn do_combine_sections(
754758
let section = &mut sections[i];
755759
section.size = 0;
756760
data.append(&mut section.data.0);
761+
align_data_slice_to(&mut data, section.combined_alignment());
757762
section.relocations.iter_mut().for_each(|r| r.address += offset);
758763
relocations.append(&mut section.relocations);
759764
line_info.append(&mut section.line_info.iter().map(|(&a, &l)| (a + offset, l)).collect());

objdiff-core/src/obj/snapshots/objdiff_core__obj__read__test__combine_sections.snap

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ expression: "(sections, symbols)"
1414
8,
1515
),
1616
flags: FlagSet(),
17+
align: None,
1718
relocations: [
1819
Relocation {
1920
flags: Elf(
@@ -53,6 +54,7 @@ expression: "(sections, symbols)"
5354
12,
5455
),
5556
flags: FlagSet(Combined),
57+
align: None,
5658
relocations: [
5759
Relocation {
5860
flags: Elf(
@@ -87,6 +89,7 @@ expression: "(sections, symbols)"
8789
0,
8890
),
8991
flags: FlagSet(Hidden),
92+
align: None,
9093
relocations: [],
9194
line_info: {},
9295
virtual_address: None,
@@ -101,6 +104,7 @@ expression: "(sections, symbols)"
101104
0,
102105
),
103106
flags: FlagSet(Hidden),
107+
align: None,
104108
relocations: [],
105109
line_info: {},
106110
virtual_address: None,

objdiff-core/src/obj/split_meta.rs

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ use alloc::{string::String, vec, vec::Vec};
33
use anyhow::{Result, anyhow};
44
use object::{Endian, ObjectSection, elf::SHT_NOTE};
55

6+
#[cfg(feature = "std")]
7+
use crate::util::align_data_to_4;
8+
use crate::util::align_size_to_4;
9+
610
pub const SPLITMETA_SECTION: &str = ".note.split";
711
pub const SHT_SPLITMETA: u32 = SHT_NOTE;
812
pub const ELF_NOTE_SPLIT: &[u8] = b"Split";
@@ -190,17 +194,6 @@ where E: Endian
190194
}
191195
}
192196

193-
fn align_size_to_4(size: usize) -> usize { (size + 3) & !3 }
194-
195-
#[cfg(feature = "std")]
196-
fn align_data_to_4<W: std::io::Write + ?Sized>(writer: &mut W, len: usize) -> std::io::Result<()> {
197-
const ALIGN_BYTES: &[u8] = &[0; 4];
198-
if len % 4 != 0 {
199-
writer.write_all(&ALIGN_BYTES[..4 - len % 4])?;
200-
}
201-
Ok(())
202-
}
203-
204197
// ELF note format:
205198
// Name Size | 4 bytes (integer)
206199
// Desc Size | 4 bytes (integer)

objdiff-core/src/util.rs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use alloc::format;
1+
use alloc::{format, vec::Vec};
22
use core::fmt;
33

44
use anyhow::{Result, ensure};
@@ -39,3 +39,24 @@ pub fn read_u16(obj_file: &object::File, reader: &mut &[u8]) -> Result<u16> {
3939
*reader = &reader[2..];
4040
Ok(obj_file.endianness().read_u16(value))
4141
}
42+
43+
pub fn align_size_to_4(size: usize) -> usize { (size + 3) & !3 }
44+
45+
#[cfg(feature = "std")]
46+
pub fn align_data_to_4<W: std::io::Write + ?Sized>(
47+
writer: &mut W,
48+
len: usize,
49+
) -> std::io::Result<()> {
50+
const ALIGN_BYTES: &[u8] = &[0; 4];
51+
if len % 4 != 0 {
52+
writer.write_all(&ALIGN_BYTES[..4 - len % 4])?;
53+
}
54+
Ok(())
55+
}
56+
57+
pub fn align_u64_to(len: u64, align: u64) -> u64 { len + ((align - (len % align)) % align) }
58+
59+
pub fn align_data_slice_to(data: &mut Vec<u8>, align: u64) {
60+
const ALIGN_BYTE: u8 = 0;
61+
data.resize(align_u64_to(data.len() as u64, align) as usize, ALIGN_BYTE);
62+
}

objdiff-core/tests/snapshots/arch_arm__read_arm.snap

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1519,6 +1519,9 @@ Object {
15191519
556,
15201520
),
15211521
flags: FlagSet(),
1522+
align: Some(
1523+
1,
1524+
),
15221525
relocations: [
15231526
Relocation {
15241527
flags: Elf(
@@ -1718,6 +1721,9 @@ Object {
17181721
0,
17191722
),
17201723
flags: FlagSet(),
1724+
align: Some(
1725+
4,
1726+
),
17211727
relocations: [],
17221728
line_info: {},
17231729
virtual_address: None,
@@ -1732,6 +1738,9 @@ Object {
17321738
76,
17331739
),
17341740
flags: FlagSet(),
1741+
align: Some(
1742+
1,
1743+
),
17351744
relocations: [
17361745
Relocation {
17371746
flags: Elf(
@@ -1883,6 +1892,9 @@ Object {
18831892
0,
18841893
),
18851894
flags: FlagSet(),
1895+
align: Some(
1896+
4,
1897+
),
18861898
relocations: [],
18871899
line_info: {},
18881900
virtual_address: None,
@@ -1897,6 +1909,9 @@ Object {
18971909
0,
18981910
),
18991911
flags: FlagSet(),
1912+
align: Some(
1913+
4,
1914+
),
19001915
relocations: [],
19011916
line_info: {},
19021917
virtual_address: None,
@@ -1911,6 +1926,9 @@ Object {
19111926
0,
19121927
),
19131928
flags: FlagSet(),
1929+
align: Some(
1930+
1,
1931+
),
19141932
relocations: [],
19151933
line_info: {},
19161934
virtual_address: None,
@@ -1925,6 +1943,9 @@ Object {
19251943
0,
19261944
),
19271945
flags: FlagSet(),
1946+
align: Some(
1947+
1,
1948+
),
19281949
relocations: [],
19291950
line_info: {},
19301951
virtual_address: None,

0 commit comments

Comments
 (0)