| ... | @@ -1912,3 +1912,90 @@ pub const LoadCommandIterator = struct { | ... | @@ -1912,3 +1912,90 @@ pub const LoadCommandIterator = struct { |
| 1912 | return cmd; | 1912 | return cmd; |
| 1913 | } | 1913 | } |
| 1914 | }; | 1914 | }; |
| | 1915 | |
| | 1916 | pub const compact_unwind_encoding_t = u32; |
| | 1917 | |
| | 1918 | // Relocatable object files: __LD,__compact_unwind |
| | 1919 | |
| | 1920 | pub const compact_unwind_entry = extern struct { |
| | 1921 | rangeStart: u64, |
| | 1922 | rangeLength: u32, |
| | 1923 | compactUnwindEncoding: u32, |
| | 1924 | personalityFunction: u64, |
| | 1925 | lsda: u64, |
| | 1926 | }; |
| | 1927 | |
| | 1928 | // Final linked images: __TEXT,__unwind_info |
| | 1929 | // The __TEXT,__unwind_info section is laid out for an efficient two level lookup. |
| | 1930 | // The header of the section contains a coarse index that maps function address |
| | 1931 | // to the page (4096 byte block) containing the unwind info for that function. |
| | 1932 | |
| | 1933 | pub const UNWIND_SECTION_VERSION = 1; |
| | 1934 | pub const UNWIND_SECOND_LEVEL_REGULAR = 2; |
| | 1935 | pub const UNWIND_SECOND_LEVEL_COMPRESSED = 3; |
| | 1936 | |
| | 1937 | pub const unwind_info_section_header = extern struct { |
| | 1938 | /// UNWIND_SECTION_VERSION |
| | 1939 | version: u32 = UNWIND_SECTION_VERSION, |
| | 1940 | commonEncodingsArraySectionOffset: u32, |
| | 1941 | commonEncodingsArrayCount: u32, |
| | 1942 | personalityArraySectionOffset: u32, |
| | 1943 | personalityArrayCount: u32, |
| | 1944 | indexSectionOffset: u32, |
| | 1945 | indexCount: u32, |
| | 1946 | // compact_unwind_encoding_t[] |
| | 1947 | // uint32_t personalities[] |
| | 1948 | // unwind_info_section_header_index_entry[] |
| | 1949 | // unwind_info_section_header_lsda_index_entry[] |
| | 1950 | }; |
| | 1951 | |
| | 1952 | pub const unwind_info_section_header_index_entry = extern struct { |
| | 1953 | functionOffset: u32, |
| | 1954 | |
| | 1955 | /// section offset to start of regular or compress page |
| | 1956 | secondLevelPagesSectionOffset: u32, |
| | 1957 | |
| | 1958 | /// section offset to start of lsda_index array for this range |
| | 1959 | lsdaIndexArraySectionOffset: u32, |
| | 1960 | }; |
| | 1961 | |
| | 1962 | pub const unwind_info_section_header_lsda_index_entry = extern struct { |
| | 1963 | functionOffset: u32, |
| | 1964 | lsdaOffset: u32, |
| | 1965 | }; |
| | 1966 | |
| | 1967 | // There are two kinds of second level index pages: regular and compressed. |
| | 1968 | // A compressed page can hold up to 1021 entries, but it cannot be used if |
| | 1969 | // too many different encoding types are used. The regular page holds 511 |
| | 1970 | // entries. |
| | 1971 | |
| | 1972 | pub const unwind_info_regular_second_level_entry = extern struct { |
| | 1973 | functionOffset: u32, |
| | 1974 | encoding: compact_unwind_encoding_t, |
| | 1975 | }; |
| | 1976 | |
| | 1977 | pub const unwind_info_regular_second_level_page_header = extern struct { |
| | 1978 | /// UNWIND_SECOND_LEVEL_REGULAR |
| | 1979 | kind: u32 = UNWIND_SECOND_LEVEL_REGULAR, |
| | 1980 | |
| | 1981 | entryPageOffset: u16, |
| | 1982 | entryCount: u16, |
| | 1983 | // entry array |
| | 1984 | }; |
| | 1985 | |
| | 1986 | pub const unwind_info_compressed_second_level_page_header = extern struct { |
| | 1987 | /// UNWIND_SECOND_LEVEL_COMPRESSED |
| | 1988 | kind: u32 = UNWIND_SECOND_LEVEL_COMPRESSED, |
| | 1989 | |
| | 1990 | entryPageOffset: u16, |
| | 1991 | entryCount: u16, |
| | 1992 | encodingsPageOffset: u16, |
| | 1993 | encodingsCount: u16, |
| | 1994 | // 32bit entry array |
| | 1995 | // encodings array |
| | 1996 | }; |
| | 1997 | |
| | 1998 | pub const UnwindInfoCompressedEntry = packed struct(u32) { |
| | 1999 | funcOffset: u24, |
| | 2000 | encodingIndex: u8, |
| | 2001 | }; |