diff --git a/src/elf/parser.rs b/src/elf/parser.rs index 5ab24f55..bb84df89 100644 --- a/src/elf/parser.rs +++ b/src/elf/parser.rs @@ -560,9 +560,11 @@ impl<'elf, B> Cache<'elf, B> { let shdrs = if ehdr.is_32bit() { data.read_pod_slice_ref::(ehdr.shnum) + .map(Cow::Borrowed) .map(ElfN_Shdrs::B32) } else { data.read_pod_slice_ref::(ehdr.shnum) + .map(Cow::Borrowed) .map(ElfN_Shdrs::B64) } .ok_or_invalid_data(|| "failed to read ELF section headers")?; @@ -584,9 +586,11 @@ impl<'elf, B> Cache<'elf, B> { let phdrs = if ehdr.is_32bit() { data.read_pod_slice_ref::(ehdr.phnum) + .map(Cow::Borrowed) .map(ElfN_Phdrs::B32) } else { data.read_pod_slice_ref::(ehdr.phnum) + .map(Cow::Borrowed) .map(ElfN_Phdrs::B64) } .ok_or_invalid_data(|| "failed to read ELF program headers")?; @@ -709,9 +713,11 @@ impl<'elf, B> Cache<'elf, B> { let mut data = self.section_data_raw(idx)?; let syms = if ehdr.is_32bit() { data.read_pod_slice_ref::(count) + .map(Cow::Borrowed) .map(ElfN_Syms::B32) } else { data.read_pod_slice_ref::(count) + .map(Cow::Borrowed) .map(ElfN_Syms::B64) } .ok_or_invalid_data(|| format!("failed to read ELF {section} symbol table contents"))?; @@ -1595,7 +1601,7 @@ mod tests { #[test] fn lookup_symbol_without_match() { let strs = b"\x00_glapi_tls_Context\x00_glapi_get_dispatch_table_size\x00"; - let syms = ElfN_Syms::B64(&[ + let syms = ElfN_Syms::B64(Cow::Borrowed(&[ Elf64_Sym { st_name: 0x21, st_info: 0x12, @@ -1621,7 +1627,7 @@ mod tests { st_value: 0, st_size: 0, }, - ]); + ])); let by_addr_idx = [2, 1, 0]; let result = find_sym(&syms, &by_addr_idx, strs, 0x10d20, SymType::Function).unwrap(); @@ -1658,7 +1664,7 @@ mod tests { assert_eq!(result, None); } - let syms = ElfN_Syms::B64(&[ + let syms = ElfN_Syms::B64(Cow::Borrowed(&[ Elf64_Sym { st_name: 0, st_info: 0, @@ -1683,7 +1689,7 @@ mod tests { st_value: 0x29d00, st_size: 0x0, }, - ]); + ])); let by_addr_idx = [0, 2, 1]; test(&syms, &by_addr_idx); @@ -1765,7 +1771,7 @@ mod tests { backend: aligned_data, elf_data: aligned_data, ehdr: OnceCell::from(ehdr), - shdrs: OnceCell::from(ElfN_Shdrs::B64(shdrs.as_slice())), + shdrs: OnceCell::from(ElfN_Shdrs::B64(Cow::Borrowed(shdrs.as_slice()))), shstrtab: OnceCell::from(b".shstrtab\x00.symtab\x00".as_slice()), phdrs: OnceCell::new(), symtab: OnceCell::new(), diff --git a/src/elf/types.rs b/src/elf/types.rs index 0ef54c95..97c6da4d 100644 --- a/src/elf/types.rs +++ b/src/elf/types.rs @@ -62,10 +62,11 @@ where #[derive(Debug)] pub(crate) enum ElfNSlice<'elf, T> where - T: Has32BitTy, + T: Clone + Has32BitTy, + T::Ty32Bit: Clone, { - B32(&'elf [T::Ty32Bit]), - B64(&'elf [T]), + B32(Cow<'elf, [T::Ty32Bit]>), + B64(Cow<'elf, [T]>), } impl<'elf, T> ElfNSlice<'elf, T> @@ -75,9 +76,9 @@ where { pub fn empty(tybit32: bool) -> Self { if tybit32 { - Self::B32(&[]) + Self::B32(Cow::Borrowed(&[])) } else { - Self::B64(&[]) + Self::B64(Cow::Borrowed(&[])) } } @@ -85,7 +86,7 @@ where self.len() == 0 } - pub fn get(&self, idx: usize) -> Option> { + pub fn get(&self, idx: usize) -> Option> { match self { Self::B32(slice) => Some(ElfN::B32(Cow::Borrowed(slice.get(idx)?))), Self::B64(slice) => Some(ElfN::B64(Cow::Borrowed(slice.get(idx)?))), @@ -99,7 +100,7 @@ where } } - pub fn iter(&self, start_idx: usize) -> impl ExactSizeIterator> { + pub fn iter(&self, start_idx: usize) -> impl ExactSizeIterator> { match self { Self::B32(slice) => Either::A(slice[start_idx..].iter().map(|x| ElfN::B32(Cow::Borrowed(x)))), Self::B64(slice) => Either::B(slice[start_idx..].iter().map(|x| ElfN::B64(Cow::Borrowed(x)))),