Linux Kernel Architecture

(Jacob Rumans) #1

Chapter7:Modules


unsigned int pcpuindex,
struct module *mod)
{
Elf_Sym *sym = (void *)sechdrs[symindex].sh_addr;
unsigned long secbase;
unsigned int i, n = sechdrs[symindex].sh_size / sizeof(Elf_Sym);
int ret = 0;

for (i = 1; i < n; i++) {
switch (sym[i].st_shndx) {

Different symbol types must be handled differently. This is easiest for absolutely defined symbols because
nothing need be done:

kernel/module.c
case SHN_ABS:
/* Don’t need to do anything */
DEBUGP("Absolute symbol: 0x%08lx\n",
(long)sym[i].st_value);
break;

Undefined symbols must be resolved (I deal below with the correspondingresolve_symbolfunction
that returns the matching address for a given symbol):

kernel/module.c
case SHN_UNDEF:
sym[i].st_value
= resolve_symbol(sechdrs, versindex,
strtab + sym[i].st_name, mod);

/* Ok if resolved. */
if (sym[i].st_value != 0)
break;
/* Ok if weak. */
if (ELF_ST_BIND(sym[i].st_info) == STB_WEAK)
break;

printk(KERN_WARNING "%s: Unknown symbol %s\n",
mod->name, strtab + sym[i].st_name);
ret = -ENOENT;
break; strtab + sym[i].st_name, mod);

If the symbol cannot be resolved because no matching definition is available,resolve_symbolreturns 0.
This is OK if the symbol is defined asweak(see Appendix E); otherwise, the module cannot be inserted
because it references symbols that do not exist.

All other symbols are resolved by looking up their value in the symbol table of the module:

kernel/module.c
default:
secbase = sechdrs[sym[i].st_shndx].sh_addr;
sym[i].st_value += secbase;
Free download pdf