Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Strengthen validation for sections&segments in compute_segment_layout #94

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 42 additions & 4 deletions wild_lib/src/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1368,16 +1368,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 @@ -4122,7 +4148,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 @@ -4164,6 +4190,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