Skip to content

Commit

Permalink
read: add name_bytes methods to traits (#351)
Browse files Browse the repository at this point in the history
  • Loading branch information
philipc committed Aug 14, 2021
1 parent ff17df8 commit aa5895d
Show file tree
Hide file tree
Showing 18 changed files with 227 additions and 51 deletions.
24 changes: 22 additions & 2 deletions src/read/any.rs
Original file line number Diff line number Diff line change
Expand Up @@ -293,9 +293,9 @@ where
}
}

fn section_by_name(&'file self, section_name: &str) -> Option<Section<'data, 'file, R>> {
fn section_by_name_bytes(&'file self, section_name: &[u8]) -> Option<Section<'data, 'file, R>> {
map_inner_option!(self.inner, FileInternal, SectionInternal, |x| x
.section_by_name(section_name))
.section_by_name_bytes(section_name))
.map(|inner| Section { inner })
}

Expand Down Expand Up @@ -554,6 +554,10 @@ impl<'data, 'file, R: ReadRef<'data>> ObjectSegment<'data> for Segment<'data, 'f
with_inner!(self.inner, SegmentInternal, |x| x.data_range(address, size))
}

fn name_bytes(&self) -> Result<Option<&[u8]>> {
with_inner!(self.inner, SegmentInternal, |x| x.name_bytes())
}

fn name(&self) -> Result<Option<&str>> {
with_inner!(self.inner, SegmentInternal, |x| x.name())
}
Expand Down Expand Up @@ -695,10 +699,18 @@ impl<'data, 'file, R: ReadRef<'data>> ObjectSection<'data> for Section<'data, 'f
with_inner!(self.inner, SectionInternal, |x| x.compressed_data())
}

fn name_bytes(&self) -> Result<&[u8]> {
with_inner!(self.inner, SectionInternal, |x| x.name_bytes())
}

fn name(&self) -> Result<&str> {
with_inner!(self.inner, SectionInternal, |x| x.name())
}

fn segment_name_bytes(&self) -> Result<Option<&[u8]>> {
with_inner!(self.inner, SectionInternal, |x| x.segment_name_bytes())
}

fn segment_name(&self) -> Result<Option<&str>> {
with_inner!(self.inner, SectionInternal, |x| x.segment_name())
}
Expand Down Expand Up @@ -817,6 +829,10 @@ impl<'data, 'file, R: ReadRef<'data>> ObjectComdat<'data> for Comdat<'data, 'fil
with_inner!(self.inner, ComdatInternal, |x| x.symbol())
}

fn name_bytes(&self) -> Result<&[u8]> {
with_inner!(self.inner, ComdatInternal, |x| x.name_bytes())
}

fn name(&self) -> Result<&str> {
with_inner!(self.inner, ComdatInternal, |x| x.name())
}
Expand Down Expand Up @@ -1092,6 +1108,10 @@ impl<'data, 'file, R: ReadRef<'data>> ObjectSymbol<'data> for Symbol<'data, 'fil
with_inner!(self.inner, SymbolInternal, |x| x.0.index())
}

fn name_bytes(&self) -> Result<&'data [u8]> {
with_inner!(self.inner, SymbolInternal, |x| x.0.name_bytes())
}

fn name(&self) -> Result<&'data str> {
with_inner!(self.inner, SymbolInternal, |x| x.0.name())
}
Expand Down
11 changes: 8 additions & 3 deletions src/read/coff/comdat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,15 @@ impl<'data, 'file, R: ReadRef<'data>> ObjectComdat<'data> for CoffComdat<'data,
}

#[inline]
fn name(&self) -> Result<&str> {
fn name_bytes(&self) -> Result<&[u8]> {
// Find the name of first symbol referring to the section.
let name = self.symbol.name(self.file.common.symbols.strings())?;
str::from_utf8(name)
self.symbol.name(self.file.common.symbols.strings())
}

#[inline]
fn name(&self) -> Result<&str> {
let bytes = self.name_bytes()?;
str::from_utf8(bytes)
.ok()
.read_error("Non UTF-8 COFF COMDAT name")
}
Expand Down
8 changes: 5 additions & 3 deletions src/read/coff/file.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use alloc::vec::Vec;
use core::str;

use crate::read::{
self, Architecture, Export, FileFlags, Import, NoDynamicRelocationIterator, Object,
Expand Down Expand Up @@ -96,9 +95,12 @@ where
}
}

fn section_by_name(&'file self, section_name: &str) -> Option<CoffSection<'data, 'file, R>> {
fn section_by_name_bytes(
&'file self,
section_name: &[u8],
) -> Option<CoffSection<'data, 'file, R>> {
self.sections()
.find(|section| section.name() == Ok(section_name))
.find(|section| section.name_bytes() == Ok(section_name))
}

fn section_by_index(&'file self, index: SectionIndex) -> Result<CoffSection<'data, 'file, R>> {
Expand Down
28 changes: 22 additions & 6 deletions src/read/coff/section.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,14 +173,20 @@ impl<'data, 'file, R: ReadRef<'data>> ObjectSegment<'data> for CoffSegment<'data
))
}

#[inline]
fn name_bytes(&self) -> Result<Option<&[u8]>> {
self.section
.name(self.file.common.symbols.strings())
.map(Some)
}

#[inline]
fn name(&self) -> Result<Option<&str>> {
let name = self.section.name(self.file.common.symbols.strings())?;
Ok(Some(
str::from_utf8(name)
.ok()
.read_error("Non UTF-8 COFF section name")?,
))
str::from_utf8(name)
.ok()
.read_error("Non UTF-8 COFF section name")
.map(Some)
}
}

Expand Down Expand Up @@ -274,14 +280,24 @@ impl<'data, 'file, R: ReadRef<'data>> ObjectSection<'data> for CoffSection<'data
self.data().map(CompressedData::none)
}

#[inline]
fn name_bytes(&self) -> Result<&[u8]> {
self.section.name(self.file.common.symbols.strings())
}

#[inline]
fn name(&self) -> Result<&str> {
let name = self.section.name(self.file.common.symbols.strings())?;
let name = self.name_bytes()?;
str::from_utf8(name)
.ok()
.read_error("Non UTF-8 COFF section name")
}

#[inline]
fn segment_name_bytes(&self) -> Result<Option<&[u8]>> {
Ok(None)
}

#[inline]
fn segment_name(&self) -> Result<Option<&str>> {
Ok(None)
Expand Down
14 changes: 9 additions & 5 deletions src/read/coff/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -324,14 +324,18 @@ impl<'data, 'file, R: ReadRef<'data>> ObjectSymbol<'data> for CoffSymbol<'data,
self.index
}

fn name(&self) -> read::Result<&'data str> {
let name = if self.symbol.has_aux_file_name() {
fn name_bytes(&self) -> read::Result<&'data [u8]> {
if self.symbol.has_aux_file_name() {
self.file
.symbols
.aux_file_name(self.index.0, self.symbol.number_of_aux_symbols)?
.aux_file_name(self.index.0, self.symbol.number_of_aux_symbols)
} else {
self.symbol.name(self.file.symbols.strings())?
};
self.symbol.name(self.file.symbols.strings())
}
}

fn name(&self) -> read::Result<&'data str> {
let name = self.name_bytes()?;
str::from_utf8(name)
.ok()
.read_error("Non UTF-8 COFF symbol name")
Expand Down
8 changes: 6 additions & 2 deletions src/read/elf/comdat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,11 +110,15 @@ where
SymbolIndex(self.section.sh_info(self.file.endian) as usize)
}

fn name(&self) -> read::Result<&str> {
fn name_bytes(&self) -> read::Result<&[u8]> {
// FIXME: check sh_link
let index = self.section.sh_info(self.file.endian) as usize;
let symbol = self.file.symbols.symbol(index)?;
let name = symbol.name(self.file.endian, self.file.symbols.strings())?;
symbol.name(self.file.endian, self.file.symbols.strings())
}

fn name(&self) -> read::Result<&str> {
let name = self.name_bytes()?;
str::from_utf8(name)
.ok()
.read_error("Non UTF-8 ELF COMDAT name")
Expand Down
25 changes: 14 additions & 11 deletions src/read/elf/file.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use alloc::vec::Vec;
use core::convert::TryInto;
use core::fmt::Debug;
use core::{mem, str};
use core::mem;

use crate::read::{
self, util, Architecture, ByteString, Bytes, Error, Export, FileFlags, Import, Object,
Expand Down Expand Up @@ -93,10 +93,10 @@ where

fn raw_section_by_name<'file>(
&'file self,
section_name: &str,
section_name: &[u8],
) -> Option<ElfSection<'data, 'file, Elf, R>> {
self.sections
.section_by_name(self.endian, section_name.as_bytes())
.section_by_name(self.endian, section_name)
.map(|(index, section)| ElfSection {
file: self,
index: SectionIndex(index),
Expand All @@ -107,18 +107,21 @@ where
#[cfg(feature = "compression")]
fn zdebug_section_by_name<'file>(
&'file self,
section_name: &str,
section_name: &[u8],
) -> Option<ElfSection<'data, 'file, Elf, R>> {
if !section_name.starts_with(".debug_") {
if !section_name.starts_with(b".debug_") {
return None;
}
self.raw_section_by_name(&format!(".zdebug_{}", &section_name[7..]))
let mut name = Vec::with_capacity(section_name.len() + 1);
name.extend_from_slice(b".zdebug_");
name.extend_from_slice(&section_name[7..]);
self.raw_section_by_name(&name)
}

#[cfg(not(feature = "compression"))]
fn zdebug_section_by_name<'file>(
&'file self,
_section_name: &str,
_section_name: &[u8],
) -> Option<ElfSection<'data, 'file, Elf, R>> {
None
}
Expand Down Expand Up @@ -193,9 +196,9 @@ where
}
}

fn section_by_name(
fn section_by_name_bytes(
&'file self,
section_name: &str,
section_name: &[u8],
) -> Option<ElfSection<'data, 'file, Elf, R>> {
self.raw_section_by_name(section_name)
.or_else(|| self.zdebug_section_by_name(section_name))
Expand Down Expand Up @@ -357,7 +360,7 @@ where
}

fn gnu_debuglink(&self) -> read::Result<Option<(&'data [u8], u32)>> {
let section = match self.raw_section_by_name(".gnu_debuglink") {
let section = match self.raw_section_by_name(b".gnu_debuglink") {
Some(section) => section,
None => return Ok(None),
};
Expand All @@ -378,7 +381,7 @@ where
}

fn gnu_debugaltlink(&self) -> read::Result<Option<(&'data [u8], &'data [u8])>> {
let section = match self.raw_section_by_name(".gnu_debugaltlink") {
let section = match self.raw_section_by_name(b".gnu_debugaltlink") {
Some(section) => section,
None => return Ok(None),
};
Expand Down
16 changes: 12 additions & 4 deletions src/read/elf/section.rs
Original file line number Diff line number Diff line change
Expand Up @@ -514,16 +514,24 @@ where
self.compressed_file_range()?.data(self.file.data)
}

fn name(&self) -> read::Result<&str> {
let name = self
.file
fn name_bytes(&self) -> read::Result<&[u8]> {
self.file
.sections
.section_name(self.file.endian, self.section)?;
.section_name(self.file.endian, self.section)
}

fn name(&self) -> read::Result<&str> {
let name = self.name_bytes()?;
str::from_utf8(name)
.ok()
.read_error("Non UTF-8 ELF section name")
}

#[inline]
fn segment_name_bytes(&self) -> read::Result<Option<&[u8]>> {
Ok(None)
}

#[inline]
fn segment_name(&self) -> read::Result<Option<&str>> {
Ok(None)
Expand Down
5 changes: 5 additions & 0 deletions src/read/elf/segment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,11 @@ where
))
}

#[inline]
fn name_bytes(&self) -> read::Result<Option<&[u8]>> {
Ok(None)
}

#[inline]
fn name(&self) -> read::Result<Option<&str>> {
Ok(None)
Expand Down
6 changes: 5 additions & 1 deletion src/read/elf/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -317,8 +317,12 @@ impl<'data, 'file, Elf: FileHeader, R: ReadRef<'data>> ObjectSymbol<'data>
self.index
}

fn name_bytes(&self) -> read::Result<&'data [u8]> {
self.symbol.name(self.endian, self.symbols.strings())
}

fn name(&self) -> read::Result<&'data str> {
let name = self.symbol.name(self.endian, self.symbols.strings())?;
let name = self.name_bytes()?;
str::from_utf8(name)
.ok()
.read_error("Non UTF-8 ELF symbol name")
Expand Down
15 changes: 10 additions & 5 deletions src/read/macho/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,13 +153,13 @@ where
}
}

fn section_by_name(
fn section_by_name_bytes(
&'file self,
section_name: &str,
section_name: &[u8],
) -> Option<MachOSection<'data, 'file, Mach, R>> {
// Translate the "." prefix to the "__" prefix used by OSX/Mach-O, eg
// ".debug_info" to "__debug_info", and limit to 16 bytes total.
let system_name = if section_name.starts_with('.') {
let system_name = if section_name.starts_with(b".") {
if section_name.len() > 15 {
Some(&section_name[1..15])
} else {
Expand All @@ -170,12 +170,12 @@ where
};
let cmp_section_name = |section: &MachOSection<'data, 'file, Mach, R>| {
section
.name()
.name_bytes()
.map(|name| {
section_name == name
|| system_name
.filter(|system_name| {
name.starts_with("__") && name[2..] == **system_name
name.starts_with(b"__") && name[2..] == **system_name
})
.is_some()
})
Expand Down Expand Up @@ -427,6 +427,11 @@ where
unreachable!();
}

#[inline]
fn name_bytes(&self) -> Result<&[u8]> {
unreachable!();
}

#[inline]
fn name(&self) -> Result<&str> {
unreachable!();
Expand Down
10 changes: 10 additions & 0 deletions src/read/macho/section.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,13 +150,23 @@ where
self.data().map(CompressedData::none)
}

#[inline]
fn name_bytes(&self) -> Result<&[u8]> {
Ok(self.internal.section.name())
}

#[inline]
fn name(&self) -> Result<&str> {
str::from_utf8(self.internal.section.name())
.ok()
.read_error("Non UTF-8 Mach-O section name")
}

#[inline]
fn segment_name_bytes(&self) -> Result<Option<&[u8]>> {
Ok(Some(self.internal.section.segment_name()))
}

#[inline]
fn segment_name(&self) -> Result<Option<&str>> {
Ok(Some(
Expand Down
Loading

0 comments on commit aa5895d

Please sign in to comment.