int get_ldso_metadata(signed int *binding_offset) { ldso_info_t info; int result; char filename[MAX_PATH_LEN+1]; find_interp_name(); debug_printf2("Requesting interpreter metadata for %s\n", interp_name); result = send_ldso_info_request(ldcsid, interp_name, filename); if (result == -1) return -1; read_ldso_metadata(filename, &info); *binding_offset = info.binding_offset; return 0; }
static int try_load_elf(elf_prog_t *prog, long bailout) { int err, has_interp; char i_filename[PATH_MAX]; /* so much easier */ elf_bin_t *bin=&prog->bin, *interp=&prog->interp; if ( (err = open_elf(prog->filename, bin)) < 0 ) return err; Elf32_Phdr phdr_bin_tmp[bin->hdr.e_phnum]; bin->phdr = phdr_bin_tmp; /* point to mmapped region later if any */ if (read_at(bin->fd, bin->hdr.e_phoff, bin->phdr, sizeof(*bin->phdr)*bin->hdr.e_phnum) != (long)sizeof(*bin->phdr)*bin->hdr.e_phnum) return -EIO; if ( (err = find_interp_name(bin, i_filename, PATH_MAX)) < 0 ) return err; has_interp = err; interp->phdr = NULL; interp->hdr.e_phnum = 0; if ( has_interp && (err = open_elf(i_filename, interp)) < 0) return err; Elf32_Phdr phdr_interp_tmp[interp->hdr.e_phnum]; if ( has_interp ) { interp->phdr = phdr_interp_tmp; /* point to mmapped region later */ if (read_at(interp->fd, interp->hdr.e_phoff, interp->phdr, sizeof(*interp->phdr)*interp->hdr.e_phnum) != (long)sizeof(*interp->phdr)*interp->hdr.e_phnum) return -EIO; } /* point of no return */ if (bailout) return 0; int stack_prot = get_stack_prot(bin); err = alloc_user_stack(prog, stack_prot); if ( mmap_binary(bin, 0) & PG_MASK ) raise(SIGKILL); if ( has_interp && (mmap_binary(interp, 1) & PG_MASK) ) raise(SIGKILL); /* set up stack */ bin->phdr = mapped_phdr(bin); if ( has_interp ) interp->phdr = mapped_phdr(interp); init_user_stack(prog, stack_prot); if (err & PG_MASK) raise(SIGKILL); if (has_interp) prog->entry = (void *)(interp->base + interp->hdr.e_entry); else prog->entry = (void *)(bin->base + bin->hdr.e_entry); return 0; }