1 use core
::convert
::TryInto
;
7 use crate::read
::{ReadError, Result, StringTable}
;
9 /// A trait for generic access to `Dyn32` and `Dyn64`.
10 #[allow(missing_docs)]
11 pub trait Dyn
: Debug
+ Pod
{
13 type Endian
: endian
::Endian
;
15 fn d_tag(&self, endian
: Self::Endian
) -> Self::Word
;
16 fn d_val(&self, endian
: Self::Endian
) -> Self::Word
;
18 /// Try to convert the tag to a `u32`.
19 fn tag32(&self, endian
: Self::Endian
) -> Option
<u32> {
20 self.d_tag(endian
).into().try_into().ok()
23 /// Try to convert the value to a `u32`.
24 fn val32(&self, endian
: Self::Endian
) -> Option
<u32> {
25 self.d_val(endian
).into().try_into().ok()
28 /// Return true if the value is an offset in the dynamic string table.
29 fn is_string(&self, endian
: Self::Endian
) -> bool
{
30 if let Some(tag
) = self.tag32(endian
) {
37 | elf
::DT_FILTER
=> true,
45 /// Use the value to get a string in a string table.
47 /// Does not check for an appropriate tag.
51 strings
: StringTable
<'data
>,
52 ) -> Result
<&'data
[u8]> {
54 .and_then(|val
| strings
.get(val
).ok())
55 .read_error("Invalid ELF dyn string")
58 /// Return true if the value is an address.
59 fn is_address(&self, endian
: Self::Endian
) -> bool
{
60 if let Some(tag
) = self.tag32(endian
) {
75 | elf
::DT_PREINIT_ARRAY
76 | elf
::DT_SYMTAB_SHNDX
80 | elf
::DT_ADDRRNGLO
..=elf
::DT_ADDRRNGHI
=> true,
89 impl<Endian
: endian
::Endian
> Dyn
for elf
::Dyn32
<Endian
> {
94 fn d_tag(&self, endian
: Self::Endian
) -> Self::Word
{
95 self.d_tag
.get(endian
)
99 fn d_val(&self, endian
: Self::Endian
) -> Self::Word
{
100 self.d_val
.get(endian
)
104 impl<Endian
: endian
::Endian
> Dyn
for elf
::Dyn64
<Endian
> {
106 type Endian
= Endian
;
109 fn d_tag(&self, endian
: Self::Endian
) -> Self::Word
{
110 self.d_tag
.get(endian
)
114 fn d_val(&self, endian
: Self::Endian
) -> Self::Word
{
115 self.d_val
.get(endian
)