/// Internal format to use for the `.drectve` section containing linker /// directives for symbol exports. #[derive(Clone, Copy, Debug, PartialEq, Eq)] pubenum CoffExportStyle { /// MSVC format supported by link.exe and LLD.
Msvc, /// Gnu format supported by GNU LD and LLD.
Gnu,
}
pub(crate) fn coff_subsection_name(&self, section: &[u8], value: &[u8]) -> Vec<u8> { letmut name = section.to_vec();
name.push(b'$');
name.extend_from_slice(value);
name
}
pub(crate) fn coff_translate_relocation(&mutself, reloc: &style='color:red'>mut Relocation) -> Result<()> { let (mut kind, _encoding, size) = iflet RelocationFlags::Generic {
kind,
encoding,
size,
} = reloc.flags
{
(kind, encoding, size)
} else { return Ok(());
}; if kind == RelocationKind::GotRelative { // Use a stub symbol for the relocation instead. // This isn't really a GOT, but it's a similar purpose. // TODO: need to handle DLL imports differently?
kind = RelocationKind::Relative;
reloc.symbol = self.coff_add_stub_symbol(reloc.symbol)?;
} elseif kind == RelocationKind::PltRelative { // Windows doesn't need a separate relocation type for // references to functions in import libraries. // For convenience, treat this the same as Relative.
kind = RelocationKind::Relative;
}
/// Appends linker directives to the `.drectve` section to tell the linker /// to export all symbols with `SymbolScope::Dynamic`. /// /// This must be called after all symbols have been defined. pub fn add_coff_exports(&mutself, style: CoffExportStyle) {
assert_eq!(self.format, BinaryFormat::Coff);
letmut directives = vec![];
for symbol in &self.symbols { if symbol.scope == SymbolScope::Dynamic { match style {
CoffExportStyle::Msvc => directives.extend(b" /EXPORT:\""),
CoffExportStyle::Gnu => directives.extend(b" -export:\""),
}
directives.extend(&symbol.name);
directives.extend(b"\""); if symbol.kind != SymbolKind::Text { match style {
CoffExportStyle::Msvc => directives.extend(b",DATA"),
CoffExportStyle::Gnu => directives.extend(b",data"),
}
}
}
} let drectve = self.add_section(vec![], b".drectve".to_vec(), SectionKind::Linker); self.append_section_data(drectve, &directives, 1);
}
// Add section strings to strtab. letmut section_offsets = vec![SectionOffsets::default(); self.sections.len()];
for (index, section) in self.sections.iter().enumerate() {
section_offsets[index].name = writer.add_name(§ion.name);
}
// Set COMDAT flags.
for comdat in &self.comdats { let symbol = &self.symbols[comdat.symbol.0]; let comdat_section = match symbol.section {
SymbolSection::Section(id) => id.0,
_ => { return Err(Error(format!( "unsupported COMDAT symbol `{}` section {:?}",
symbol.name().unwrap_or(""),
symbol.section
)));
}
};
section_offsets[comdat_section].selection = match comdat.kind {
ComdatKind::NoDuplicates => coff::IMAGE_COMDAT_SELECT_NODUPLICATES,
ComdatKind::Any => coff::IMAGE_COMDAT_SELECT_ANY,
ComdatKind::SameSize => coff::IMAGE_COMDAT_SELECT_SAME_SIZE,
ComdatKind::ExactMatch => coff::IMAGE_COMDAT_SELECT_EXACT_MATCH,
ComdatKind::Largest => coff::IMAGE_COMDAT_SELECT_LARGEST,
ComdatKind::Newest => coff::IMAGE_COMDAT_SELECT_NEWEST,
ComdatKind::Unknown => { return Err(Error(format!( "unsupported COMDAT symbol `{}` kind {:?}",
symbol.name().unwrap_or(""),
comdat.kind
)));
}
};
for id in &comdat.sections { let section = &self.sections[id.0]; if section.symbol.is_none() { return Err(Error(format!( "missing symbol for COMDAT section `{}`",
section.name().unwrap_or(""),
)));
} if id.0 != comdat_section {
section_offsets[id.0].selection = coff::IMAGE_COMDAT_SELECT_ASSOCIATIVE;
section_offsets[id.0].associative_section = comdat_section as u32 + 1;
}
}
}
// Reserve symbol indices and add symbol strings to strtab. letmut symbol_offsets = vec![SymbolOffsets::default(); self.symbols.len()];
for (index, symbol) in self.symbols.iter().enumerate() {
symbol_offsets[index].index = writer.reserve_symbol_index(); letmut name = &*symbol.name; match symbol.kind {
SymbolKind::File => { // Name goes in auxiliary symbol records.
symbol_offsets[index].aux_count = writer.reserve_aux_file_name(&symbol.name);
name = b".file";
}
SymbolKind::Section if symbol.section.id().is_some() => {
symbol_offsets[index].aux_count = writer.reserve_aux_section();
}
_ => {}
};
symbol_offsets[index].name = writer.add_name(name);
}
// Reserve file ranges.
writer.reserve_file_header();
writer.reserve_section_headers(self.sections.len() as u16);
for (index, section) in self.sections.iter().enumerate() {
section_offsets[index].offset = writer.reserve_section(section.data.len());
section_offsets[index].reloc_offset =
writer.reserve_relocations(section.relocations.len());
}
writer.reserve_symtab_strtab();
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.