diff options
author | Valentin Popov <valentin@popov.link> | 2024-07-19 15:37:58 +0300 |
---|---|---|
committer | Valentin Popov <valentin@popov.link> | 2024-07-19 15:37:58 +0300 |
commit | a990de90fe41456a23e58bd087d2f107d321f3a1 (patch) | |
tree | 15afc392522a9e85dc3332235e311b7d39352ea9 /vendor/object/src/write/xcoff.rs | |
parent | 3d48cd3f81164bbfc1a755dc1d4a9a02f98c8ddd (diff) | |
download | fparkan-a990de90fe41456a23e58bd087d2f107d321f3a1.tar.xz fparkan-a990de90fe41456a23e58bd087d2f107d321f3a1.zip |
Deleted vendor folder
Diffstat (limited to 'vendor/object/src/write/xcoff.rs')
-rw-r--r-- | vendor/object/src/write/xcoff.rs | 556 |
1 files changed, 0 insertions, 556 deletions
diff --git a/vendor/object/src/write/xcoff.rs b/vendor/object/src/write/xcoff.rs deleted file mode 100644 index fc58886..0000000 --- a/vendor/object/src/write/xcoff.rs +++ /dev/null @@ -1,556 +0,0 @@ -use core::mem; - -use crate::endian::{BigEndian as BE, I16, U16, U32}; -use crate::write::string::*; -use crate::write::util::*; -use crate::write::*; - -use crate::{xcoff, AddressSize}; - -#[derive(Default, Clone, Copy)] -struct SectionOffsets { - address: u64, - data_offset: usize, - reloc_offset: usize, -} - -#[derive(Default, Clone, Copy)] -struct SymbolOffsets { - index: usize, - str_id: Option<StringId>, - aux_count: u8, - storage_class: u8, -} - -impl<'a> Object<'a> { - pub(crate) fn xcoff_section_info( - &self, - section: StandardSection, - ) -> (&'static [u8], &'static [u8], SectionKind, SectionFlags) { - match section { - StandardSection::Text => (&[], &b".text"[..], SectionKind::Text, SectionFlags::None), - StandardSection::Data => (&[], &b".data"[..], SectionKind::Data, SectionFlags::None), - StandardSection::ReadOnlyData - | StandardSection::ReadOnlyDataWithRel - | StandardSection::ReadOnlyString => ( - &[], - &b".rdata"[..], - SectionKind::ReadOnlyData, - SectionFlags::None, - ), - StandardSection::UninitializedData => ( - &[], - &b".bss"[..], - SectionKind::UninitializedData, - SectionFlags::None, - ), - StandardSection::Tls => (&[], &b".tdata"[..], SectionKind::Tls, SectionFlags::None), - StandardSection::UninitializedTls => ( - &[], - &b".tbss"[..], - SectionKind::UninitializedTls, - SectionFlags::None, - ), - StandardSection::TlsVariables => { - // Unsupported section. - (&[], &[], SectionKind::TlsVariables, SectionFlags::None) - } - StandardSection::Common => { - // Unsupported section. - (&[], &[], SectionKind::Common, SectionFlags::None) - } - StandardSection::GnuProperty => { - // Unsupported section. - (&[], &[], SectionKind::Note, SectionFlags::None) - } - } - } - - pub(crate) fn xcoff_fixup_relocation(&mut self, relocation: &mut Relocation) -> i64 { - let constant = match relocation.kind { - RelocationKind::Relative => relocation.addend + 4, - _ => relocation.addend, - }; - relocation.addend -= constant; - constant - } - - pub(crate) fn xcoff_write(&self, buffer: &mut dyn WritableBuffer) -> Result<()> { - let is_64 = match self.architecture.address_size().unwrap() { - AddressSize::U8 | AddressSize::U16 | AddressSize::U32 => false, - AddressSize::U64 => true, - }; - - let (hdr_size, sechdr_size, rel_size, sym_size) = if is_64 { - ( - mem::size_of::<xcoff::FileHeader64>(), - mem::size_of::<xcoff::SectionHeader64>(), - mem::size_of::<xcoff::Rel64>(), - mem::size_of::<xcoff::Symbol64>(), - ) - } else { - ( - mem::size_of::<xcoff::FileHeader32>(), - mem::size_of::<xcoff::SectionHeader32>(), - mem::size_of::<xcoff::Rel32>(), - mem::size_of::<xcoff::Symbol32>(), - ) - }; - - // Calculate offsets and build strtab. - let mut offset = 0; - let mut strtab = StringTable::default(); - // We place the shared address 0 immediately after the section header table. - let mut address = 0; - - // XCOFF file header. - offset += hdr_size; - // Section headers. - offset += self.sections.len() * sechdr_size; - - // Calculate size of section data. - let mut section_offsets = vec![SectionOffsets::default(); self.sections.len()]; - for (index, section) in self.sections.iter().enumerate() { - let len = section.data.len(); - let sectype = section.kind; - // Section address should be 0 for all sections except the .text, .data, and .bss sections. - if sectype == SectionKind::Data - || sectype == SectionKind::Text - || sectype == SectionKind::UninitializedData - { - section_offsets[index].address = address as u64; - address += len; - address = align(address, 4); - } else { - section_offsets[index].address = 0; - } - if len != 0 { - // Set the default section alignment as 4. - offset = align(offset, 4); - section_offsets[index].data_offset = offset; - offset += len; - } else { - section_offsets[index].data_offset = 0; - } - } - - // Calculate size of relocations. - for (index, section) in self.sections.iter().enumerate() { - let count = section.relocations.len(); - if count != 0 { - section_offsets[index].reloc_offset = offset; - offset += count * rel_size; - } else { - section_offsets[index].reloc_offset = 0; - } - } - - // Calculate size of symbols. - let mut file_str_id = None; - let mut symbol_offsets = vec![SymbolOffsets::default(); self.symbols.len()]; - let mut symtab_count = 0; - for (index, symbol) in self.symbols.iter().enumerate() { - symbol_offsets[index].index = symtab_count; - symtab_count += 1; - - let storage_class = if let SymbolFlags::Xcoff { n_sclass, .. } = symbol.flags { - n_sclass - } else { - match symbol.kind { - SymbolKind::Null => xcoff::C_NULL, - SymbolKind::File => xcoff::C_FILE, - SymbolKind::Text | SymbolKind::Data | SymbolKind::Tls => { - if symbol.is_local() { - xcoff::C_STAT - } else if symbol.weak { - xcoff::C_WEAKEXT - } else { - xcoff::C_EXT - } - } - SymbolKind::Section | SymbolKind::Label | SymbolKind::Unknown => { - return Err(Error(format!( - "unimplemented symbol `{}` kind {:?}", - symbol.name().unwrap_or(""), - symbol.kind - ))); - } - } - }; - symbol_offsets[index].storage_class = storage_class; - - if storage_class == xcoff::C_FILE { - if is_64 && file_str_id.is_none() { - file_str_id = Some(strtab.add(b".file")); - } - if symbol.name.len() > 8 { - symbol_offsets[index].str_id = Some(strtab.add(&symbol.name)); - } - } else if is_64 || symbol.name.len() > 8 { - symbol_offsets[index].str_id = Some(strtab.add(&symbol.name)); - } - - symbol_offsets[index].aux_count = 0; - match storage_class { - xcoff::C_FILE => { - symbol_offsets[index].aux_count = 1; - symtab_count += 1; - } - xcoff::C_EXT | xcoff::C_WEAKEXT | xcoff::C_HIDEXT => { - symbol_offsets[index].aux_count = 1; - symtab_count += 1; - } - // TODO: support auxiliary entry for other types of symbol. - _ => {} - } - } - let symtab_offset = offset; - let symtab_len = symtab_count * sym_size; - offset += symtab_len; - - // Calculate size of strtab. - let strtab_offset = offset; - let mut strtab_data = Vec::new(); - // First 4 bytes of strtab are the length. - strtab.write(4, &mut strtab_data); - let strtab_len = strtab_data.len() + 4; - offset += strtab_len; - - // Start writing. - buffer - .reserve(offset) - .map_err(|_| Error(String::from("Cannot allocate buffer")))?; - - // Write file header. - if is_64 { - let header = xcoff::FileHeader64 { - f_magic: U16::new(BE, xcoff::MAGIC_64), - f_nscns: U16::new(BE, self.sections.len() as u16), - f_timdat: U32::new(BE, 0), - f_symptr: U64::new(BE, symtab_offset as u64), - f_nsyms: U32::new(BE, symtab_count as u32), - f_opthdr: U16::new(BE, 0), - f_flags: match self.flags { - FileFlags::Xcoff { f_flags } => U16::new(BE, f_flags), - _ => U16::default(), - }, - }; - buffer.write(&header); - } else { - let header = xcoff::FileHeader32 { - f_magic: U16::new(BE, xcoff::MAGIC_32), - f_nscns: U16::new(BE, self.sections.len() as u16), - f_timdat: U32::new(BE, 0), - f_symptr: U32::new(BE, symtab_offset as u32), - f_nsyms: U32::new(BE, symtab_count as u32), - f_opthdr: U16::new(BE, 0), - f_flags: match self.flags { - FileFlags::Xcoff { f_flags } => U16::new(BE, f_flags), - _ => U16::default(), - }, - }; - buffer.write(&header); - } - - // Write section headers. - for (index, section) in self.sections.iter().enumerate() { - let mut sectname = [0; 8]; - sectname - .get_mut(..section.name.len()) - .ok_or_else(|| { - Error(format!( - "section name `{}` is too long", - section.name().unwrap_or(""), - )) - })? - .copy_from_slice(§ion.name); - let flags = if let SectionFlags::Xcoff { s_flags } = section.flags { - s_flags - } else { - match section.kind { - SectionKind::Text - | SectionKind::ReadOnlyData - | SectionKind::ReadOnlyString - | SectionKind::ReadOnlyDataWithRel => xcoff::STYP_TEXT, - SectionKind::Data => xcoff::STYP_DATA, - SectionKind::UninitializedData => xcoff::STYP_BSS, - SectionKind::Tls => xcoff::STYP_TDATA, - SectionKind::UninitializedTls => xcoff::STYP_TBSS, - SectionKind::OtherString => xcoff::STYP_INFO, - SectionKind::Debug => xcoff::STYP_DEBUG, - SectionKind::Other | SectionKind::Metadata => 0, - SectionKind::Note - | SectionKind::Linker - | SectionKind::Common - | SectionKind::Unknown - | SectionKind::TlsVariables - | SectionKind::Elf(_) => { - return Err(Error(format!( - "unimplemented section `{}` kind {:?}", - section.name().unwrap_or(""), - section.kind - ))); - } - } - .into() - }; - if is_64 { - let section_header = xcoff::SectionHeader64 { - s_name: sectname, - s_paddr: U64::new(BE, section_offsets[index].address), - // This field has the same value as the s_paddr field. - s_vaddr: U64::new(BE, section_offsets[index].address), - s_size: U64::new(BE, section.data.len() as u64), - s_scnptr: U64::new(BE, section_offsets[index].data_offset as u64), - s_relptr: U64::new(BE, section_offsets[index].reloc_offset as u64), - s_lnnoptr: U64::new(BE, 0), - s_nreloc: U32::new(BE, section.relocations.len() as u32), - s_nlnno: U32::new(BE, 0), - s_flags: U32::new(BE, flags), - s_reserve: U32::new(BE, 0), - }; - buffer.write(§ion_header); - } else { - let section_header = xcoff::SectionHeader32 { - s_name: sectname, - s_paddr: U32::new(BE, section_offsets[index].address as u32), - // This field has the same value as the s_paddr field. - s_vaddr: U32::new(BE, section_offsets[index].address as u32), - s_size: U32::new(BE, section.data.len() as u32), - s_scnptr: U32::new(BE, section_offsets[index].data_offset as u32), - s_relptr: U32::new(BE, section_offsets[index].reloc_offset as u32), - s_lnnoptr: U32::new(BE, 0), - // TODO: If more than 65,534 relocation entries are required, the field - // value will be 65535, and an STYP_OVRFLO section header will contain - // the actual count of relocation entries in the s_paddr field. - s_nreloc: U16::new(BE, section.relocations.len() as u16), - s_nlnno: U16::new(BE, 0), - s_flags: U32::new(BE, flags), - }; - buffer.write(§ion_header); - } - } - - // Write section data. - for (index, section) in self.sections.iter().enumerate() { - let len = section.data.len(); - if len != 0 { - write_align(buffer, 4); - debug_assert_eq!(section_offsets[index].data_offset, buffer.len()); - buffer.write_bytes(§ion.data); - } - } - - // Write relocations. - for (index, section) in self.sections.iter().enumerate() { - if !section.relocations.is_empty() { - debug_assert_eq!(section_offsets[index].reloc_offset, buffer.len()); - for reloc in §ion.relocations { - let rtype = match reloc.kind { - RelocationKind::Absolute => xcoff::R_POS, - RelocationKind::Relative => xcoff::R_REL, - RelocationKind::Got => xcoff::R_TOC, - RelocationKind::Xcoff(x) => x, - _ => { - return Err(Error(format!("unimplemented relocation {:?}", reloc))); - } - }; - if is_64 { - let xcoff_rel = xcoff::Rel64 { - r_vaddr: U64::new(BE, reloc.offset), - r_symndx: U32::new(BE, symbol_offsets[reloc.symbol.0].index as u32), - // Specifies the bit length of the relocatable reference minus one. - r_rsize: (reloc.size - 1), - r_rtype: rtype, - }; - buffer.write(&xcoff_rel); - } else { - let xcoff_rel = xcoff::Rel32 { - r_vaddr: U32::new(BE, reloc.offset as u32), - r_symndx: U32::new(BE, symbol_offsets[reloc.symbol.0].index as u32), - r_rsize: (reloc.size - 1), - r_rtype: rtype, - }; - buffer.write(&xcoff_rel); - } - } - } - } - - // Write symbols. - debug_assert_eq!(symtab_offset, buffer.len()); - for (index, symbol) in self.symbols.iter().enumerate() { - let (n_value, section_kind) = if let SymbolSection::Section(id) = symbol.section { - ( - section_offsets[id.0].address + symbol.value, - self.sections[id.0].kind, - ) - } else { - (symbol.value, SectionKind::Unknown) - }; - let n_scnum = match symbol.section { - SymbolSection::None => { - debug_assert_eq!(symbol.kind, SymbolKind::File); - xcoff::N_DEBUG - } - SymbolSection::Undefined | SymbolSection::Common => xcoff::N_UNDEF, - SymbolSection::Absolute => xcoff::N_ABS, - SymbolSection::Section(id) => id.0 as i16 + 1, - }; - let n_sclass = symbol_offsets[index].storage_class; - let n_type = if (symbol.scope == SymbolScope::Linkage) - && (n_sclass == xcoff::C_EXT - || n_sclass == xcoff::C_WEAKEXT - || n_sclass == xcoff::C_HIDEXT) - { - xcoff::SYM_V_HIDDEN - } else { - 0 - }; - let n_numaux = symbol_offsets[index].aux_count; - if is_64 { - let str_id = if n_sclass == xcoff::C_FILE { - file_str_id.unwrap() - } else { - symbol_offsets[index].str_id.unwrap() - }; - let xcoff_sym = xcoff::Symbol64 { - n_value: U64::new(BE, n_value), - n_offset: U32::new(BE, strtab.get_offset(str_id) as u32), - n_scnum: I16::new(BE, n_scnum), - n_type: U16::new(BE, n_type), - n_sclass, - n_numaux, - }; - buffer.write(&xcoff_sym); - } else { - let mut sym_name = [0; 8]; - if n_sclass == xcoff::C_FILE { - sym_name[..5].copy_from_slice(b".file"); - } else if symbol.name.len() <= 8 { - sym_name[..symbol.name.len()].copy_from_slice(&symbol.name[..]); - } else { - let str_offset = strtab.get_offset(symbol_offsets[index].str_id.unwrap()); - sym_name[4..8].copy_from_slice(&u32::to_be_bytes(str_offset as u32)); - } - let xcoff_sym = xcoff::Symbol32 { - n_name: sym_name, - n_value: U32::new(BE, n_value as u32), - n_scnum: I16::new(BE, n_scnum), - n_type: U16::new(BE, n_type), - n_sclass, - n_numaux, - }; - buffer.write(&xcoff_sym); - } - // Generate auxiliary entries. - if n_sclass == xcoff::C_FILE { - debug_assert_eq!(n_numaux, 1); - let mut x_fname = [0; 8]; - if symbol.name.len() <= 8 { - x_fname[..symbol.name.len()].copy_from_slice(&symbol.name[..]); - } else { - let str_offset = strtab.get_offset(symbol_offsets[index].str_id.unwrap()); - x_fname[4..8].copy_from_slice(&u32::to_be_bytes(str_offset as u32)); - } - if is_64 { - let file_aux = xcoff::FileAux64 { - x_fname, - x_fpad: Default::default(), - x_ftype: xcoff::XFT_FN, - x_freserve: Default::default(), - x_auxtype: xcoff::AUX_FILE, - }; - buffer.write(&file_aux); - } else { - let file_aux = xcoff::FileAux32 { - x_fname, - x_fpad: Default::default(), - x_ftype: xcoff::XFT_FN, - x_freserve: Default::default(), - }; - buffer.write(&file_aux); - } - } else if n_sclass == xcoff::C_EXT - || n_sclass == xcoff::C_WEAKEXT - || n_sclass == xcoff::C_HIDEXT - { - debug_assert_eq!(n_numaux, 1); - let (x_smtyp, x_smclas) = if let SymbolFlags::Xcoff { - x_smtyp, x_smclas, .. - } = symbol.flags - { - (x_smtyp, x_smclas) - } else { - match symbol.kind { - SymbolKind::Text => (xcoff::XTY_SD, xcoff::XMC_PR), - SymbolKind::Data => { - if section_kind == SectionKind::UninitializedData { - (xcoff::XTY_CM, xcoff::XMC_BS) - } else if section_kind == SectionKind::ReadOnlyData { - (xcoff::XTY_SD, xcoff::XMC_RO) - } else { - (xcoff::XTY_SD, xcoff::XMC_RW) - } - } - SymbolKind::Tls => { - if section_kind == SectionKind::UninitializedTls { - (xcoff::XTY_CM, xcoff::XMC_UL) - } else { - (xcoff::XTY_SD, xcoff::XMC_TL) - } - } - _ => { - return Err(Error(format!( - "unimplemented symbol `{}` kind {:?}", - symbol.name().unwrap_or(""), - symbol.kind - ))); - } - } - }; - let scnlen = if let SymbolFlags::Xcoff { - containing_csect: Some(containing_csect), - .. - } = symbol.flags - { - symbol_offsets[containing_csect.0].index as u64 - } else { - symbol.size - }; - if is_64 { - let csect_aux = xcoff::CsectAux64 { - x_scnlen_lo: U32::new(BE, (scnlen & 0xFFFFFFFF) as u32), - x_scnlen_hi: U32::new(BE, ((scnlen >> 32) & 0xFFFFFFFF) as u32), - x_parmhash: U32::new(BE, 0), - x_snhash: U16::new(BE, 0), - x_smtyp, - x_smclas, - pad: 0, - x_auxtype: xcoff::AUX_CSECT, - }; - buffer.write(&csect_aux); - } else { - let csect_aux = xcoff::CsectAux32 { - x_scnlen: U32::new(BE, scnlen as u32), - x_parmhash: U32::new(BE, 0), - x_snhash: U16::new(BE, 0), - x_smtyp, - x_smclas, - x_stab: U32::new(BE, 0), - x_snstab: U16::new(BE, 0), - }; - buffer.write(&csect_aux); - } - } - } - - // Write string table. - debug_assert_eq!(strtab_offset, buffer.len()); - buffer.write_bytes(&u32::to_be_bytes(strtab_len as u32)); - buffer.write_bytes(&strtab_data); - - debug_assert_eq!(offset, buffer.len()); - Ok(()) - } -} |