Modular IDE:Loading and Symbol Resolution
Initial Core Loading
- Core IDE is loaded at a fixed address by the Prom.
- Core Ide begins executing its script.
- If Core IDE encounters a load command (either via its script or from the
user), it executes the module loading mechanism described below.
Module Loading & Execution Mechanism
- If no other modules have been previously loaded by Core IDE, Core reads
its own symbol table (this is done only once before the first module is
loaded). This symbol table will later be used by Core IDE to resolve core
symbols in IDE modules.
- The load command will only load a module if is a dynamic elf binary (i.e.
the module has been compiled -shared). If this criteria is not met, the
load will fail.
- Now Core IDE begins loading the dynamic elf module binary. To be able to
do proper symbol resolution later, Core IDE needs to make sure that the
following elf program segments exist in the module:
- .MIPS.options segment: contains the value of the GP (global pointer) of the module
- .got segment: contains the Global Offset Table (GOT). The GOT is used to resolve
symbols in the module that refer to Core symbols. Note that a module may
not have a GOT if it has no unresolved symbols.
- .dynsym segment: the dynamic symbol table. This symbol table is used by Core IDE
to find the module's undefined symbols (the dynamic symbol table uses offsets
into the dynamic string table for symbol string names).
- .dynstr segment: the dynamic string table. The string table contains the string
names of the module's symbols. This is used by Core IDE to do symbol look-up
in conjunction with the dynamic symbol table.
- Now Core IDE uses the following symbol resolution mechanism:
- Core IDE scans through the dynamic symbol table (.dynsym) of the module
looking for undefined symbols.
- For each undefined symbol:
- Core IDE uses the module's dynamic string table (.dynstr) to get the symbol's
string name.
- Core IDE tries to look up the unknown symbol's string in its own symbol
table.
- If the symbol is found, Core places the symbol's core address into the symbol's
GOT (.got) entry of the module. Else an error is reported and the load fails
due to an unresolved symbol.
- All symbols are now defined in the module.
- Core IDE uses the .reginfo segment to read the module's GP value. This value
is needed by the initial module code so that it can inialize the $gp register.
This register is needed because all symbol references in the module use
the GOT table which in turn depend on $gp as a base register.
- Core IDE uses the standard argv & environment passing mechanism of the Prom
as follows:
- argv[0] contains the path name of the module
- argv[1] contains the module's GP value in ascii (no leading 0x or 0X).
- the remaining argv strings which were passed to Core IDE from Prom are passed
to the module in argv[2], argv[3], ....
- the environment strings which were passed to Core IDE from Prom, are copied
and passed to the module
- Core IDE jumps to the module's start_module() assembly routine and begins
execution.
- Before any references can be made by the module, its $gp register must be
set so that references can go through the GOT. The very first thing that
start_module() does is convert the GP value string in argv[1] to a hex number
and store it in $gp. Once $gp is set, the module's stack can be initialized,
the original $gp is saved, the original stack is saved, and the C module_main()
function is called.
- module_main() can now set variables in the Core to point to the module's
script and its list of module commands.
- Finally, module_main() calls the Core main() function which starts the parser
on the module's script.
stojanof@engr.sgi.com