aboutsummaryrefslogtreecommitdiff
path: root/vendor/gimli/src/write/writer.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/gimli/src/write/writer.rs')
-rw-r--r--vendor/gimli/src/write/writer.rs494
1 files changed, 0 insertions, 494 deletions
diff --git a/vendor/gimli/src/write/writer.rs b/vendor/gimli/src/write/writer.rs
deleted file mode 100644
index 1ce3641..0000000
--- a/vendor/gimli/src/write/writer.rs
+++ /dev/null
@@ -1,494 +0,0 @@
-use crate::common::{Format, SectionId};
-use crate::constants;
-use crate::endianity::Endianity;
-use crate::leb128;
-use crate::write::{Address, Error, Result};
-
-/// A trait for writing the data to a DWARF section.
-///
-/// All write operations append to the section unless otherwise specified.
-#[allow(clippy::len_without_is_empty)]
-pub trait Writer {
- /// The endianity of bytes that are written.
- type Endian: Endianity;
-
- /// Return the endianity of bytes that are written.
- fn endian(&self) -> Self::Endian;
-
- /// Return the current section length.
- ///
- /// This may be used as an offset for future `write_at` calls.
- fn len(&self) -> usize;
-
- /// Write a slice.
- fn write(&mut self, bytes: &[u8]) -> Result<()>;
-
- /// Write a slice at a given offset.
- ///
- /// The write must not extend past the current section length.
- fn write_at(&mut self, offset: usize, bytes: &[u8]) -> Result<()>;
-
- /// Write an address.
- ///
- /// If the writer supports relocations, then it must provide its own implementation
- /// of this method.
- // TODO: use write_reference instead?
- fn write_address(&mut self, address: Address, size: u8) -> Result<()> {
- match address {
- Address::Constant(val) => self.write_udata(val, size),
- Address::Symbol { .. } => Err(Error::InvalidAddress),
- }
- }
-
- /// Write an address with a `.eh_frame` pointer encoding.
- ///
- /// The given size is only used for `DW_EH_PE_absptr` formats.
- ///
- /// If the writer supports relocations, then it must provide its own implementation
- /// of this method.
- fn write_eh_pointer(
- &mut self,
- address: Address,
- eh_pe: constants::DwEhPe,
- size: u8,
- ) -> Result<()> {
- match address {
- Address::Constant(val) => {
- // Indirect doesn't matter here.
- let val = match eh_pe.application() {
- constants::DW_EH_PE_absptr => val,
- constants::DW_EH_PE_pcrel => {
- // TODO: better handling of sign
- let offset = self.len() as u64;
- val.wrapping_sub(offset)
- }
- _ => {
- return Err(Error::UnsupportedPointerEncoding(eh_pe));
- }
- };
- self.write_eh_pointer_data(val, eh_pe.format(), size)
- }
- Address::Symbol { .. } => Err(Error::InvalidAddress),
- }
- }
-
- /// Write a value with a `.eh_frame` pointer format.
- ///
- /// The given size is only used for `DW_EH_PE_absptr` formats.
- ///
- /// This must not be used directly for values that may require relocation.
- fn write_eh_pointer_data(
- &mut self,
- val: u64,
- format: constants::DwEhPe,
- size: u8,
- ) -> Result<()> {
- match format {
- constants::DW_EH_PE_absptr => self.write_udata(val, size),
- constants::DW_EH_PE_uleb128 => self.write_uleb128(val),
- constants::DW_EH_PE_udata2 => self.write_udata(val, 2),
- constants::DW_EH_PE_udata4 => self.write_udata(val, 4),
- constants::DW_EH_PE_udata8 => self.write_udata(val, 8),
- constants::DW_EH_PE_sleb128 => self.write_sleb128(val as i64),
- constants::DW_EH_PE_sdata2 => self.write_sdata(val as i64, 2),
- constants::DW_EH_PE_sdata4 => self.write_sdata(val as i64, 4),
- constants::DW_EH_PE_sdata8 => self.write_sdata(val as i64, 8),
- _ => Err(Error::UnsupportedPointerEncoding(format)),
- }
- }
-
- /// Write an offset that is relative to the start of the given section.
- ///
- /// If the writer supports relocations, then it must provide its own implementation
- /// of this method.
- fn write_offset(&mut self, val: usize, _section: SectionId, size: u8) -> Result<()> {
- self.write_udata(val as u64, size)
- }
-
- /// Write an offset that is relative to the start of the given section.
- ///
- /// If the writer supports relocations, then it must provide its own implementation
- /// of this method.
- fn write_offset_at(
- &mut self,
- offset: usize,
- val: usize,
- _section: SectionId,
- size: u8,
- ) -> Result<()> {
- self.write_udata_at(offset, val as u64, size)
- }
-
- /// Write a reference to a symbol.
- ///
- /// If the writer supports symbols, then it must provide its own implementation
- /// of this method.
- fn write_reference(&mut self, _symbol: usize, _size: u8) -> Result<()> {
- Err(Error::InvalidReference)
- }
-
- /// Write a u8.
- fn write_u8(&mut self, val: u8) -> Result<()> {
- let bytes = [val];
- self.write(&bytes)
- }
-
- /// Write a u16.
- fn write_u16(&mut self, val: u16) -> Result<()> {
- let mut bytes = [0; 2];
- self.endian().write_u16(&mut bytes, val);
- self.write(&bytes)
- }
-
- /// Write a u32.
- fn write_u32(&mut self, val: u32) -> Result<()> {
- let mut bytes = [0; 4];
- self.endian().write_u32(&mut bytes, val);
- self.write(&bytes)
- }
-
- /// Write a u64.
- fn write_u64(&mut self, val: u64) -> Result<()> {
- let mut bytes = [0; 8];
- self.endian().write_u64(&mut bytes, val);
- self.write(&bytes)
- }
-
- /// Write a u8 at the given offset.
- fn write_u8_at(&mut self, offset: usize, val: u8) -> Result<()> {
- let bytes = [val];
- self.write_at(offset, &bytes)
- }
-
- /// Write a u16 at the given offset.
- fn write_u16_at(&mut self, offset: usize, val: u16) -> Result<()> {
- let mut bytes = [0; 2];
- self.endian().write_u16(&mut bytes, val);
- self.write_at(offset, &bytes)
- }
-
- /// Write a u32 at the given offset.
- fn write_u32_at(&mut self, offset: usize, val: u32) -> Result<()> {
- let mut bytes = [0; 4];
- self.endian().write_u32(&mut bytes, val);
- self.write_at(offset, &bytes)
- }
-
- /// Write a u64 at the given offset.
- fn write_u64_at(&mut self, offset: usize, val: u64) -> Result<()> {
- let mut bytes = [0; 8];
- self.endian().write_u64(&mut bytes, val);
- self.write_at(offset, &bytes)
- }
-
- /// Write unsigned data of the given size.
- ///
- /// Returns an error if the value is too large for the size.
- /// This must not be used directly for values that may require relocation.
- fn write_udata(&mut self, val: u64, size: u8) -> Result<()> {
- match size {
- 1 => {
- let write_val = val as u8;
- if val != u64::from(write_val) {
- return Err(Error::ValueTooLarge);
- }
- self.write_u8(write_val)
- }
- 2 => {
- let write_val = val as u16;
- if val != u64::from(write_val) {
- return Err(Error::ValueTooLarge);
- }
- self.write_u16(write_val)
- }
- 4 => {
- let write_val = val as u32;
- if val != u64::from(write_val) {
- return Err(Error::ValueTooLarge);
- }
- self.write_u32(write_val)
- }
- 8 => self.write_u64(val),
- otherwise => Err(Error::UnsupportedWordSize(otherwise)),
- }
- }
-
- /// Write signed data of the given size.
- ///
- /// Returns an error if the value is too large for the size.
- /// This must not be used directly for values that may require relocation.
- fn write_sdata(&mut self, val: i64, size: u8) -> Result<()> {
- match size {
- 1 => {
- let write_val = val as i8;
- if val != i64::from(write_val) {
- return Err(Error::ValueTooLarge);
- }
- self.write_u8(write_val as u8)
- }
- 2 => {
- let write_val = val as i16;
- if val != i64::from(write_val) {
- return Err(Error::ValueTooLarge);
- }
- self.write_u16(write_val as u16)
- }
- 4 => {
- let write_val = val as i32;
- if val != i64::from(write_val) {
- return Err(Error::ValueTooLarge);
- }
- self.write_u32(write_val as u32)
- }
- 8 => self.write_u64(val as u64),
- otherwise => Err(Error::UnsupportedWordSize(otherwise)),
- }
- }
-
- /// Write a word of the given size at the given offset.
- ///
- /// Returns an error if the value is too large for the size.
- /// This must not be used directly for values that may require relocation.
- fn write_udata_at(&mut self, offset: usize, val: u64, size: u8) -> Result<()> {
- match size {
- 1 => {
- let write_val = val as u8;
- if val != u64::from(write_val) {
- return Err(Error::ValueTooLarge);
- }
- self.write_u8_at(offset, write_val)
- }
- 2 => {
- let write_val = val as u16;
- if val != u64::from(write_val) {
- return Err(Error::ValueTooLarge);
- }
- self.write_u16_at(offset, write_val)
- }
- 4 => {
- let write_val = val as u32;
- if val != u64::from(write_val) {
- return Err(Error::ValueTooLarge);
- }
- self.write_u32_at(offset, write_val)
- }
- 8 => self.write_u64_at(offset, val),
- otherwise => Err(Error::UnsupportedWordSize(otherwise)),
- }
- }
-
- /// Write an unsigned LEB128 encoded integer.
- fn write_uleb128(&mut self, val: u64) -> Result<()> {
- let mut bytes = [0u8; 10];
- // bytes is long enough so this will never fail.
- let len = leb128::write::unsigned(&mut { &mut bytes[..] }, val).unwrap();
- self.write(&bytes[..len])
- }
-
- /// Read an unsigned LEB128 encoded integer.
- fn write_sleb128(&mut self, val: i64) -> Result<()> {
- let mut bytes = [0u8; 10];
- // bytes is long enough so this will never fail.
- let len = leb128::write::signed(&mut { &mut bytes[..] }, val).unwrap();
- self.write(&bytes[..len])
- }
-
- /// Write an initial length according to the given DWARF format.
- ///
- /// This will only write a length of zero, since the length isn't
- /// known yet, and a subsequent call to `write_initial_length_at`
- /// will write the actual length.
- fn write_initial_length(&mut self, format: Format) -> Result<InitialLengthOffset> {
- if format == Format::Dwarf64 {
- self.write_u32(0xffff_ffff)?;
- }
- let offset = InitialLengthOffset(self.len());
- self.write_udata(0, format.word_size())?;
- Ok(offset)
- }
-
- /// Write an initial length at the given offset according to the given DWARF format.
- ///
- /// `write_initial_length` must have previously returned the offset.
- fn write_initial_length_at(
- &mut self,
- offset: InitialLengthOffset,
- length: u64,
- format: Format,
- ) -> Result<()> {
- self.write_udata_at(offset.0, length, format.word_size())
- }
-}
-
-/// The offset at which an initial length should be written.
-#[derive(Debug, Clone, Copy)]
-pub struct InitialLengthOffset(usize);
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use crate::write;
- use crate::{BigEndian, LittleEndian};
- use std::{i64, u64};
-
- #[test]
- fn test_writer() {
- let mut w = write::EndianVec::new(LittleEndian);
- w.write_address(Address::Constant(0x1122_3344), 4).unwrap();
- assert_eq!(w.slice(), &[0x44, 0x33, 0x22, 0x11]);
- assert_eq!(
- w.write_address(
- Address::Symbol {
- symbol: 0,
- addend: 0
- },
- 4
- ),
- Err(Error::InvalidAddress)
- );
-
- let mut w = write::EndianVec::new(LittleEndian);
- w.write_offset(0x1122_3344, SectionId::DebugInfo, 4)
- .unwrap();
- assert_eq!(w.slice(), &[0x44, 0x33, 0x22, 0x11]);
- w.write_offset_at(1, 0x5566, SectionId::DebugInfo, 2)
- .unwrap();
- assert_eq!(w.slice(), &[0x44, 0x66, 0x55, 0x11]);
-
- let mut w = write::EndianVec::new(LittleEndian);
- w.write_u8(0x11).unwrap();
- w.write_u16(0x2233).unwrap();
- w.write_u32(0x4455_6677).unwrap();
- w.write_u64(0x8081_8283_8485_8687).unwrap();
- #[rustfmt::skip]
- assert_eq!(w.slice(), &[
- 0x11,
- 0x33, 0x22,
- 0x77, 0x66, 0x55, 0x44,
- 0x87, 0x86, 0x85, 0x84, 0x83, 0x82, 0x81, 0x80,
- ]);
- w.write_u8_at(14, 0x11).unwrap();
- w.write_u16_at(12, 0x2233).unwrap();
- w.write_u32_at(8, 0x4455_6677).unwrap();
- w.write_u64_at(0, 0x8081_8283_8485_8687).unwrap();
- #[rustfmt::skip]
- assert_eq!(w.slice(), &[
- 0x87, 0x86, 0x85, 0x84, 0x83, 0x82, 0x81, 0x80,
- 0x77, 0x66, 0x55, 0x44,
- 0x33, 0x22,
- 0x11,
- ]);
-
- let mut w = write::EndianVec::new(BigEndian);
- w.write_u8(0x11).unwrap();
- w.write_u16(0x2233).unwrap();
- w.write_u32(0x4455_6677).unwrap();
- w.write_u64(0x8081_8283_8485_8687).unwrap();
- #[rustfmt::skip]
- assert_eq!(w.slice(), &[
- 0x11,
- 0x22, 0x33,
- 0x44, 0x55, 0x66, 0x77,
- 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
- ]);
- w.write_u8_at(14, 0x11).unwrap();
- w.write_u16_at(12, 0x2233).unwrap();
- w.write_u32_at(8, 0x4455_6677).unwrap();
- w.write_u64_at(0, 0x8081_8283_8485_8687).unwrap();
- #[rustfmt::skip]
- assert_eq!(w.slice(), &[
- 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
- 0x44, 0x55, 0x66, 0x77,
- 0x22, 0x33,
- 0x11,
- ]);
-
- let mut w = write::EndianVec::new(LittleEndian);
- w.write_udata(0x11, 1).unwrap();
- w.write_udata(0x2233, 2).unwrap();
- w.write_udata(0x4455_6677, 4).unwrap();
- w.write_udata(0x8081_8283_8485_8687, 8).unwrap();
- #[rustfmt::skip]
- assert_eq!(w.slice(), &[
- 0x11,
- 0x33, 0x22,
- 0x77, 0x66, 0x55, 0x44,
- 0x87, 0x86, 0x85, 0x84, 0x83, 0x82, 0x81, 0x80,
- ]);
- assert_eq!(w.write_udata(0x100, 1), Err(Error::ValueTooLarge));
- assert_eq!(w.write_udata(0x1_0000, 2), Err(Error::ValueTooLarge));
- assert_eq!(w.write_udata(0x1_0000_0000, 4), Err(Error::ValueTooLarge));
- assert_eq!(w.write_udata(0x00, 3), Err(Error::UnsupportedWordSize(3)));
- w.write_udata_at(14, 0x11, 1).unwrap();
- w.write_udata_at(12, 0x2233, 2).unwrap();
- w.write_udata_at(8, 0x4455_6677, 4).unwrap();
- w.write_udata_at(0, 0x8081_8283_8485_8687, 8).unwrap();
- #[rustfmt::skip]
- assert_eq!(w.slice(), &[
- 0x87, 0x86, 0x85, 0x84, 0x83, 0x82, 0x81, 0x80,
- 0x77, 0x66, 0x55, 0x44,
- 0x33, 0x22,
- 0x11,
- ]);
- assert_eq!(w.write_udata_at(0, 0x100, 1), Err(Error::ValueTooLarge));
- assert_eq!(w.write_udata_at(0, 0x1_0000, 2), Err(Error::ValueTooLarge));
- assert_eq!(
- w.write_udata_at(0, 0x1_0000_0000, 4),
- Err(Error::ValueTooLarge)
- );
- assert_eq!(
- w.write_udata_at(0, 0x00, 3),
- Err(Error::UnsupportedWordSize(3))
- );
-
- let mut w = write::EndianVec::new(LittleEndian);
- w.write_uleb128(0).unwrap();
- assert_eq!(w.slice(), &[0]);
-
- let mut w = write::EndianVec::new(LittleEndian);
- w.write_uleb128(u64::MAX).unwrap();
- assert_eq!(
- w.slice(),
- &[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 1]
- );
-
- let mut w = write::EndianVec::new(LittleEndian);
- w.write_sleb128(0).unwrap();
- assert_eq!(w.slice(), &[0]);
-
- let mut w = write::EndianVec::new(LittleEndian);
- w.write_sleb128(i64::MAX).unwrap();
- assert_eq!(
- w.slice(),
- &[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0]
- );
-
- let mut w = write::EndianVec::new(LittleEndian);
- w.write_sleb128(i64::MIN).unwrap();
- assert_eq!(
- w.slice(),
- &[0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f]
- );
-
- let mut w = write::EndianVec::new(LittleEndian);
- let offset = w.write_initial_length(Format::Dwarf32).unwrap();
- assert_eq!(w.slice(), &[0, 0, 0, 0]);
- w.write_initial_length_at(offset, 0x1122_3344, Format::Dwarf32)
- .unwrap();
- assert_eq!(w.slice(), &[0x44, 0x33, 0x22, 0x11]);
- assert_eq!(
- w.write_initial_length_at(offset, 0x1_0000_0000, Format::Dwarf32),
- Err(Error::ValueTooLarge)
- );
-
- let mut w = write::EndianVec::new(LittleEndian);
- let offset = w.write_initial_length(Format::Dwarf64).unwrap();
- assert_eq!(w.slice(), &[0xff, 0xff, 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0]);
- w.write_initial_length_at(offset, 0x1122_3344_5566_7788, Format::Dwarf64)
- .unwrap();
- assert_eq!(
- w.slice(),
- &[0xff, 0xff, 0xff, 0xff, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11]
- );
- }
-}