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

Improve simple_write example #747

Merged
merged 1 commit into from
Sep 5, 2024
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
33 changes: 25 additions & 8 deletions crates/examples/src/bin/simple_write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
//! The resulting object file can be linked with a C runtime to create a complete executable:
//! ```sh
//! $ cargo run --bin simple_write
//! $ gcc -o hello hello.o
//! $ gcc -o hello hello.o -z noexecstack
//! $ ./hello
//! Hello, world!
//! ```
Expand Down Expand Up @@ -48,8 +48,9 @@ impl RelocateWriter for Section {
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
let binary_format = object::BinaryFormat::native_object();
let mut obj = object::write::Object::new(
object::BinaryFormat::native_object(),
binary_format,
object::Architecture::X86_64,
object::Endianness::Little,
);
Expand All @@ -69,7 +70,12 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
// Choose the encoding parameters.
let encoding = Encoding {
format: Format::Dwarf32,
version: 5,
version: if binary_format == object::BinaryFormat::Coff {
// The COFF toolchain I used didn't work with DWARF version 5.
4
} else {
5
},
address_size: 8,
};

Expand Down Expand Up @@ -148,7 +154,12 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
if section.data.len() == 0 {
return Ok(());
}
let section_id = obj.add_section(Vec::new(), id.name().into(), object::SectionKind::Debug);
let kind = if id.is_string() {
object::SectionKind::DebugString
} else {
object::SectionKind::Debug
};
let section_id = obj.add_section(Vec::new(), id.name().into(), kind);
obj.set_section_data(section_id, section.data.take(), 1);

// Record the section ID so that it can be used for relocations.
Expand All @@ -166,14 +177,20 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
// The `eh_pe` field is not used in this example because we are not writing
// unwind information.
debug_assert!(reloc.eh_pe.is_none());
let symbol = match reloc.target {
let (symbol, kind) = match reloc.target {
RelocationTarget::Section(id) => {
obj.section_symbol(sections.get(id).unwrap().id.unwrap())
let kind = if binary_format == object::BinaryFormat::Coff {
object::RelocationKind::SectionOffset
} else {
object::RelocationKind::Absolute
};
let symbol = obj.section_symbol(sections.get(id).unwrap().id.unwrap());
(symbol, kind)
}
RelocationTarget::Symbol(id) => {
// The main function is the only symbol we have defined.
debug_assert_eq!(id, 0);
main_symbol
(main_symbol, object::RelocationKind::Absolute)
}
};
obj.add_relocation(
Expand All @@ -183,7 +200,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
symbol,
addend: reloc.addend,
flags: object::RelocationFlags::Generic {
kind: object::RelocationKind::Absolute,
kind,
encoding: object::RelocationEncoding::Generic,
size: reloc.size * 8,
},
Expand Down
7 changes: 7 additions & 0 deletions src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,13 @@ impl SectionId {
_ => return None,
})
}

/// Returns true if this is a mergeable string section.
///
/// This is useful for determining the correct section flags.
pub fn is_string(self) -> bool {
matches!(self, SectionId::DebugStr | SectionId::DebugLineStr)
}
}

/// An optionally-provided implementation-defined compilation unit ID to enable
Expand Down
Loading