Skip to content

Commit

Permalink
Strengthen validation for sections&segments in compute_segment_layout
Browse files Browse the repository at this point in the history
  • Loading branch information
marxin authored and davidlattimore committed Aug 30, 2024
1 parent 250d2bf commit 0dbb766
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 10 deletions.
46 changes: 42 additions & 4 deletions wild_lib/src/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1370,16 +1370,42 @@ fn compute_segment_layout(
}
OrderEvent::Section(section_id, section_details) => {
let part = section_layouts.get(section_id);
// Segments only cover sections that are allocated and have a non-zero address.
if section_details.section_flags.contains(shf::ALLOC) {
assert!(part.mem_offset != 0 || section_id == FILE_HEADER);

// Skip all ignored sections that will not end up in the final file.
if output_sections.output_section_indexes[section_id.as_usize()].is_none() {
return;
}

if !active_records.is_empty() {
// All segments should only cover sections that are allocated and have a non-zero address.
assert!(
part.mem_offset != 0 || section_id == FILE_HEADER,
"Missing memory offset for section `{}` present in a program segment.",
section_details.name
);
assert!(
section_details.section_flags.contains(shf::ALLOC),
"Missing SHF_ALLOC section flag for section `{}` present in a program segment.",
section_details.name
);
for rec in active_records.values_mut() {
rec.file_start = rec.file_start.min(part.file_offset);
rec.mem_start = rec.mem_start.min(part.mem_offset);
rec.file_end = rec.file_end.max(part.file_offset + part.file_size);
rec.mem_end = rec.mem_end.max(part.mem_offset + part.mem_size);
rec.alignment = rec.alignment.max(part.alignment);
}
} else {
assert_eq!(
part.mem_offset, 0,
"Expected zero address for section `{}` not present in any program segment.",
section_details.name
);
assert!(
!section_details.section_flags.contains(shf::ALLOC),
"Section with SHF_ALLOC flag `{}` not present in any program segment.",
section_details.name
);
}
}
});
Expand Down Expand Up @@ -4124,7 +4150,7 @@ impl<'data> DynamicSymbolDefinition<'data> {
/// overlap and that sections don't overlap.
#[test]
fn test_no_disallowed_overlaps() {
let output_sections =
let mut output_sections =
crate::output_section_id::OutputSectionsBuilder::with_base_address(0x1000)
.build()
.unwrap();
Expand Down Expand Up @@ -4166,6 +4192,18 @@ fn test_no_disallowed_overlaps() {
active_segment_ids: (0..MAX_SEGMENTS).map(ProgramSegmentId::new).collect(),
};

let mut section_index = 0;
for section in output_sections.section_infos.iter() {
if section.details.section_flags.contains(shf::ALLOC) {
output_sections
.output_section_indexes
.push(Some(section_index));
section_index += 1;
} else {
output_sections.output_section_indexes.push(None)
}
}

let segment_layouts = compute_segment_layout(&section_layouts, &output_sections, &header_info);

// Make sure loadable segments don't overlap in memory or in the file.
Expand Down
16 changes: 10 additions & 6 deletions wild_lib/src/output_section_id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ pub struct OutputSections<'data> {
pub(crate) exec_custom: Vec<OutputSectionId>,
pub(crate) data_custom: Vec<OutputSectionId>,
pub(crate) bss_custom: Vec<OutputSectionId>,
pub(crate) debug: Vec<OutputSectionId>,
pub(crate) nonalloc_debug: Vec<OutputSectionId>,
}

impl<'data> OutputSections<'data> {
Expand Down Expand Up @@ -228,6 +228,7 @@ impl<'data> OutputSections<'data> {
}
}

#[derive(Debug)]
pub(crate) struct SectionOutputInfo<'data> {
pub(crate) loadable_segment_id: Option<ProgramSegmentId>,
pub(crate) details: SectionDetails<'data>,
Expand Down Expand Up @@ -521,6 +522,7 @@ const SECTION_DEFINITIONS: [BuiltInSectionDetails; NUM_BUILT_IN_SECTIONS] = [
details: SectionDetails {
name: SectionName(b".preinit_array"),
ty: object::elf::SHT_PREINIT_ARRAY,
section_flags: SectionFlags(shf::ALLOC),
retain: true,
..SectionDetails::default()
},
Expand Down Expand Up @@ -744,7 +746,7 @@ impl<'data> OutputSectionsBuilder<'data> {
let mut exec_custom = Vec::new();
let mut data_custom = Vec::new();
let mut bss_custom = Vec::new();
let mut debug = Vec::new();
let mut nonalloc_debug = Vec::new();

for (offset, info) in self.section_infos[NUM_BUILT_IN_SECTIONS..]
.iter()
Expand All @@ -754,8 +756,10 @@ impl<'data> OutputSectionsBuilder<'data> {
if info.details.section_flags.contains(shf::EXECINSTR) {
exec_custom.push(id);
} else if !info.details.section_flags.contains(shf::WRITE) {
if info.details.name.0.starts_with(b".debug") {
debug.push(id);
if info.details.name.0.starts_with(b".debug")
&& !info.details.section_flags.contains(shf::ALLOC)
{
nonalloc_debug.push(id);
} else {
ro_custom.push(id);
}
Expand All @@ -774,7 +778,7 @@ impl<'data> OutputSectionsBuilder<'data> {
exec_custom,
data_custom,
bss_custom,
debug,
nonalloc_debug,
output_section_indexes: Default::default(),
};

Expand Down Expand Up @@ -872,7 +876,7 @@ impl<'data> OutputSections<'data> {
self.ids_do(&self.bss_custom, &mut cb);
cb(OrderEvent::SegmentEnd(crate::program_segments::LOAD_RW));

self.ids_do(&self.debug, &mut cb);
self.ids_do(&self.nonalloc_debug, &mut cb);
cb(COMMENT.event());
cb(SHSTRTAB.event());
cb(SYMTAB.event());
Expand Down

0 comments on commit 0dbb766

Please sign in to comment.