420 Commits

Author SHA1 Message Date
Christopher Cole
a4b075766d
Change ParsingTable::new() to no longer take entsize option
All of the uses validate the entsize as found in the file, so there's no need
to perform the duplicate validation again in the constructor. It's desireable
to do the validation before trying to get the buffer to back the table. So while
it'd be nice to have the table do the checking automatically for you, it happens
too late when done automatically that way.
2022-10-30 22:11:37 -07:00
Christopher Cole
45574cbe11
Remove internal entsize field from ParsingTable in favor of P::size_for(class)
There's no need to represent it as bytes in the actual table representation when
we've validated that it's a known constant for the given ELF class that we're parsing.
2022-10-30 21:56:50 -07:00
Christopher Cole
72fb2f0aef
Add size validation when parsing entsizes
This is done by making each ParseAt type aware of the sizes based on the ELF class
via a new ParseAT::size_for(class) method, then adding validation checks based on that.
2022-10-30 21:48:08 -07:00
Christopher Cole
15a680c7d5
Remove unhelpful SectionFlag wrapper type
The rest of the ELF parsing impl has moved away from these wrapper types for constants
since they don't really provide much value.
2022-10-30 19:40:14 -07:00
Christopher Cole
ff73fcea8c
Fix copy-paste typo in CompressionHeader parse test names 2022-10-30 15:47:57 -07:00
Christopher Cole
4fffc808c4
Update doc comment on File::segments() 2022-10-30 15:40:58 -07:00
Christopher Cole
0c8691753a
Remove Display impl for FileHeader
This output is opinionated in a way that is likely unhelpful for users of this
library. If someone is wanting to display FileHeader contents, they likely want
their own string formatting, and can construct it with the to_str helpers.
2022-10-30 15:22:17 -07:00
Christopher Cole
44df61f019
Move file types to to_str pattern 2022-10-30 15:18:55 -07:00
Christopher Cole
720aa4a9cf
Remove to_str match for SHT_NUM
This is an marker for the highest top of the reserved range and is not
itself a reserved identifier.
2022-10-30 14:58:28 -07:00
Christopher Cole
fcea01e6a5
Use new to_str pattern for ProgType and ProgFlag 2022-10-30 14:50:37 -07:00
Christopher Cole
cbdfec879b
Remove Display impl for ProgramHeader
This output is opinionated in a way that is likely unhelpful for users of this
library. If someone is wanting to display ProgramHeader contents, they likely want
their own string formatting, and can construct it with the to_str helpers.
2022-10-30 14:43:08 -07:00
Christopher Cole
fa7490a1aa
Remove unnecessary format! from to_str write! calls 2022-10-30 14:42:00 -07:00
Christopher Cole
7dd31929cc
Use new to_str pattern for SectionType 2022-10-30 14:39:46 -07:00
Christopher Cole
ac354f4969
Remove Display impl for SectionHeader
This output is opinionated in a way that is likely unhelpful for users of this
library. If someone is wanting to display SectionHeader contents, they likely want
their own string formatting, and can construct it with the to_str helpers.
2022-10-30 14:35:46 -07:00
Christopher Cole
049d6425cf
Add ch_type_to_str for CompressionHeader.ch_type 2022-10-30 14:33:31 -07:00
Christopher Cole
1a14f2886c
Remove Display impl for Symbol
This output is opinionated in a way that is likely unhelpful for users of this
library. If someone is wanting to display Symbol contents, they likely want
their own string formatting, and can construct it with the to_str helpers.
2022-10-30 14:29:48 -07:00
Christopher Cole
be60cccbf9
Add to_str feature which exports to_str and Display impls for gabi constants
This has a few motivations:
* Move the big blocks of code dedicated to providing human readable strings for
  gabi constants out of the way. This code can be long and distracting from the actual
  parsing functionality.
* Allow users to opt out of this functionality if they don't need it. The big blocks
  of &'static str definitions can add a fair amount to the resulting library size. For
  users who are trying to optimize for library size, these to_str methods are often unneeded.
* The to_str method's Option return value allows users to decide how they want to display
  unknown values.
2022-10-30 14:26:07 -07:00
Christopher Cole
b73c9ba515
Fix copy-paste error in a test's error message 2022-10-30 13:30:57 -07:00
Christopher Cole
e0cad991f0
Remove deprecated File::section_data_for_header() in favor of File::section_data()
section_data() is a superset of the functionality of section_data_for_header()
2022-10-30 13:14:32 -07:00
Christopher Cole
ebd64f54fa
Change File's SectionHeader interfaces to provide a ParsingTable
The table has additional helpful features, like .get() to parse a given index in the table,
while still allowing access to the ParsingIterator interface via .iter()

Also remove dubiously helpful File::section_strings() method

If you want the strings, you probably also want the headers, so use the section_headers_with_strtab()
method.
2022-10-30 13:12:43 -07:00
Christopher Cole
15a229d9d1
Change File::segments() to return a ParsingTable instead of just a ParsingIterator
The table has additional helpful features, like .get() to parse a given index in the table,
while still allowing access to the ParsingIterator interface via .iter()
2022-10-30 12:49:52 -07:00
Christopher Cole
3058d54982
Remove ParseError::UnsupportedElfVersion in favor of more general ParseError::UnsupportedVersion 2022-10-30 12:44:53 -07:00
Christopher Cole
8771fbbff5
Bump crate version to v0.5.0
New interfaces:
* Add File::symbol_version_table() interface to get the GNU extension symbol versioning table
* Add Symbol.is_undefined() helper to check if a symbol is defined in this object
* Add File::section_data() which opportunistically parses the CompressionHeader if present

Bug fixes:
* Fix StringTable to return a ParseError on index out of bounds instead of panicking
* Fix File::section_data_as_rels to properly parse Rels (not Relas)
2022-10-30 12:35:39 -07:00
Christopher Cole
7006cb20c3
Rename Symbol::undefined() -> Symbol::is_undefined()
This better matches other boolean flag helper method names
2022-10-30 12:24:54 -07:00
Christopher Cole
29a604e913
Fix File::symbol_version_table() to properly load strings section data
Previously, it would forget to load and then just try to get the strings section data
This would work if some other processing on the file had already loaded the string table
but not if this was the first method that wanted to inspect those strings.

This class of bugs is really an integration with the CachedReadBytes interface, so it
can only get caught if we're testing with that impl. These interface tests should be parameterized
for both interfaces.
2022-10-29 15:58:59 -07:00
Christopher Cole
2162e6e347
File::symbol_version_table -> Stop iterating the section headers once we've found our shdrs 2022-10-29 14:22:01 -07:00
Christopher Cole
8577748e63
Add File::symbol_version_table() interface to get the GNU extension symbol versioning table 2022-10-29 14:19:33 -07:00
Christopher Cole
37a0da0b64
Add a VersionTable to interface with the GNU symbol versioning VerNeed VerDefs structures
This is a zero-alloc interface which parses on-demand, which can be desireable if you can't
or don't want to allocate, but is less CPU-efficient if you're doing a lot of look ups on the table.
2022-10-28 16:44:20 -07:00
Christopher Cole
c9a50c95cb
Fix StringTable to return a ParseError on index out of bounds instead of panicking 2022-10-28 15:47:02 -07:00
Christopher Cole
84485adf10
Add constants for .gnu symbol version extension sections' flag fields 2022-10-28 14:14:40 -07:00
Christopher Cole
899e6035f6
Add VersionIndex::is_hidden() to check if a symbol should be visible for linking
Also, change VersionIndex methods to act on a reference so that they don't move/consume
the value when called.
2022-10-28 14:08:38 -07:00
Christopher Cole
da3eaf169e
Elide VerNeed.vn_version by treating an invalid value as a ParseError
There's only one valid version number, so there's no need to include this field
in the parsed result.
2022-10-28 13:53:34 -07:00
Christopher Cole
870cab0159
Change the various Ver* struct _need and _aux fields to be private
These are just used as part of parsing and aren't important for users of the interface.
2022-10-28 13:45:10 -07:00
Christopher Cole
e1d71d9447
Add Symbol.undefined() helper to test if a symbol is defined in this object or not 2022-10-27 14:45:33 -07:00
Christopher Cole
7513214a6a
Document that the gnu verneed and verdef sections' sh_info field also contains the number of entries 2022-10-27 14:11:43 -07:00
Christopher Cole
c1b18674f7
Remove unused SymbolIterator type
This is now given to us for free by the ParsingTable's iterator interfaces
2022-10-26 17:33:15 -07:00
Christopher Cole
4bddfe3269
Replace .gnu.version section parsing type from ParsingIterator to ParsingTable
This more closely matches the datastructure and its use-case. Users are likely
wanting to look up the VerNeeds and VerDefs for a particular symbol in the .dynsym
table, and to do so they'll need to look up the VersionIndex by the Symbol's index
in the .dynsym table. The ParsingTable helps provide that interface with its .get(index)
method.

Alternatively, someone could do a variant of zip(SymbolTable.iter(), VersionTable.iter())
to have the Symbol alongside the VersionIndex, which is also supported by VersionTable.
2022-10-26 17:21:19 -07:00
Christopher Cole
b331fdf832
Add a generic ParsingTable impl to go alongside the ParsingIterator
Also, use this ParsingTable to replace the hand-rolled SymbolTable.

This implements a lazily-parsed table/array of structs that can be parsed
with the ParseAt trait that drives the parsing of our ELF structs.

Elements in the table are lazily parsed on-demand via the .get(index)
method. The table can also optionally be converted into a ParsingIterator
with either iter() or into_iter(), meaning the ParsingTable can be used
like so:

```
let table = ParsingTable<Foo>::new(...)
for foo in Table {
    ... do things with parsed Foo
}
```

or
```
let table = ParsingTable<Foo>::new(...)
for foo in Table.iter() {
    ... do things with parsed Foo
}
for foo in Table.iter() {
    ... do another pass of things with parsed Foo
}
```

Note that the second pattern will re-parse the second time. Useful
if you're wanting to avoid allocations, but otherwise it's probably
more useful to .collect() the iterator into a Vec<Foo>.
2022-10-26 17:10:45 -07:00
Christopher Cole
4600c54657
Handle the case where the _cnt field expects more entries than there are
I think that ideally this would be able to yield a ParseError in some way,
as it likely indicates corrupted section data. All of our iterators silently
end iteration on ParseErrors currently, though, so this is in line with
existing patterns of behavior.
2022-10-26 15:30:44 -07:00
Christopher Cole
273b0e6182
Move around some code in gnu_symver.rs
move iters to come after the types they iterate over. I think this
reads a bit easier
2022-10-26 15:17:10 -07:00
Christopher Cole
e70d43d03d
Add VerNeedIterator which parses Version Need/Requirements and their associated Auxilliary info lists
This represents an iterative parser for the contents of the .gnu.version_r
section - the interspersed lists of VerNeed and VerNeedAux structs.
2022-10-26 15:14:50 -07:00
Christopher Cole
a8fb4bfb16
Add VerNeedAuxIterator which parses Version Need/Requirement Auxillary info lists
These are found in the .gnu.version_r section interspersed with VerNeed entries.
2022-10-26 15:09:49 -07:00
Christopher Cole
cca2c02a31
Add some more figlets in gnu_symver.rs
This helps the eye track groups of related code when scrolling through the file
2022-10-26 14:47:53 -07:00
Christopher Cole
d401c17d10
Get rid of unnecessary EndianParseExt trait
There was only one implementer of this trait, on &[u8], and the indirection
didn't serve any real purpose. The indirection via the double &&[u8] impl was
more expensive than necessary, and the indirection also added a layer of unnecessary
cognitive overhead to reading the code.

This goes back to having simple parse methods for the endian-aware integer parsing
which operate on byte slices.
2022-10-26 14:24:23 -07:00
Christopher Cole
37e0904787
Elide VerDef.vd_version by treating an invalid value as a ParseError
There's only one valid version number, so there's no need to include this field
in the parsed result.
2022-10-26 00:47:43 -07:00
Christopher Cole
6ba37955db
Add VerDefIterator which parses Version Definition and their associated Auxilliary info lists
This represents an iterative parser for the contents of the .gnu.version_d
section - the interspersed lists of VerDef and VerDefAux structs.
2022-10-26 00:11:48 -07:00
Christopher Cole
8ac79d37c2
Add VerDefAuxIterator which parses Version Definition Auxillary info lists
These are found in the .gnu.version_d section interspersed with VerDef entries.
2022-10-25 23:34:23 -07:00
Christopher Cole
cbda6b3d99
Properly escape some [] in a doc comment 2022-10-25 19:03:13 -07:00
Christopher Cole
b01eb0e79d
Add VerNeedAux parsing for entries in the GNU extension section .gnu.version_r
These other type of entries are found in the .gnu.version_r section of type SHT_GNU_VERNEED.
This only parses the type, and is not hooked up to anything else yet.
2022-10-25 18:29:56 -07:00
Christopher Cole
ea1439d2ee
Remove some extraneous and erroneous copy-pasted comments in some unit test set up code 2022-10-25 18:21:17 -07:00