442 Commits

Author SHA1 Message Date
Christopher Cole 2e8365c9f7 Use checked integer math in File::dynamic_section() 2022-11-01 00:34:05 -07:00
Christopher Cole 47b687157d Use checked integer math in File::get_symbol_table_of_type() 2022-11-01 00:31:23 -07:00
Christopher Cole 0564da4f97 Use checked integer math in ParsingTable::get() 2022-11-01 00:21:37 -07:00
Christopher Cole eea7bbc757 Use checked integer math in the various File::section_data* methods 2022-11-01 00:18:50 -07:00
Christopher Cole a2cf456530 Use checked integer math in File::section_data() 2022-11-01 00:05:10 -07:00
Christopher Cole 0421f9bfea Use checked integer math in File::segments() 2022-11-01 00:02:12 -07:00
Christopher Cole 86416f4d0a Use checked integer math in endian-aware integer parsing methods 2022-10-31 23:57:03 -07:00
Christopher Cole 138a5390ba Use checked integer math in File::section_headers() 2022-10-31 23:50:25 -07:00
Christopher Cole 00e30b3c2f Use checked integer math in File::section_headers_by_index() 2022-10-31 23:41:10 -07:00
Christopher Cole 411a9f066d Use checked integer math in File::section_headers_with_strtab()
My plan is to use the correct width of the corresponding ELF types when parsing ELF structures
and then converting them into usize as appropriate when those fields are being interpreted
to locate other elf structures within in-memory buffers. For the common case these days
of 64-bit machines with 64-bit usizes, these conversions will all succeed. For 32-bit
machines, this conversion means that the library will not be able to parse large 64-bit
files. When that happens, though, the library should helpfully return an error instead of crashing.

These same sorts of changes will need to be made throughout the library in order to
harden it against crashing due to integer overflow math (often due to corrupted files).

Fuzzing catches this sort of thing really quickly.

Also, introduce two new resulting ParseError types:
  TryFromIntError and IntegerOverflow
2022-10-31 23:27:40 -07:00
Christopher Cole e5c4892e71 Represent empty string table data with the empty slice instead of None
This matches our other lazy-parsing types
2022-10-31 20:55:31 -07:00
Christopher Cole 277058f448 Inline size constants for ParseAt types
These used to be used by tests, but now that's taken care of automatically
with ParseAt::size_for() in the test helpers.
2022-10-31 20:06:17 -07:00
Christopher Cole af4b57b18c Add some note n_type constants for GNU extension notes. 2022-10-31 19:22:08 -07:00
Christopher Cole 3713bb238f Fix note parsing for 8-byte aligned .note.gnu.property sections
The current state seems to satisfy the cases I've observed so far. We'll see
how many variations of size/alignment exist out in the wild :P
2022-10-31 19:13:13 -07:00
Christopher Cole 877dc3cf6a Add SysVHashTable which interprets the contents of a SHT_HASH section
Note that the SysVHashTable::find() method does not currently take any symbol versioning
into account.

Also, add another sample elf file that contains a two versioned exported
symbols, a SHT_HASH section, a SHT_GNU_HASH section, GNU Symbol
Versioning sections, and .note.gnu.property and .note.gnu.build-id sections.
2022-10-31 17:38:06 -07:00
Christopher Cole 28eec01696 Add StringTable::get_raw() to get an uninterpreted &[u8]
This skips the utf8 validation done in StringTable::get() and is helpful
for code that wants to interpret the raw bytes (such as for calculating hash values).
2022-10-31 14:57:28 -07:00
Christopher Cole 2c03caf2e6 Add ParsingTable.len() method to get the number of elements in the table
Also, backfill some tests of the generic table interface on a simple endian-aware
u32 table impl.
2022-10-31 14:26:19 -07:00
Christopher Cole 4e3ec92061 Also remove FileHeader wrapper types OSABI, Architecture, and ObjectFileType 2022-10-31 12:37:42 -07:00
Christopher Cole 76258711a2 Also remove ProgramHeader wrapper types ProgType and ProgFlag 2022-10-31 12:21:29 -07:00
Christopher Cole 0b3de78a6d Also remove Symbol wrapper types SymbolType SymbolBind SymbolVis 2022-10-31 12:10:11 -07:00
Christopher Cole e7e502aa45 Remove wrapper type SectionType
This didn't end up providing much value. As an interface, we want to be able
to be able to parse files with unknown section types the type had to allow
unknown values anyway. All it provided was an opinionated Display impl,
which can be easily recovered with sh_type_to_str() or sh_type_to_string()
2022-10-31 12:04:52 -07:00
Christopher Cole 2f658264a1 Refactor parsing tests with test helpers parameterized on ParseAt types
This reduces a ton of boiler-plate code. It can also probably be reduced even
further with some macros, but I generally find macros add more cognitive overhead
than they're worth for simple tests like this. Maybe a project for another rainy day ;)
2022-10-30 23:21:05 -07:00
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