Exemplo n.º 1
0
void _ldaddname(const char *name) {
  modent_t *newent;

  newent = (modent_t *)_ldalloc(sizeof(*newent));
  newent->name = name;
  newent->next = names;
  names = newent;
}
Exemplo n.º 2
0
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;
}