Beispiel #1
0
static
#endif
void*_dl_open(const char*filename,int flags) {
  int fd;
  char buf[PATH_MAX];
  const char*p=0;

  for (fd=0;filename[fd] && (p==0);++fd) if (filename[fd]=='/') p=filename;
  if (p) {
#ifdef __DIET_LD_SO__
    if ((fd=_dl_sys_open(p,O_RDONLY,0))<0) fd=-1;
#else
    fd=open(p,O_RDONLY);
#endif
  } else {
    p=buf;
    fd=_dl_search(buf,sizeof(buf)-1,filename);
  }
  if (fd==-1) {
    _dl_error_data=filename;
    _dl_error=1;
    return 0;
  }
  return _dl_load(filename,p,fd,flags);
}
Beispiel #2
0
static int _new_file(DL * dl, char const * pathname)
{
	Elf_Phdr * phdr;
	size_t i;
	ssize_t len;

	dl->fd = open(pathname, O_RDONLY);
	dl->path = strdup(pathname);
	if(dl->fd < 0 || dl->path == NULL)
		return _dl_error_set_errno(-1);
	/* read the ELF header */
	if(_file_read_ehdr(dl->fd, &dl->ehdr) != 0)
		return -1;
	/* read the program headers */
	if((phdr = _dl_load(dl, dl->ehdr.e_phoff, sizeof(*phdr)
					* dl->ehdr.e_phnum)) == NULL)
		return -1;
	for(i = 0; i < dl->ehdr.e_phnum; i++)
	{
		if(phdr[i].p_type != PT_LOAD)
			continue;
		if(phdr[i].p_filesz > phdr[i].p_memsz)
		{
			free(phdr);
			return _dl_error_set(DE_INVALID_FORMAT, -1);
		}
		if(_file_mmap(dl, &phdr[i]) == 0)
			continue;
		free(phdr);
		return -1;
	}
	free(phdr);
	/* read the section headers */
	if((len = dl->ehdr.e_shnum * sizeof(*dl->shdr)) < 0) /* XXX relevant? */
		return _dl_error_set(DE_INVALID_FORMAT, -1);
	if((dl->shdr = _dl_load(dl, dl->ehdr.e_shoff, len)) == NULL)
		return -1;
	if(_file_symbols(dl) != 0 || _file_relocations(dl) != 0)
		return -1;
	return 0;
}
Beispiel #3
0
static int _file_relocations(DL * dl)
{
	size_t i;
	Elf_Shdr * shdr;
	size_t j;
	Elf_Rel * rel = NULL;
	Elf_Rela rela;
	Elf_Sym * symtab;
	size_t symtab_cnt;
	char * strtab;
	size_t strtab_cnt;
	Elf_Sym * sym;

#ifdef DEBUG
	fprintf(stderr, "DEBUG: %s()\n", __func__);
#endif
	for(i = 0; i < dl->ehdr.e_shnum; i++)
	{
		shdr = &dl->shdr[i];
		if((shdr->sh_type != SHT_REL
					|| shdr->sh_entsize != sizeof(*rel))
				&& (shdr->sh_type != SHT_RELA
					|| shdr->sh_entsize != sizeof(rela)))
			continue;
		if((rel = _dl_load(dl, shdr->sh_offset, shdr->sh_size))
				== NULL)
			break;
		if(_dl_symtab(dl, shdr->sh_link, SHT_DYNSYM, &symtab,
					&symtab_cnt) != 0)
			break;
		if(_dl_strtab(dl, dl->shdr[shdr->sh_link].sh_link, &strtab,
					&strtab_cnt) != 0)
		{
			free(symtab);
			break;
		}
		for(j = 0; j < shdr->sh_size; j += shdr->sh_entsize)
		{
			rela.r_addend = 0;
			memcpy(&rela, (char *)rel + j, shdr->sh_entsize);
			if(ELF_R_SYM(rela.r_info) >= symtab_cnt)
				break; /* XXX */
			sym = &symtab[ELF_R_SYM(rela.r_info)];
			_file_relocations_arch(dl, &rela, strtab, strtab_cnt,
					sym);
		}
		free(strtab);
		free(symtab);
	}
	free(rel);
	return 0;
}
Beispiel #4
0
/* dl_strtab */
static int _dl_strtab(DL * dl, Elf_Word index, char ** strtab,
		size_t * strtab_cnt)
{
	Elf_Shdr * shdr;

	if(index >= dl->ehdr.e_shnum || dl->shdr[index].sh_type != SHT_STRTAB)
		return -_dl_error_set(DE_INVALID_FORMAT, 1);
	shdr = &dl->shdr[index];
	if((*strtab = _dl_load(dl, shdr->sh_offset, shdr->sh_size)) == NULL)
		return -1;
	if((*strtab)[shdr->sh_size - 1] != '\0')
	{
		free(*strtab);
		return -_dl_error_set(DE_INVALID_FORMAT, 1);
	}
	*strtab_cnt = shdr->sh_size;
	return 0;
}
Beispiel #5
0
/* dl_symtab */
static int _dl_symtab(DL * dl, Elf_Word index, Elf_Word type, Elf_Sym ** symtab,
		size_t * symtab_cnt)
{
	Elf_Shdr * shdr;

#ifdef DEBUG
	fprintf(stderr, "DEBUG: %s(%p, %u, %u, symtab, symtab_cnt)\n", __func__,
			dl, index, type);
#endif
	if(index >= dl->ehdr.e_shnum)
		return -_dl_error_set(DE_INVALID_FORMAT, 1);
	shdr = &dl->shdr[index];
	if(shdr->sh_type != type || shdr->sh_entsize != sizeof(**symtab))
		return -_dl_error_set(DE_INVALID_FORMAT, 1);
	if((*symtab = _dl_load(dl, shdr->sh_offset, shdr->sh_size)) == NULL)
		return -1;
	*symtab_cnt = shdr->sh_size / shdr->sh_entsize;
	return 0;
}