static int linux_read_ldt(struct lwp *l, const struct linux_sys_modify_ldt_args *uap, register_t *retval) { struct x86_get_ldt_args gl; int error; union descriptor *ldt_buf; size_t sz; /* * I've checked the linux code - this function is asymetric with * linux_write_ldt, and returns raw ldt entries. * NB, the code I saw zerod the spare parts of the user buffer. */ DPRINTF(("linux_read_ldt!")); sz = 8192 * sizeof(*ldt_buf); ldt_buf = kmem_zalloc(sz, KM_SLEEP); gl.start = 0; gl.desc = NULL; gl.num = SCARG(uap, bytecount) / sizeof(union descriptor); error = x86_get_ldt1(l, &gl, ldt_buf); /* NB gl.num might have changed */ if (error == 0) { *retval = gl.num * sizeof *ldt; error = copyout(ldt_buf, SCARG(uap, ptr), gl.num * sizeof *ldt_buf); } kmem_free(ldt_buf, sz); return error; }
static int linux_read_ldt(struct lwp *l, const struct linux_sys_modify_ldt_args *uap, register_t *retval) { struct x86_get_ldt_args gl; int error; int num_ldt; union descriptor *ldt_buf; /* * I've checked the linux code - this function is asymetric with * linux_write_ldt, and returns raw ldt entries. * NB, the code I saw zerod the spare parts of the user buffer. */ DPRINTF(("linux_read_ldt!")); num_ldt = x86_get_ldt_len(l); if (num_ldt <= 0) return EINVAL; gl.start = 0; gl.desc = NULL; gl.num = SCARG(uap, bytecount) / sizeof(union descriptor); if (gl.num > num_ldt) gl.num = num_ldt; ldt_buf = malloc(gl.num * sizeof *ldt, M_TEMP, M_WAITOK); error = x86_get_ldt1(l, &gl, ldt_buf); /* NB gl.num might have changed */ if (error == 0) { *retval = gl.num * sizeof *ldt; error = copyout(ldt_buf, SCARG(uap, ptr), gl.num * sizeof *ldt_buf); } free(ldt_buf, M_TEMP); return error; }