ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
emu_elf_symbols.c File Reference

Bounded raw-descriptor ELF32 symbol and string streaming. More...

#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include "emu_elf.h"
#include "emu_elf_source_internal.h"
Include dependency graph for emu_elf_symbols.c:

Go to the source code of this file.

Data Structures

struct  emu_elf_section_table_t
 Decoded section-header table geometry. More...
struct  emu_elf_symbol_table_t
 Decoded usable symbol/string table pair. More...
struct  emu_elf_name_match_t
 Incremental exact string comparison state. More...
struct  emu_elf_lookup_t
 Symbol-address lookup callback state. More...

Enumerations

enum  emu_elf_symbol_limit_t : uint32_t {
  k_elf_symbol_entry_min = 16U ,
  k_elf_string_chunk = 256U ,
  k_elf_sht_symtab = 2U ,
  k_elf_word_high_shift = 24U ,
  k_elf_data_offset = 5U ,
  k_elf_shentsize_offset = 46U ,
  k_elf_section_count_offset = 48U
}
 Fixed bytes consumed from section and symbol entries. More...

Functions

static RA8_INTERNAL uint16_t internal_symbol_u16 (const uint8_t *bytes)
 Decode one little-endian 16-bit field.
static RA8_INTERNAL uint32_t internal_symbol_u32 (const uint8_t *bytes)
 Decode one little-endian 32-bit field without alignment assumptions.
static RA8_INTERNAL bool internal_symbol_read (const emu_elf_source_t *elf, uint64_t offset, uint8_t *bytes, size_t length)
 Read one fixed-size source object into supplied scratch.
static RA8_INTERNAL bool internal_section_table (const emu_elf_source_t *elf, emu_elf_section_table_t *table)
 Decode and validate section-header table geometry.
static RA8_INTERNAL bool internal_section_read (const emu_elf_source_t *elf, const emu_elf_section_table_t *sections, uint32_t index, uint8_t bytes[k_elf_shentsize_min])
 Read one section header from validated table geometry.
static RA8_INTERNAL bool internal_symbol_table (const emu_elf_source_t *elf, const emu_elf_section_table_t *sections, const uint8_t bytes[k_elf_shentsize_min], emu_elf_symbol_table_t *table)
 Decode one SHT_SYMTAB and its linked string-table bounds.
static RA8_INTERNAL bool internal_symbol_walk (const emu_elf_source_t *elf, const emu_elf_symbol_table_t *table, emu_elf_symbol_fn fn, void *ctx, uint32_t *visited)
 Walk every entry of one validated symbol table.
uint32_t elf_foreach_symbol (const emu_elf_source_t *elf, emu_elf_symbol_fn fn, void *ctx)
 Walk every symbol in every usable SHT_SYMTAB section.
bool elf_string_foreach (const emu_elf_source_t *elf, uint64_t offset, emu_elf_string_fn fn, void *ctx)
 Stream one NUL-terminated ELF string through bounded stack chunks.
static RA8_INTERNAL bool internal_name_chunk (const char *bytes, size_t length, void *opaque)
 Compare one streamed source-name chunk with the expected suffix.
static RA8_INTERNAL bool internal_lookup_symbol (const emu_elf_symbol_t *symbol, void *opaque)
 Compare one symbol name and stop on an exact hit.
uint32_t elf_sym_addr (const emu_elf_source_t *elf, const char *name, uint32_t *size_out)
 Resolve a function symbol's entry address from the ELF .symtab.

Detailed Description

Bounded raw-descriptor ELF32 symbol and string streaming.

Section headers, symbols, and names are decoded through small stack views. Consumers retain source offsets rather than pointers into a whole-file allocation.

Since
0.1.0

Definition in file emu_elf_symbols.c.

Enumeration Type Documentation

◆ emu_elf_symbol_limit_t

enum emu_elf_symbol_limit_t : uint32_t

Fixed bytes consumed from section and symbol entries.

Enumerator
k_elf_symbol_entry_min 

ELF32 symbol bytes consumed.

k_elf_string_chunk 

Transient streamed-name bytes.

k_elf_sht_symtab 

SHT_SYMTAB section type.

k_elf_word_high_shift 

Shift of byte three in a word.

k_elf_data_offset 

ELF identification data-byte offset.

k_elf_shentsize_offset 

Section-entry-size header offset.

k_elf_section_count_offset 

Section-count header offset.

Definition at line 21 of file emu_elf_symbols.c.

Function Documentation

◆ elf_foreach_symbol()

uint32_t elf_foreach_symbol ( const emu_elf_source_t * elf,
emu_elf_symbol_fn fn,
void * ctx )

Walk every symbol in every usable SHT_SYMTAB section.

Decodes bounded entries and retains only absolute name offsets.

Parameters
[in]elfOpen immutable ELF source.
[in]fnCallback invoked for each decoded entry.
[in,out]ctxOpaque callback context.
Returns
Number of symbol entries handed to fn.
Return values
0The table is malformed or no symbol was delivered.
Precondition
elf remains open for the complete walk.
fn is non-null.
Postcondition
Malformed tables are skipped without out-of-range reads.
Iteration stops when fn returns false.
Note
Uses only bounded stack views and retains no source pointers.
Since
0.1.0

Definition at line 274 of file emu_elf_symbols.c.

References emu_elf_section_table_t::count, internal_section_read(), internal_section_table(), internal_symbol_table(), internal_symbol_walk(), and k_elf_shentsize_min.

Referenced by elf_sym_addr(), and prof_load().

◆ elf_string_foreach()

bool elf_string_foreach ( const emu_elf_source_t * elf,
uint64_t offset,
emu_elf_string_fn fn,
void * ctx )

Stream one NUL-terminated ELF string through bounded stack chunks.

Reads at most 256 bytes per step and never retains source bytes.

Parameters
[in]elfOpen immutable ELF source.
[in]offsetAbsolute first string byte.
[in]fnChunk consumer.
[in,out]ctxOpaque callback context.
Returns
True only when a terminating NUL was found and every callback accepted.
Return values
trueA terminating NUL was found and every callback accepted.
falseA read failed, no NUL was found, or the callback stopped.
Precondition
elf remains open through the stream.
fn is non-null.
Postcondition
No callback chunk contains the terminating NUL.
No read crosses elf->length.
Note
The callback must consume each transient chunk before returning.
Since
0.1.0

Definition at line 298 of file emu_elf_symbols.c.

References internal_symbol_read(), k_elf_string_chunk, emu_elf_source_t::length, and memchr().

Referenced by internal_lookup_symbol(), and internal_prof_name().

◆ elf_sym_addr()

uint32_t elf_sym_addr ( const emu_elf_source_t * elf,
const char * name,
uint32_t * size_out )

Resolve a function symbol's entry address from the ELF .symtab.

Walks the ELF32 section headers for the SHT_SYMTAB table and its linked string table, then matches name and returns its st_value with the Thumb bit cleared (so it can be used as a UC_HOOK_CODE address). Used by the seam installers to shim first-party firmware APIs and by the --dump-sym / --stop-sym probes. Returns 0 if the symbol (or a symbol table) is absent.

Parameters
[in]elfOpen immutable ELF source.
[in]nameNUL-terminated symbol name to find.
[out]size_outIf non-NULL, receives the symbol's st_size (0 if absent).
Returns
Even (Thumb-cleared) symbol address, or 0 if not found.
Return values
0Symbol not present, or the image carries no symbol table.
Precondition
elf remains open throughout the bounded symbol walk.
name is NUL-terminated.
Postcondition
On a hit, size_out (when non-NULL) holds the symbol size.
The source and its descriptor cursor are unmodified.
Note
Not thread-safe; ra8_emulator is single-threaded.
See also
elf_vector_base() The segment-level companion lookup.
Since
0.1.0

Definition at line 401 of file emu_elf_symbols.c.

References emu_elf_lookup_t::address, elf_foreach_symbol(), internal_lookup_symbol(), emu_elf_source_t::length, emu_elf_lookup_t::size, and strlen().

Referenced by emu_tz_install(), emu_tz_patch_cmse(), eth_seam_hook(), fast_sd_seam_install(), internal_main_resolve_symbols(), sym_trace_install(), and usbh_seam_install().

◆ internal_lookup_symbol()

RA8_INTERNAL bool internal_lookup_symbol ( const emu_elf_symbol_t * symbol,
void * opaque )
static

Compare one symbol name and stop on an exact hit.

Streams the referenced name and publishes address/size only on equality.

Parameters
[in]symbolBounds-checked symbol with an absolute name offset.
[in,out]opaqueemu_elf_lookup_t lookup state.
Returns
Whether the symbol walk should continue.
Return values
trueThis symbol did not exactly match the requested name.
falseThe symbol matched and the lookup is complete.
Precondition
symbol is non-null.
opaque points to writable lookup state with an open source.
Postcondition
A match publishes the Thumb-cleared address and symbol size.
A miss leaves the prior lookup result unchanged.
Note
Reads name bytes through bounded transient chunks.
Since
0.1.0

Definition at line 387 of file emu_elf_symbols.c.

References emu_elf_lookup_t::address, emu_elf_name_match_t::compared, elf_string_foreach(), emu_elf_name_match_t::equal, internal_name_chunk(), emu_elf_lookup_t::length, emu_elf_name_match_t::length, emu_elf_lookup_t::name, emu_elf_symbol_t::name_offset, RA8_INTERNAL, emu_elf_lookup_t::size, emu_elf_symbol_t::size, emu_elf_lookup_t::source, and emu_elf_symbol_t::value.

Referenced by elf_sym_addr().

◆ internal_name_chunk()

RA8_INTERNAL bool internal_name_chunk ( const char * bytes,
size_t length,
void * opaque )
static

Compare one streamed source-name chunk with the expected suffix.

Advances the match only while the complete chunk remains equal.

Parameters
[in]bytesNon-empty transient name bytes.
[in]lengthChunk length.
[in,out]opaqueemu_elf_name_match_t comparison state.
Returns
Whether string streaming should continue.
Return values
trueThe chunk matched the expected suffix.
falseThe chunk exceeded or differed from the expected suffix.
Precondition
bytes is non-null and spans length bytes.
opaque points to writable comparison state.
Postcondition
Success advances the compared-byte count by length.
Failure clears the sticky equality flag.
Note
Pure apart from the caller-owned comparison state.
Since
0.1.0

Definition at line 351 of file emu_elf_symbols.c.

References emu_elf_name_match_t::compared, emu_elf_name_match_t::equal, emu_elf_name_match_t::expected, emu_elf_name_match_t::length, memcmp(), and RA8_INTERNAL.

Referenced by internal_lookup_symbol().

◆ internal_section_read()

RA8_INTERNAL bool internal_section_read ( const emu_elf_source_t * elf,
const emu_elf_section_table_t * sections,
uint32_t index,
uint8_t bytes[k_elf_shentsize_min] )
static

Read one section header from validated table geometry.

Computes the entry offset in 64 bits and reads only the fixed prefix.

Parameters
[in]elfOpen source.
[in]sectionsValidated section table.
[in]indexEntry index below sections->count.
[out]bytesForty-byte section-header scratch.
Returns
Whether the exact section header was read.
Return values
trueThe fixed section header was read completely.
falseThe positioned read failed.
Precondition
All pointers are non-null and index is in range.
bytes spans k_elf_shentsize_min bytes.
Postcondition
Success initializes all consumed fields.
Failure does not publish a section view.
Note
Entry padding beyond forty bytes is never read.
Since
0.1.0

Definition at line 166 of file emu_elf_symbols.c.

References emu_elf_section_table_t::entry_size, internal_symbol_read(), k_elf_shentsize_min, emu_elf_section_table_t::offset, and RA8_INTERNAL.

Referenced by elf_foreach_symbol(), and internal_symbol_table().

◆ internal_section_table()

RA8_INTERNAL bool internal_section_table ( const emu_elf_source_t * elf,
emu_elf_section_table_t * table )
static

Decode and validate section-header table geometry.

Rejects wrong magic, class, byte order, and out-of-range tables.

Parameters
[in]elfOpen source.
[out]tableReceives bounded geometry.
Returns
Whether the fixed ELF header and complete table are usable.
Return values
trueComplete validated geometry was published.
falseThe fixed header or table geometry is unusable.
Precondition
table is non-null.
elf remains open.
Postcondition
Success initializes table.
Failure performs no out-of-range table read.
Note
Uses only 52 bytes of stack scratch.
Since
0.1.0

Definition at line 123 of file emu_elf_symbols.c.

References emu_elf_section_table_t::count, emu_elf_section_table_t::entry_size, internal_symbol_read(), internal_symbol_u16(), internal_symbol_u32(), k_elf_data_offset, k_elf_ehdr_size, k_elf_section_count_offset, k_elf_shentsize_min, k_elf_shentsize_offset, emu_elf_source_t::length, memcmp(), emu_elf_section_table_t::offset, and RA8_INTERNAL.

Referenced by elf_foreach_symbol().

◆ internal_symbol_read()

RA8_INTERNAL bool internal_symbol_read ( const emu_elf_source_t * elf,
uint64_t offset,
uint8_t * bytes,
size_t length )
static

Read one fixed-size source object into supplied scratch.

Delegates one exact positioned read and publishes only success.

Parameters
[in]elfOpen source.
[in]offsetSource byte offset.
[out]bytesDestination scratch.
[in]lengthExact object length.
Returns
Whether the complete object was read.
Return values
trueEvery requested byte was read.
falseValidation, EOF, capacity, or host I/O failed.
Precondition
bytes spans length writable bytes.
elf remains open during the read.
Postcondition
Success initializes all destination bytes.
Failure publishes no view.
Note
Thin local predicate over priv_emu_elf_read.
Since
0.1.0

Definition at line 102 of file emu_elf_symbols.c.

References k_emu_elf_io_ok, priv_emu_elf_read(), and emu_elf_io_result_t::status.

Referenced by elf_string_foreach(), internal_section_read(), internal_section_table(), and internal_symbol_walk().

◆ internal_symbol_table()

RA8_INTERNAL bool internal_symbol_table ( const emu_elf_source_t * elf,
const emu_elf_section_table_t * sections,
const uint8_t bytes[k_elf_shentsize_min],
emu_elf_symbol_table_t * table )
static

Decode one SHT_SYMTAB and its linked string-table bounds.

Validates both source ranges and the linked section index before publication.

Parameters
[in]elfOpen source.
[in]sectionsValidated section table.
[in]bytesCandidate section-header bytes.
[out]tableReceives usable paired-table geometry.
Returns
True only for a wholly bounded SHT_SYMTAB pair.
Return values
trueA usable symbol/string pair was published.
falseThe candidate or its linked table is unusable.
Precondition
All pointers are non-null.
bytes contains one exact section header.
Postcondition
Success initializes table with nonzero entry size.
Failure leaves table untouched.
Note
Malformed linked tables are skipped, never partially walked.
Since
0.1.0

Definition at line 192 of file emu_elf_symbols.c.

References emu_elf_section_table_t::count, internal_section_read(), internal_symbol_u32(), k_elf_sh_entsize_off, k_elf_sh_link_off, k_elf_sh_size_off, k_elf_shentsize_min, k_elf_sht_symtab, k_elf_symbol_entry_min, emu_elf_source_t::length, and RA8_INTERNAL.

Referenced by elf_foreach_symbol().

◆ internal_symbol_u16()

RA8_INTERNAL uint16_t internal_symbol_u16 ( const uint8_t * bytes)
static

Decode one little-endian 16-bit field.

Combines exact bytes so host byte order is irrelevant.

Parameters
[in]bytesTwo-byte little-endian field.
Returns
Decoded unsigned value.
Return values
uint16_tThe decoded field.
Precondition
bytes is non-null.
bytes spans at least two readable bytes.
Postcondition
The input bytes remain unchanged.
No global state changes.
Note
Pure and alignment-independent.
Since
0.1.0

Definition at line 60 of file emu_elf_symbols.c.

References RA8_INTERNAL.

Referenced by internal_section_table().

◆ internal_symbol_u32()

RA8_INTERNAL uint32_t internal_symbol_u32 ( const uint8_t * bytes)
static

Decode one little-endian 32-bit field without alignment assumptions.

Combines exact bytes so host byte order is irrelevant.

Parameters
[in]bytesFour-byte little-endian field.
Returns
Decoded unsigned value.
Return values
uint32_tThe decoded field.
Precondition
bytes is non-null.
bytes spans at least four readable bytes.
Postcondition
The input bytes remain unchanged.
No global state changes.
Note
Pure and alignment-independent.
Since
0.1.0

Definition at line 78 of file emu_elf_symbols.c.

References k_elf_word_high_shift, and RA8_INTERNAL.

Referenced by internal_section_table(), internal_symbol_table(), and internal_symbol_walk().

◆ internal_symbol_walk()

RA8_INTERNAL bool internal_symbol_walk ( const emu_elf_source_t * elf,
const emu_elf_symbol_table_t * table,
emu_elf_symbol_fn fn,
void * ctx,
uint32_t * visited )
static

Walk every entry of one validated symbol table.

Reads only fixed entry prefixes and skips invalid string offsets.

Parameters
[in]elfOpen source.
[in]tableValidated paired-table geometry.
[in]fnCaller symbol consumer.
[in,out]ctxOpaque callback context.
[in,out]visitedRunning delivered-entry count.
Returns
True to continue to another table, false after callback stop/read fault.
Return values
trueEvery usable entry was delivered.
falseA read failed or the callback stopped the walk.
Precondition
All pointers are non-null.
Table ranges are wholly source-bounded.
Postcondition
visited advances only for delivered entries.
No symbol source bytes are retained after a callback returns.
Note
Reads sixteen bytes per symbol regardless of padded entry size.
Since
0.1.0

Definition at line 244 of file emu_elf_symbols.c.

References emu_elf_symbol_table_t::entry_size, internal_symbol_read(), internal_symbol_u32(), k_elf_sym_info_off, k_elf_symbol_entry_min, RA8_INTERNAL, emu_elf_symbol_table_t::string_offset, emu_elf_symbol_table_t::string_size, emu_elf_symbol_table_t::symbol_count, and emu_elf_symbol_table_t::symbol_offset.

Referenced by elf_foreach_symbol().