void _ldaddname(const char *name) { modent_t *newent; newent = (modent_t *)_ldalloc(sizeof(*newent)); newent->name = name; newent->next = names; names = newent; }
static module_t *_ldlinkobj(module_t *info, char *baseaddr, Elf32_Dyn *dyn) { Elf32_Dyn *curdyn; module_t **curmod; char *name; /* uint32_t d_needed = 0; */ uint32_t d_rpath = 0; uint32_t d_relocsz = 0; uint32_t d_relocent = 0; uint32_t d_plttype = 0; uint32_t d_pltsize = 0; /* create an info structure if we weren't passed one */ if (!info) { info = (module_t *) _ldalloc(sizeof(*info)); memset(info, 0, sizeof(*info)); _ldfirst = info->first = info; curmod = &(info->next); } else { curmod = _ldlast; } info->base = (unsigned long) baseaddr; for (curdyn = dyn; curdyn->d_tag != DT_NULL; curdyn++) { switch (curdyn->d_tag) { case DT_HASH: info->hash = (void *)(info->base + curdyn->d_un.d_ptr); break; case DT_SYMTAB: info->dynsym = (void *)(info->base + curdyn->d_un.d_ptr); break; case DT_STRTAB: info->dynstr = (char *)(info->base + curdyn->d_un.d_ptr); break; case DT_JMPREL: info->pltreloc = (void *)(info->base + curdyn->d_un.d_ptr); break; case DT_RELA: case DT_REL: info->reloc = (void *)(info->base + curdyn->d_un.d_ptr); break; case DT_INIT: info->init = (ldfunc_t)(info->base + curdyn->d_un.d_ptr); break; case DT_FINI: info->fini = (ldfunc_t)(info->base + curdyn->d_un.d_ptr); break; case DT_NEEDED: /* d_needed = curdyn->d_un.d_val; */ break; case DT_RPATH: d_rpath = curdyn->d_un.d_val; break; case DT_PLTGOT: info->pltgot = (void *)(info->base + curdyn->d_un.d_ptr); break; case DT_PLTRELSZ: d_pltsize = curdyn->d_un.d_val; break; case DT_PLTREL: d_plttype = curdyn->d_un.d_val; break; case DT_BIND_NOW: _ldenv.ld_bind_now = 1; break; case DT_RELENT: case DT_RELAENT: d_relocent = curdyn->d_un.d_val; break; case DT_RELSZ: case DT_RELASZ: d_relocsz = curdyn->d_un.d_val; break; default: break; } } if (info->reloc) { info->nreloc = d_relocsz / d_relocent; } if (info->pltreloc) { /* bytes per element */ int bpe = d_plttype == DT_REL ? sizeof(Elf32_Rel) : sizeof(Elf32_Rela); info->npltreloc = d_pltsize / bpe; } /* Set up plt */ if (info->pltgot) { _ldpltgot_init(info); } /* create modules for dependencies */ for (curdyn = dyn; curdyn->d_tag != DT_NULL; curdyn++) { if (curdyn->d_tag == DT_NEEDED) { name = info->dynstr + curdyn->d_un.d_val; if (_ldchkname(name)) break; _ldaddname(name); *curmod = (module_t *)_ldalloc(sizeof(module_t)); (**curmod).name = name; _ldaddname((**curmod).name); if (d_rpath) { (**curmod).runpath = info->dynstr + d_rpath; } else { (**curmod).runpath = NULL; } (**curmod).next = NULL; (**curmod).first = _ldfirst; curmod = &((**curmod).next); } } _ldlast = curmod; return info; }