dynamic.py: move logic around to allow symbol access more easily (#346)
So far, the implementation of num_symbols() and get_symbol()
in the DynamicSegment class depended on iter_symbols().
However, most part of iter_symbols() is actually about
determining the number of symbols. Let's move that logic to
the correct method and use it in iter_symbols().
Additionally, in an ELF file without any exported symbols,
the hash table will be empty and will thus return a too low
number of symbols. However, a loader might still need to
access the imported symbols (which also have an entry in
the symbol table, with st_shndx set to SHN_UNDEF). To allow
this, make get_symbol() take any index and simply read the
symbol data from the corresponding index, and use
get_symbol() from iter_symbols(). This way, one can for
example use symbol index information from relocation entries
to directly access the symbol data.
These changes also make the logic in DynamicSegment resemble
the code in SymbolTableSection more closely.
Fixes: #342