]> git.proxmox.com Git - rustc.git/blob - vendor/object-0.31.1/src/read/elf/comdat.rs
New upstream version 1.73.0+dfsg1
[rustc.git] / vendor / object-0.31.1 / src / read / elf / comdat.rs
1 use core::fmt::Debug;
2 use core::{iter, slice, str};
3
4 use crate::elf;
5 use crate::endian::{Endianness, U32Bytes};
6 use crate::read::{self, ComdatKind, ObjectComdat, ReadError, ReadRef, SectionIndex, SymbolIndex};
7
8 use super::{ElfFile, FileHeader, SectionHeader, Sym};
9
10 /// An iterator over the COMDAT section groups of an `ElfFile32`.
11 pub type ElfComdatIterator32<'data, 'file, Endian = Endianness, R = &'data [u8]> =
12 ElfComdatIterator<'data, 'file, elf::FileHeader32<Endian>, R>;
13 /// An iterator over the COMDAT section groups of an `ElfFile64`.
14 pub type ElfComdatIterator64<'data, 'file, Endian = Endianness, R = &'data [u8]> =
15 ElfComdatIterator<'data, 'file, elf::FileHeader64<Endian>, R>;
16
17 /// An iterator over the COMDAT section groups of an `ElfFile`.
18 #[derive(Debug)]
19 pub struct ElfComdatIterator<'data, 'file, Elf, R = &'data [u8]>
20 where
21 Elf: FileHeader,
22 R: ReadRef<'data>,
23 {
24 pub(super) file: &'file ElfFile<'data, Elf, R>,
25 pub(super) iter: iter::Enumerate<slice::Iter<'data, Elf::SectionHeader>>,
26 }
27
28 impl<'data, 'file, Elf, R> Iterator for ElfComdatIterator<'data, 'file, Elf, R>
29 where
30 Elf: FileHeader,
31 R: ReadRef<'data>,
32 {
33 type Item = ElfComdat<'data, 'file, Elf, R>;
34
35 fn next(&mut self) -> Option<Self::Item> {
36 for (_index, section) in self.iter.by_ref() {
37 if let Some(comdat) = ElfComdat::parse(self.file, section) {
38 return Some(comdat);
39 }
40 }
41 None
42 }
43 }
44
45 /// A COMDAT section group of an `ElfFile32`.
46 pub type ElfComdat32<'data, 'file, Endian = Endianness, R = &'data [u8]> =
47 ElfComdat<'data, 'file, elf::FileHeader32<Endian>, R>;
48 /// A COMDAT section group of an `ElfFile64`.
49 pub type ElfComdat64<'data, 'file, Endian = Endianness, R = &'data [u8]> =
50 ElfComdat<'data, 'file, elf::FileHeader64<Endian>, R>;
51
52 /// A COMDAT section group of an `ElfFile`.
53 #[derive(Debug)]
54 pub struct ElfComdat<'data, 'file, Elf, R = &'data [u8]>
55 where
56 Elf: FileHeader,
57 R: ReadRef<'data>,
58 {
59 file: &'file ElfFile<'data, Elf, R>,
60 section: &'data Elf::SectionHeader,
61 sections: &'data [U32Bytes<Elf::Endian>],
62 }
63
64 impl<'data, 'file, Elf, R> ElfComdat<'data, 'file, Elf, R>
65 where
66 Elf: FileHeader,
67 R: ReadRef<'data>,
68 {
69 fn parse(
70 file: &'file ElfFile<'data, Elf, R>,
71 section: &'data Elf::SectionHeader,
72 ) -> Option<ElfComdat<'data, 'file, Elf, R>> {
73 let (flag, sections) = section.group(file.endian, file.data).ok()??;
74 if flag != elf::GRP_COMDAT {
75 return None;
76 }
77 Some(ElfComdat {
78 file,
79 section,
80 sections,
81 })
82 }
83 }
84
85 impl<'data, 'file, Elf, R> read::private::Sealed for ElfComdat<'data, 'file, Elf, R>
86 where
87 Elf: FileHeader,
88 R: ReadRef<'data>,
89 {
90 }
91
92 impl<'data, 'file, Elf, R> ObjectComdat<'data> for ElfComdat<'data, 'file, Elf, R>
93 where
94 Elf: FileHeader,
95 R: ReadRef<'data>,
96 {
97 type SectionIterator = ElfComdatSectionIterator<'data, 'file, Elf, R>;
98
99 #[inline]
100 fn kind(&self) -> ComdatKind {
101 ComdatKind::Any
102 }
103
104 #[inline]
105 fn symbol(&self) -> SymbolIndex {
106 SymbolIndex(self.section.sh_info(self.file.endian) as usize)
107 }
108
109 fn name_bytes(&self) -> read::Result<&[u8]> {
110 // FIXME: check sh_link
111 let index = self.section.sh_info(self.file.endian) as usize;
112 let symbol = self.file.symbols.symbol(index)?;
113 symbol.name(self.file.endian, self.file.symbols.strings())
114 }
115
116 fn name(&self) -> read::Result<&str> {
117 let name = self.name_bytes()?;
118 str::from_utf8(name)
119 .ok()
120 .read_error("Non UTF-8 ELF COMDAT name")
121 }
122
123 fn sections(&self) -> Self::SectionIterator {
124 ElfComdatSectionIterator {
125 file: self.file,
126 sections: self.sections.iter(),
127 }
128 }
129 }
130
131 /// An iterator over the sections in a COMDAT section group of an `ElfFile32`.
132 pub type ElfComdatSectionIterator32<'data, 'file, Endian = Endianness, R = &'data [u8]> =
133 ElfComdatSectionIterator<'data, 'file, elf::FileHeader32<Endian>, R>;
134 /// An iterator over the sections in a COMDAT section group of an `ElfFile64`.
135 pub type ElfComdatSectionIterator64<'data, 'file, Endian = Endianness, R = &'data [u8]> =
136 ElfComdatSectionIterator<'data, 'file, elf::FileHeader64<Endian>, R>;
137
138 /// An iterator over the sections in a COMDAT section group of an `ElfFile`.
139 #[derive(Debug)]
140 pub struct ElfComdatSectionIterator<'data, 'file, Elf, R = &'data [u8]>
141 where
142 Elf: FileHeader,
143 R: ReadRef<'data>,
144 {
145 file: &'file ElfFile<'data, Elf, R>,
146 sections: slice::Iter<'data, U32Bytes<Elf::Endian>>,
147 }
148
149 impl<'data, 'file, Elf, R> Iterator for ElfComdatSectionIterator<'data, 'file, Elf, R>
150 where
151 Elf: FileHeader,
152 R: ReadRef<'data>,
153 {
154 type Item = SectionIndex;
155
156 fn next(&mut self) -> Option<Self::Item> {
157 let index = self.sections.next()?;
158 Some(SectionIndex(index.get(self.file.endian) as usize))
159 }
160 }