---
name: "i386_set_ldt"
section: "2"
platform: "macos"
package: "xnu"
version: "12377.121.6"
release: "macOS 26.5"
platforms: ["linux", "macos"]
url: "https://new.carta.tech/i386_get_ldt"
---

# i386\_set\_ldt(2)

manage i386 per-process Local Descriptor Table entries

Part of [i386\_get\_ldt(2)](/i386_get_ldt/2.md).

## NAME

**i386\_get\_ldt**, **i386\_set\_ldt** – manage i386 per-process Local Descriptor Table entries

## LIBRARY

Standard C Library (libc, -lc)

## SYNOPSIS

**#include \<architecture/i386/table.h\>**

**#include \<i386/user\_ldt.h\>**

*int*\

**i386\_get\_ldt**(*int start\_sel*, *union ldt\_entry \*descs*, *int num\_sels*);

*int*\

**i386\_set\_ldt**(*int start\_sel*, *union ldt\_entry \*descs*, *int num\_sels*);

## DESCRIPTION

The **i386\_get\_ldt**() system call will return the list of i386 descriptors that the process has in its LDT. The **i386\_set\_ldt**() system call will set a list of i386 descriptors for the current process in its LDT. Both routines accept a starting selector number *start\_sel*, an array of memory that will contain the descriptors to be set or returned *descs*, and the number of entries to set or return *num\_sels*.

The argument *descs* can be either code\_desc\_t, data\_desc\_t or call\_gate\_t and are defined in ⟨architecture/i386/desc.h⟩. These structures are defined by the architecture as disjoint bit-fields, so care must be taken in constructing them.

If *start\_sel* is *LDT\_AUTO\_ALLOC*, *num\_sels* is 1 and the descriptor pointed to by *descs* is legal, then **i386\_set\_ldt**() will allocate a descriptor and return its selector number.

If *num\_descs* is 1, *start\_sels* is valid, and *descs* is NULL, then **i386\_set\_ldt**() will free that descriptor (making it available to be reallocated again later).

If *num\_descs* is 0, *start\_sels* is 0 and *descs* is NULL then, as a special case, **i386\_set\_ldt**() will free all descriptors.

## NOTES

**i386\_set\_ldt**() and **i386\_get\_ldt**() may be used by 64-bit processes to create 32-bit (compatibility mode) code segments (in addition to the set of other segments already specified), that, together with additional infrastructure not provided by macOS, enables 32-bit code execution. Some platforms may reject segments with non-zero base addresses by returning -1 and setting errno to EINVAL.

## RETURN VALUES

Upon successful completion, **i386\_get\_ldt**() returns the number of descriptors currently in the LDT. The **i386\_set\_ldt**() system call returns the first selector set. In the case when a descriptor is allocated by the kernel, its number will be returned. Otherwise, a value of -1 is returned and the global variable *errno* is set to indicate the error.

## ERRORS

The **i386\_get\_ldt**() and **i386\_set\_ldt**() system calls will fail if:

- \[EINVAL\]

  An inappropriate value was used for *start\_sel* or *num\_sels*, or the platform does not support non-zero base addresses in custom descriptors and the descriptor base address passed to **i386\_set\_ldt**() is non-zero.

- \[EACCES\]

  The caller attempted to use a descriptor that would circumvent protection or cause a failure.

## SEE ALSO

i386 Microprocessor Programmer's Reference Manual, Intel

## WARNING

You can really hose your process using this.
