1*ff1e46a1Swiz.\" $NetBSD: ctf.5,v 1.3 2015/09/29 06:33:01 wiz Exp $ 23745d9fbSchristos.\" 33745d9fbSchristos.\" This file and its contents are supplied under the terms of the 43745d9fbSchristos.\" Common Development and Distribution License ("CDDL"), version 1.0. 53745d9fbSchristos.\" You may only use this file in accordance with the terms of version 63745d9fbSchristos.\" 1.0 of the CDDL. 73745d9fbSchristos.\" 83745d9fbSchristos.\" A full copy of the text of the CDDL should have accompanied this 93745d9fbSchristos.\" source. A copy of the CDDL is also available via the Internet at 103745d9fbSchristos.\" http://www.illumos.org/license/CDDL. 113745d9fbSchristos.\" 123745d9fbSchristos.\" 133745d9fbSchristos.\" Copyright (c) 2014 Joyent, Inc. 143745d9fbSchristos.\" 15f3752eafSwiz.Dd September 26, 2014 163745d9fbSchristos.Dt CTF 5 173745d9fbSchristos.Os 183745d9fbSchristos.Sh NAME 193745d9fbSchristos.Nm ctf 203745d9fbSchristos.Nd Compact C Type Format 213745d9fbSchristos.Sh SYNOPSIS 223745d9fbSchristos.In sys/ctf.h 233745d9fbSchristos.Sh DESCRIPTION 243745d9fbSchristos.Nm 253745d9fbSchristosis designed to be a compact representation of the C programming 263745d9fbSchristoslanguage's type information focused on serving the needs of dynamic 273745d9fbSchristostracing, debuggers, and other in-situ and post-mortem introspection 283745d9fbSchristostools. 293745d9fbSchristos.Nm 303745d9fbSchristosdata is generally included in 313745d9fbSchristos.Sy ELF 323745d9fbSchristosobjects and is tagged as 333745d9fbSchristos.Sy SHT_PROGBITS 343745d9fbSchristosto ensure that the data is accessible in a running process and in subsequent 353745d9fbSchristoscore dumps, if generated. 363745d9fbSchristos.Lp 373745d9fbSchristosThe 383745d9fbSchristos.Nm 393745d9fbSchristosdata contained in each file has information about the layout and 403745d9fbSchristossizes of C types, including intrinsic types, enumerations, structures, 413745d9fbSchristostypedefs, and unions, that are used by the corresponding 423745d9fbSchristos.Sy ELF 43f3752eafSwizobject. 44f3752eafSwizThe 453745d9fbSchristos.Nm 463745d9fbSchristosdata may also include information about the types of global objects and 473745d9fbSchristosthe return type and arguments of functions in the symbol table. 483745d9fbSchristos.Lp 493745d9fbSchristosBecause a 503745d9fbSchristos.Nm 513745d9fbSchristosfile is often embedded inside a file, rather than being a standalone 523745d9fbSchristosfile itself, it may also be referred to as a 533745d9fbSchristos.Nm 543745d9fbSchristos.Sy container . 553745d9fbSchristos.Lp 563745d9fbSchristosOn illumos systems, 573745d9fbSchristos.Nm 58f3752eafSwizdata is consumed by multiple programs. 59*ff1e46a1SwizIt can be used by 60*ff1e46a1Swiz.\" the modular 61*ff1e46a1Swiz.\" debugger, 62*ff1e46a1Swiz.\" .Xr mdb 1 , 63*ff1e46a1Swiz.\" as well as by 64f3752eafSwiz.Xr dtrace 1 . 653745d9fbSchristosProgrammatic access to 663745d9fbSchristos.Nm 673745d9fbSchristosdata can be obtained through 68f3752eafSwiz.Xr libctf 3 . 693745d9fbSchristos.Lp 703745d9fbSchristosThe 713745d9fbSchristos.Nm 72f3752eafSwizfile format is broken down into seven different sections. 73f3752eafSwizThe first 743745d9fbSchristossection is the 753745d9fbSchristos.Sy preamble 763745d9fbSchristosand 773745d9fbSchristos.Sy header , 783745d9fbSchristoswhich describes the version of the 793745d9fbSchristos.Nm 803745d9fbSchristosfile, links it has to other 813745d9fbSchristos.Nm 82f3752eafSwizfiles, and the sizes of the other sections. 83f3752eafSwizThe next section is the 843745d9fbSchristos.Sy label 853745d9fbSchristossection, 863745d9fbSchristoswhich provides a way of identifying similar groups of 873745d9fbSchristos.Nm 88f3752eafSwizdata across multiple files. 89f3752eafSwizThis is followed by the 903745d9fbSchristos.Sy object 913745d9fbSchristosinformation section, which describes the type of global 92f3752eafSwizsymbols. 93f3752eafSwizThe subsequent section is the 943745d9fbSchristos.Sy function 953745d9fbSchristosinformation section, which describes the return 96f3752eafSwiztypes and arguments of functions. 97f3752eafSwizThe next section is the 983745d9fbSchristos.Sy type 993745d9fbSchristosinformation section, which describes 1003745d9fbSchristosthe format and layout of the C types themselves, and finally the last 1013745d9fbSchristossection is the 1023745d9fbSchristos.Sy string 1033745d9fbSchristossection, which contains the names of types, enumerations, members, and 1043745d9fbSchristoslabels. 1053745d9fbSchristos.Lp 1063745d9fbSchristosWhile strictly speaking, only the 1073745d9fbSchristos.Sy preamble 1083745d9fbSchristosand 1093745d9fbSchristos.Sy header 1103745d9fbSchristosare required, to be actually useful, both the type and string 1113745d9fbSchristossections are necessary. 1123745d9fbSchristos.Lp 1133745d9fbSchristosA 1143745d9fbSchristos.Nm 1153745d9fbSchristosfile may contain all of the type information that it requires, or it 1163745d9fbSchristosmay optionally refer to another 1173745d9fbSchristos.Nm 118f3752eafSwizfile which holds the remaining types. 119f3752eafSwizWhen a 1203745d9fbSchristos.Nm 1213745d9fbSchristosfile refers to another file, it is called the 1223745d9fbSchristos.Sy child 1233745d9fbSchristosand the file it refers to is called the 1243745d9fbSchristos.Sy parent . 125f3752eafSwizA given file may only refer to one parent. 126f3752eafSwizThis process is called 1273745d9fbSchristos.Em uniquification 1283745d9fbSchristosbecause it ensures each child only has type information that is 129f3752eafSwizunique to it. 130f3752eafSwizA common example of this is that most kernel modules in 1313745d9fbSchristosillumos are uniquified against the kernel module 1323745d9fbSchristos.Sy genunix 1333745d9fbSchristosand the type information that comes from the 1343745d9fbSchristos.Sy IP 135f3752eafSwizmodule. 136f3752eafSwizThis means that a module only has types that are unique to 1373745d9fbSchristositself and the most common types in the kernel are not duplicated. 1383745d9fbSchristos.Sh FILE FORMAT 1393745d9fbSchristosThis documents version 1403745d9fbSchristos.Em two 1413745d9fbSchristosof the 1423745d9fbSchristos.Nm 143f3752eafSwizfile format. 144f3752eafSwizAll applications and tools currently produce and operate on 1453745d9fbSchristosthis version. 1463745d9fbSchristos.Lp 1473745d9fbSchristosThe file format can be summarized with the following image, the 1483745d9fbSchristosfollowing sections will cover this in more detail. 1493745d9fbSchristos.Bd -literal 1503745d9fbSchristos 1513745d9fbSchristos +-------------+ 0t0 1523745d9fbSchristos+--------| Preamble | 1533745d9fbSchristos| +-------------+ 0t4 1543745d9fbSchristos|+-------| Header | 1553745d9fbSchristos|| +-------------+ 0t36 + cth_lbloff 1563745d9fbSchristos||+------| Labels | 1573745d9fbSchristos||| +-------------+ 0t36 + cth_objtoff 1583745d9fbSchristos|||+-----| Objects | 1593745d9fbSchristos|||| +-------------+ 0t36 + cth_funcoff 1603745d9fbSchristos||||+----| Functions | 1613745d9fbSchristos||||| +-------------+ 0t36 + cth_typeoff 1623745d9fbSchristos|||||+---| Types | 1633745d9fbSchristos|||||| +-------------+ 0t36 + cth_stroff 1643745d9fbSchristos||||||+--| Strings | 1653745d9fbSchristos||||||| +-------------+ 0t36 + cth_stroff + cth_strlen 1663745d9fbSchristos||||||| 1673745d9fbSchristos||||||| 1683745d9fbSchristos||||||| 1693745d9fbSchristos||||||| +-- magic - vers flags 1703745d9fbSchristos||||||| | | | | 1713745d9fbSchristos||||||| +------+------+------+------+ 1723745d9fbSchristos+---------| 0xcf | 0xf1 | 0x02 | 0x00 | 1733745d9fbSchristos |||||| +------+------+------+------+ 1743745d9fbSchristos |||||| 0 1 2 3 4 1753745d9fbSchristos |||||| 1763745d9fbSchristos |||||| + parent label + objects 1773745d9fbSchristos |||||| | + parent name | + functions + strings 1783745d9fbSchristos |||||| | | + label | | + types | + strlen 1793745d9fbSchristos |||||| | | | | | | | | 1803745d9fbSchristos |||||| +------+------+------+------+------+-------+-------+-------+ 1813745d9fbSchristos +--------| 0x00 | 0x00 | 0x00 | 0x08 | 0x36 | 0x110 | 0x5f4 | 0x611 | 1823745d9fbSchristos ||||| +------+------+------+------+------+-------+-------+-------+ 1833745d9fbSchristos ||||| 0x04 0x08 0x0c 0x10 0x14 0x18 0x1c 0x20 0x24 1843745d9fbSchristos ||||| 1853745d9fbSchristos ||||| + Label name 1863745d9fbSchristos ||||| | + Label type 1873745d9fbSchristos ||||| | | + Next label 1883745d9fbSchristos ||||| | | | 1893745d9fbSchristos ||||| +-------+------+-----+ 1903745d9fbSchristos +-----------| 0x01 | 0x42 | ... | 1913745d9fbSchristos |||| +-------+------+-----+ 1923745d9fbSchristos |||| cth_lbloff +0x4 +0x8 cth_objtoff 1933745d9fbSchristos |||| 1943745d9fbSchristos |||| 1953745d9fbSchristos |||| Symidx 0t15 0t43 0t44 1963745d9fbSchristos |||| +------+------+------+-----+ 1973745d9fbSchristos +----------| 0x00 | 0x42 | 0x36 | ... | 1983745d9fbSchristos ||| +------+------+------+-----+ 1993745d9fbSchristos ||| cth_objtoff +0x2 +0x4 +0x6 cth_funcoff 2003745d9fbSchristos ||| 2013745d9fbSchristos ||| + CTF_TYPE_INFO + CTF_TYPE_INFO 2023745d9fbSchristos ||| | + Return type | 2033745d9fbSchristos ||| | | + arg0 | 2043745d9fbSchristos ||| +--------+------+------+-----+ 2053745d9fbSchristos +---------| 0x2c10 | 0x08 | 0x0c | ... | 2063745d9fbSchristos || +--------+------+------+-----+ 2073745d9fbSchristos || cth_funcff +0x2 +0x4 +0x6 cth_typeoff 2083745d9fbSchristos || 2093745d9fbSchristos || + ctf_stype_t for type 1 2103745d9fbSchristos || | integer + integer encoding 2113745d9fbSchristos || | | + ctf_stype_t for type 2 2123745d9fbSchristos || | | | 2133745d9fbSchristos || +--------------------+-----------+-----+ 2143745d9fbSchristos +--------| 0x19 * 0xc01 * 0x0 | 0x1000000 | ... | 2153745d9fbSchristos | +--------------------+-----------+-----+ 2163745d9fbSchristos | cth_typeoff +0x08 +0x0c cth_stroff 2173745d9fbSchristos | 2183745d9fbSchristos | +--- str 0 2193745d9fbSchristos | | +--- str 1 + str 2 2203745d9fbSchristos | | | | 2213745d9fbSchristos | v v v 2223745d9fbSchristos | +----+---+---+---+----+---+---+---+---+---+----+ 2233745d9fbSchristos +---| \\0 | i | n | t | \\0 | f | o | o | _ | t | \\0 | 2243745d9fbSchristos +----+---+---+---+----+---+---+---+---+---+----+ 2253745d9fbSchristos 0 1 2 3 4 5 6 7 8 9 10 11 2263745d9fbSchristos.Ed 2273745d9fbSchristos.Lp 2283745d9fbSchristosEvery 2293745d9fbSchristos.Nm 2303745d9fbSchristosfile begins with a 2313745d9fbSchristos.Sy preamble , 2323745d9fbSchristosfollowed by a 2333745d9fbSchristos.Sy header . 2343745d9fbSchristosThe 2353745d9fbSchristos.Sy preamble 2363745d9fbSchristosis defined as follows: 2373745d9fbSchristos.Bd -literal 2383745d9fbSchristostypedef struct ctf_preamble { 2393745d9fbSchristos ushort_t ctp_magic; /* magic number (CTF_MAGIC) */ 2403745d9fbSchristos uchar_t ctp_version; /* data format version number (CTF_VERSION) */ 2413745d9fbSchristos uchar_t ctp_flags; /* flags (see below) */ 2423745d9fbSchristos} ctf_preamble_t; 2433745d9fbSchristos.Ed 2443745d9fbSchristos.Pp 2453745d9fbSchristosThe 2463745d9fbSchristos.Sy preamble 2473745d9fbSchristosis four bytes long and must be four byte aligned. 2483745d9fbSchristosThis 2493745d9fbSchristos.Sy preamble 2503745d9fbSchristosdefines the version of the 2513745d9fbSchristos.Nm 252f3752eafSwizfile which defines the format of the rest of the header. 253f3752eafSwizWhile the 2543745d9fbSchristosheader may change in subsequent versions, the preamble will not change 2553745d9fbSchristosacross versions, though the interpretation of its flags may change from 256f3752eafSwizversion to version. 257f3752eafSwizThe 2583745d9fbSchristos.Em ctp_magic 2593745d9fbSchristosmember defines the magic number for the 2603745d9fbSchristos.Nm 261f3752eafSwizfile format. 262f3752eafSwizThis must always be 2633745d9fbSchristos.Li 0xcff1 . 2643745d9fbSchristosIf another value is encountered, then the file should not be treated as 2653745d9fbSchristosa 2663745d9fbSchristos.Nm 267f3752eafSwizfile. 268f3752eafSwizThe 2693745d9fbSchristos.Em ctp_version 2703745d9fbSchristosmember defines the version of the 2713745d9fbSchristos.Nm 272f3752eafSwizfile. 273f3752eafSwizThe current version is 2743745d9fbSchristos.Li 2 . 275f3752eafSwizIt is possible to encounter an unsupported version. 276f3752eafSwizIn that case, 2773745d9fbSchristossoftware should not try to parse the format, as it may have changed. 2783745d9fbSchristosFinally, the 2793745d9fbSchristos.Em ctp_flags 2803745d9fbSchristosmember describes aspects of the file which modify its interpretation. 2813745d9fbSchristosThe following flags are currently defined: 2823745d9fbSchristos.Bd -literal 2833745d9fbSchristos#define CTF_F_COMPRESS 0x01 2843745d9fbSchristos.Ed 2853745d9fbSchristos.Pp 2863745d9fbSchristosThe flag 2873745d9fbSchristos.Sy CTF_F_COMPRESS 2883745d9fbSchristosindicates that the body of the 2893745d9fbSchristos.Nm 2903745d9fbSchristosfile, all the data following the 2913745d9fbSchristos.Sy header , 2923745d9fbSchristoshas been compressed through the 2933745d9fbSchristos.Sy zlib 2943745d9fbSchristoslibrary and its 2953745d9fbSchristos.Sy deflate 296f3752eafSwizalgorithm. 297f3752eafSwizIf this flag is not present, then the body has not been 298f3752eafSwizcompressed and no special action is needed to interpret it. 299f3752eafSwizAll offsets 3003745d9fbSchristosinto the data as described by 3013745d9fbSchristos.Sy header , 3023745d9fbSchristosalways refer to the 3033745d9fbSchristos.Sy uncompressed 3043745d9fbSchristosdata. 3053745d9fbSchristos.Lp 3063745d9fbSchristosIn version two of the 3073745d9fbSchristos.Nm 3083745d9fbSchristosfile format, the 3093745d9fbSchristos.Sy header 3103745d9fbSchristosdenotes whether whether or not this 3113745d9fbSchristos.Nm 3123745d9fbSchristosfile is the child of another 3133745d9fbSchristos.Nm 314f3752eafSwizfile and also indicates the size of the remaining sections. 315f3752eafSwizThe 3163745d9fbSchristosstructure for the 3173745d9fbSchristos.Sy header , 3183745d9fbSchristoslogically contains a copy of the 3193745d9fbSchristos.Sy preamble 3203745d9fbSchristosand the two have a combined size of 36 bytes. 3213745d9fbSchristos.Bd -literal 3223745d9fbSchristostypedef struct ctf_header { 3233745d9fbSchristos ctf_preamble_t cth_preamble; 3243745d9fbSchristos uint_t cth_parlabel; /* ref to name of parent lbl uniq'd against */ 3253745d9fbSchristos uint_t cth_parname; /* ref to basename of parent */ 3263745d9fbSchristos uint_t cth_lbloff; /* offset of label section */ 3273745d9fbSchristos uint_t cth_objtoff; /* offset of object section */ 3283745d9fbSchristos uint_t cth_funcoff; /* offset of function section */ 3293745d9fbSchristos uint_t cth_typeoff; /* offset of type section */ 3303745d9fbSchristos uint_t cth_stroff; /* offset of string section */ 3313745d9fbSchristos uint_t cth_strlen; /* length of string section in bytes */ 3323745d9fbSchristos} ctf_header_t; 3333745d9fbSchristos.Ed 3343745d9fbSchristos.Pp 3353745d9fbSchristosAfter the 3363745d9fbSchristos.Sy preamble , 3373745d9fbSchristosthe next two members 3383745d9fbSchristos.Em cth_parlablel 3393745d9fbSchristosand 3403745d9fbSchristos.Em cth_parname , 341f3752eafSwizare used to identify the parent. 342f3752eafSwizThe value of both members are offsets 3433745d9fbSchristosinto the 3443745d9fbSchristos.Sy string 345f3752eafSwizsection which point to the start of a null-terminated string. 346f3752eafSwizFor more 3473745d9fbSchristosinformation on the encoding of strings, see the subsection on 3483745d9fbSchristos.Sx String Identifiers . 3493745d9fbSchristosIf the value of either is zero, then there is no entry for that 350f3752eafSwizmember. 351f3752eafSwizIf the member 3523745d9fbSchristos.Em cth_parlabel 3533745d9fbSchristosis set, then the 3543745d9fbSchristos.Em ctf_parname 3553745d9fbSchristosmember must be set, otherwise it will not be possible to find the 356f3752eafSwizparent. 357f3752eafSwizIf 3583745d9fbSchristos.Em ctf_parname 3593745d9fbSchristosis set, it is not necessary to define 3603745d9fbSchristos.Em cth_parlabel , 361f3752eafSwizas the parent may not have a label. 362f3752eafSwizFor more information on labels 3633745d9fbSchristosand their interpretation, see 3643745d9fbSchristos.Sx The Label Section . 3653745d9fbSchristos.Lp 3663745d9fbSchristosThe remaining members (excepting 3673745d9fbSchristos.Em cth_strlen ) 368f3752eafSwizdescribe the beginning of the corresponding sections. 369f3752eafSwizThese offsets are 3703745d9fbSchristosrelative to the end of the 3713745d9fbSchristos.Sy header . 3723745d9fbSchristosTherefore, something with an offset of 0 is at an offset of thirty-six 3733745d9fbSchristosbytes relative to the start of the 3743745d9fbSchristos.Nm 375f3752eafSwizfile. 376f3752eafSwizThe difference between members 377f3752eafSwizindicates the size of the section itself. 378f3752eafSwizDifferent offsets have 379f3752eafSwizdifferent alignment requirements. 380f3752eafSwizThe start of the 3813745d9fbSchristos.Em cth_objotoff 3823745d9fbSchristosand 3833745d9fbSchristos.Em cth_funcoff 3843745d9fbSchristosmust be two byte aligned, while the sections 3853745d9fbSchristos.Em cth_lbloff 3863745d9fbSchristosand 3873745d9fbSchristos.Em cth_typeoff 388f3752eafSwizmust be four-byte aligned. 389f3752eafSwizThe section 3903745d9fbSchristos.Em cth_stroff 391f3752eafSwizhas no alignment requirements. 392f3752eafSwizTo calculate the size of a given section, 3933745d9fbSchristosexcepting the 3943745d9fbSchristos.Sy string 395f3752eafSwizsection, one should subtract the offset of the section from the following one. 396f3752eafSwizFor 3973745d9fbSchristosexample, the size of the 3983745d9fbSchristos.Sy types 3993745d9fbSchristossection can be calculated by subtracting 4003745d9fbSchristos.Em cth_stroff 4013745d9fbSchristosfrom 4023745d9fbSchristos.Em cth_typeoff . 4033745d9fbSchristos.Lp 4043745d9fbSchristosFinally, the member 4053745d9fbSchristos.Em cth_strlen 406f3752eafSwizdescribes the length of the string section itself. 407f3752eafSwizFrom it, you can also 4083745d9fbSchristoscalculate the size of the entire 4093745d9fbSchristos.Nm 4103745d9fbSchristosfile by adding together the size of the 4113745d9fbSchristos.Sy ctf_header_t , 4123745d9fbSchristosthe offset of the string section in 4133745d9fbSchristos.Em cth_stroff , 4143745d9fbSchristosand the size of the string section in 4153745d9fbSchristos.Em cth_srlen . 4163745d9fbSchristos.Ss Type Identifiers 4173745d9fbSchristosThrough the 4183745d9fbSchristos.Nm ctf 419f3752eafSwizdata, types are referred to by identifiers. 420f3752eafSwizA given 4213745d9fbSchristos.Nm 422f3752eafSwizfile supports up to 32767 (0x7fff) types. 423f3752eafSwizThe first valid type identifier is 0x1. 4243745d9fbSchristosWhen a given 4253745d9fbSchristos.Nm 4263745d9fbSchristosfile is a child, indicated by a non-zero entry for the 4273745d9fbSchristos.Sy header Ns 's 4283745d9fbSchristos.Em cth_parname , 4293745d9fbSchristosthen the first valid type identifier is 0x8000 and the last is 0xffff. 4303745d9fbSchristosIn this case, type identifiers 0x1 through 0x7fff are references to the 4313745d9fbSchristosparent. 4323745d9fbSchristos.Lp 4333745d9fbSchristosThe type identifier zero is a sentinel value used to indicate that there 4343745d9fbSchristosis no type information available or it is an unknown type. 4353745d9fbSchristos.Lp 4363745d9fbSchristosThroughout the file format, the identifier is stored in different sized 4373745d9fbSchristosvalues; however, the minimum size to represent a given identifier is a 4383745d9fbSchristos.Sy uint16_t . 4393745d9fbSchristosOther consumers of 4403745d9fbSchristos.Nm 4413745d9fbSchristosinformation may use larger or opaque identifiers. 4423745d9fbSchristos.Ss String Identifiers 4433745d9fbSchristosString identifiers are always encoded as four byte unsigned integers 444f3752eafSwizwhich are an offset into a string table. 445f3752eafSwizThe 4463745d9fbSchristos.Nm 4473745d9fbSchristosformat supports two different string tables which have an identifier of 448f3752eafSwizzero or one. 449f3752eafSwizThis identifier is stored in the high-order bit of the 450f3752eafSwizunsigned four byte offset. 451f3752eafSwizTherefore, the maximum supported offset into 4523745d9fbSchristosone of these tables is 0x7ffffffff. 4533745d9fbSchristos.Lp 4543745d9fbSchristosTable identifier zero, always refers to the 4553745d9fbSchristos.Sy string 456f3752eafSwizsection in the CTF file itself. 457f3752eafSwizString table identifier one refers to an 4583745d9fbSchristosexternal string table which is the ELF string table for the ELF symbol 4593745d9fbSchristostable associated with the 4603745d9fbSchristos.Nm 4613745d9fbSchristoscontainer. 4623745d9fbSchristos.Ss Type Encoding 4633745d9fbSchristosEvery 4643745d9fbSchristos.Nm 4653745d9fbSchristostype begins with metadata encoded into a 4663745d9fbSchristos.Sy uint16_t . 4673745d9fbSchristosThis encoded information tells us three different pieces of information: 4683745d9fbSchristos.Bl -bullet -offset indent -compact 4693745d9fbSchristos.It 4703745d9fbSchristosThe kind of the type 4713745d9fbSchristos.It 4723745d9fbSchristosWhether this type is a root type or not 4733745d9fbSchristos.It 4743745d9fbSchristosThe length of the variable data 4753745d9fbSchristos.El 4763745d9fbSchristos.Lp 4773745d9fbSchristosThe 16 bits that make up the encoding are broken down such that you have 4783745d9fbSchristosfive bits for the kind, one bit for indicating whether or not it is a 479f3752eafSwizroot type, and 10 bits for the variable length. 480f3752eafSwizThis is laid out as 4813745d9fbSchristosfollows: 4823745d9fbSchristos.Bd -literal -offset indent 4833745d9fbSchristos+--------------------+ 4843745d9fbSchristos| kind | root | vlen | 4853745d9fbSchristos+--------------------+ 4863745d9fbSchristos15 11 10 9 0 4873745d9fbSchristos.Ed 4883745d9fbSchristos.Lp 489f3752eafSwizThe current version of the file format defines 14 different kinds. 490f3752eafSwizThe 4913745d9fbSchristosinterpretation of these different kinds will be discussed in the section 4923745d9fbSchristos.Sx The Type Section . 4933745d9fbSchristosIf a kind is encountered that is not listed below, then it is not a valid 4943745d9fbSchristos.Nm 495f3752eafSwizfile. 496f3752eafSwizThe kinds are defined as follows: 4973745d9fbSchristos.Bd -literal -offset indent 4983745d9fbSchristos#define CTF_K_UNKNOWN 0 4993745d9fbSchristos#define CTF_K_INTEGER 1 5003745d9fbSchristos#define CTF_K_FLOAT 2 5013745d9fbSchristos#define CTF_K_POINTER 3 5023745d9fbSchristos#define CTF_K_ARRAY 4 5033745d9fbSchristos#define CTF_K_FUNCTION 5 5043745d9fbSchristos#define CTF_K_STRUCT 6 5053745d9fbSchristos#define CTF_K_UNION 7 5063745d9fbSchristos#define CTF_K_ENUM 8 5073745d9fbSchristos#define CTF_K_FORWARD 9 5083745d9fbSchristos#define CTF_K_TYPEDEF 10 5093745d9fbSchristos#define CTF_K_VOLATILE 11 5103745d9fbSchristos#define CTF_K_CONST 12 5113745d9fbSchristos#define CTF_K_RESTRICT 13 5123745d9fbSchristos.Ed 5133745d9fbSchristos.Lp 5143745d9fbSchristosPrograms directly reference many types; however, other types are referenced 515f3752eafSwizindirectly because they are part of some other structure. 516f3752eafSwizThese types that are 5173745d9fbSchristosreferenced directly and used are called 5183745d9fbSchristos.Sy root 519f3752eafSwiztypes. 520f3752eafSwizOther types may be used indirectly, for example, a program may reference 521f3752eafSwiza structure directly, but not one of its members which has a type. 522f3752eafSwizThat type is 5233745d9fbSchristosnot considered a 5243745d9fbSchristos.Sy root 525f3752eafSwiztype. 526f3752eafSwizIf a type is a 5273745d9fbSchristos.Sy root 5283745d9fbSchristostype, then it will have bit 10 set. 5293745d9fbSchristos.Lp 5303745d9fbSchristosThe variable length section is specific to each kind and is discussed in the 5313745d9fbSchristossection 5323745d9fbSchristos.Sx The Type Section . 5333745d9fbSchristos.Lp 5343745d9fbSchristosThe following macros are useful for constructing and deconstructing the encoded 5353745d9fbSchristostype information: 5363745d9fbSchristos.Bd -literal -offset indent 5373745d9fbSchristos 5383745d9fbSchristos#define CTF_MAX_VLEN 0x3ff 5393745d9fbSchristos#define CTF_INFO_KIND(info) (((info) & 0xf800) >> 11) 5403745d9fbSchristos#define CTF_INFO_ISROOT(info) (((info) & 0x0400) >> 10) 5413745d9fbSchristos#define CTF_INFO_VLEN(info) (((info) & CTF_MAX_VLEN)) 5423745d9fbSchristos 5433745d9fbSchristos#define CTF_TYPE_INFO(kind, isroot, vlen) \\ 5443745d9fbSchristos (((kind) << 11) | (((isroot) ? 1 : 0) << 10) | ((vlen) & CTF_MAX_VLEN)) 5453745d9fbSchristos.Ed 5463745d9fbSchristos.Ss The Label Section 5473745d9fbSchristosWhen consuming 5483745d9fbSchristos.Nm 5493745d9fbSchristosdata, it is often useful to know whether two different 5503745d9fbSchristos.Nm 551f3752eafSwizcontainers come from the same source base and version. 552f3752eafSwizFor example, when 5533745d9fbSchristosbuilding illumos, there are many kernel modules that are built against a 554f3752eafSwizsingle collection of source code. 555f3752eafSwizA label is encoded into the 5563745d9fbSchristos.Nm 557f3752eafSwizfiles that corresponds with the particular build. 558f3752eafSwizThis ensures that if 5593745d9fbSchristosfiles on the system were to become mixed up from multiple releases, that 5603745d9fbSchristosthey are not used together by tools, particularly when a child needs to 561f3752eafSwizrefer to a type in the parent. 562f3752eafSwizBecause they are linked used the type 5633745d9fbSchristosidentifiers, if the wrong parent is used then the wrong type will be 5643745d9fbSchristosencountered. 5653745d9fbSchristos.Lp 5663745d9fbSchristosEach label is encoded in the file format using the following eight byte 5673745d9fbSchristosstructure: 5683745d9fbSchristos.Bd -literal 5693745d9fbSchristostypedef struct ctf_lblent { 5703745d9fbSchristos uint_t ctl_label; /* ref to name of label */ 5713745d9fbSchristos uint_t ctl_typeidx; /* last type associated with this label */ 5723745d9fbSchristos} ctf_lblent_t; 5733745d9fbSchristos.Ed 5743745d9fbSchristos.Lp 5753745d9fbSchristosEach label has two different components, a name and a type identifier. 5763745d9fbSchristosThe name is encoded in the 5773745d9fbSchristos.Em ctl_label 5783745d9fbSchristosmember which is in the format defined in the section 5793745d9fbSchristos.Sx String Identifiers . 5803745d9fbSchristosGenerally, the names of all labels are found in the internal string 5813745d9fbSchristossection. 5823745d9fbSchristos.Lp 5833745d9fbSchristosThe type identifier encoded in the member 5843745d9fbSchristos.Em ctl_typeidx 5853745d9fbSchristosrefers to the last type identifier that a label refers to in the current 586f3752eafSwizfile. 587f3752eafSwizLabels only refer to types in the current file, if the 5883745d9fbSchristos.Nm 5893745d9fbSchristosfile is a child, then it will have the same label as its parent; 5903745d9fbSchristoshowever, its label will only refer to its types, not its parents. 5913745d9fbSchristos.Lp 5923745d9fbSchristosIt is also possible, though rather uncommon, for a 5933745d9fbSchristos.Nm 594f3752eafSwizfile to have multiple labels. 595f3752eafSwizLabels are placed one after another, every 596f3752eafSwizeight bytes. 597f3752eafSwizWhen multiple labels are present, types may only belong to 5983745d9fbSchristosa single label. 5993745d9fbSchristos.Ss The Object Section 6003745d9fbSchristosThe object section provides a mapping from ELF symbols of type 6013745d9fbSchristos.Sy STT_OBJECT 602f3752eafSwizin the symbol table to a type identifier. 603f3752eafSwizEvery entry in this section is 6043745d9fbSchristosa 6053745d9fbSchristos.Sy uint16_t 6063745d9fbSchristoswhich contains a type identifier as described in the section 6073745d9fbSchristos.Sx Type Identifiers . 6083745d9fbSchristosIf there is no information for an object, then the type identifier 0x0 6093745d9fbSchristosis stored for that entry. 6103745d9fbSchristos.Lp 6113745d9fbSchristosTo walk the object section, you need to have a corresponding 6123745d9fbSchristos.Sy symbol table 6133745d9fbSchristosin the ELF object that contains the 6143745d9fbSchristos.Nm 615f3752eafSwizdata. 616f3752eafSwizNot every object is included in this section. 617f3752eafSwizSpecifically, when 618f3752eafSwizwalking the symbol table. 619f3752eafSwizAn entry is skipped if it matches any of the 6203745d9fbSchristosfollowing conditions: 6213745d9fbSchristos.Lp 6223745d9fbSchristos.Bl -bullet -offset indent -compact 6233745d9fbSchristos.It 6243745d9fbSchristosThe symbol type is not 6253745d9fbSchristos.Sy STT_OBJECT 6263745d9fbSchristos.It 6273745d9fbSchristosThe symbol's section index is 6283745d9fbSchristos.Sy SHN_UNDEF 6293745d9fbSchristos.It 6303745d9fbSchristosThe symbol's name offset is zero 6313745d9fbSchristos.It 6323745d9fbSchristosThe symbol's section index is 6333745d9fbSchristos.Sy SHN_ABS 6343745d9fbSchristosand the value of the symbol is zero. 6353745d9fbSchristos.It 6363745d9fbSchristosThe symbol's name is 6373745d9fbSchristos.Li _START_ 6383745d9fbSchristosor 6393745d9fbSchristos.Li _END_ . 6403745d9fbSchristosThese are skipped because they are used for scoping local symbols in 6413745d9fbSchristosELF. 6423745d9fbSchristos.El 6433745d9fbSchristos.Lp 6443745d9fbSchristosThe following sample code shows an example of iterating the object 6453745d9fbSchristossection and skipping the correct symbols: 6463745d9fbSchristos.Bd -literal 6473745d9fbSchristos#include <gelf.h> 6483745d9fbSchristos#include <stdio.h> 6493745d9fbSchristos 6503745d9fbSchristos/* 6513745d9fbSchristos * Given the start of the object section in the CTF file, the number of symbols, 6523745d9fbSchristos * and the ELF Data sections for the symbol table and the string table, this 6533745d9fbSchristos * prints the type identifiers that correspond to objects. Note, a more robust 6543745d9fbSchristos * implementation should ensure that they don't walk beyond the end of the CTF 6553745d9fbSchristos * object section. 6563745d9fbSchristos */ 6573745d9fbSchristosstatic int 6583745d9fbSchristoswalk_symbols(uint16_t *objtoff, Elf_Data *symdata, Elf_Data *strdata, 6593745d9fbSchristos long nsyms) 6603745d9fbSchristos{ 6613745d9fbSchristos long i; 6623745d9fbSchristos uintptr_t strbase = strdata->d_buf; 6633745d9fbSchristos 6643745d9fbSchristos for (i = 1; i < nsyms; i++, objftoff++) { 6653745d9fbSchristos const char *name; 6663745d9fbSchristos GElf_Sym sym; 6673745d9fbSchristos 6683745d9fbSchristos if (gelf_getsym(symdata, i, &sym) == NULL) 6693745d9fbSchristos return (1); 6703745d9fbSchristos 6713745d9fbSchristos if (GELF_ST_TYPE(sym.st_info) != STT_OBJECT) 6723745d9fbSchristos continue; 6733745d9fbSchristos if (sym.st_shndx == SHN_UNDEF || sym.st_name == 0) 6743745d9fbSchristos continue; 6753745d9fbSchristos if (sym.st_shndx == SHN_ABS && sym.st_value == 0) 6763745d9fbSchristos continue; 6773745d9fbSchristos name = (const char *)(strbase + sym.st_name); 6783745d9fbSchristos if (strcmp(name, "_START_") == 0 || strcmp(name, "_END_") == 0) 6793745d9fbSchristos continue; 6803745d9fbSchristos 6813745d9fbSchristos (void) printf("Symbol %d has type %d\n", i, *objtoff); 6823745d9fbSchristos } 6833745d9fbSchristos 6843745d9fbSchristos return (0); 6853745d9fbSchristos} 6863745d9fbSchristos.Ed 6873745d9fbSchristos.Ss The Function Section 6883745d9fbSchristosThe function section of the 6893745d9fbSchristos.Nm 6903745d9fbSchristosfile encodes the types of both the function's arguments and the function's 691f3752eafSwizreturn type. 692f3752eafSwizSimilar to 6933745d9fbSchristos.Sx The Object Section , 6943745d9fbSchristosthe function section encodes information for all symbols of type 6953745d9fbSchristos.Sy STT_FUNCTION , 696f3752eafSwizexcepting those that fit specific criteria. 697f3752eafSwizUnlike with objects, because 6983745d9fbSchristosfunctions have a variable number of arguments, they start with a type encoding 6993745d9fbSchristosas defined in 7003745d9fbSchristos.Sx Type Encoding , 7013745d9fbSchristoswhich is the size of a 7023745d9fbSchristos.Sy uint16_t . 7033745d9fbSchristosFor functions which have no type information available, they are encoded as 7043745d9fbSchristos.Li CTF_TYPE_INFO(CTF_K_UNKNOWN, 0, 0) . 705f3752eafSwizFunctions with arguments are encoded differently. 706f3752eafSwizHere, the variable length is 707f3752eafSwizturned into the number of arguments in the function. 708f3752eafSwizIf a function is a 7093745d9fbSchristos.Sy varargs 710f3752eafSwiztype function, then the number of arguments is increased by one. 711f3752eafSwizFunctions with 7123745d9fbSchristostype information are encoded as: 7133745d9fbSchristos.Li CTF_TYPE_INFO(CTF_K_FUNCTION, 0, nargs) . 7143745d9fbSchristos.Lp 7153745d9fbSchristosFor functions that have no type information, nothing else is encoded, and the 716f3752eafSwiznext function is encoded. 717f3752eafSwizFor functions with type information, the next 7183745d9fbSchristos.Sy uint16_t 719f3752eafSwizis encoded with the type identifier of the return type of the function. 720f3752eafSwizIt is 7213745d9fbSchristosfollowed by each of the type identifiers of the arguments, if any exist, in the 722f3752eafSwizorder that they appear in the function. 723f3752eafSwizTherefore, argument 0 is the first type 724f3752eafSwizidentifier and so on. 725f3752eafSwizWhen a function has a final varargs argument, that is 7263745d9fbSchristosencoded with the type identifier of zero. 7273745d9fbSchristos.Lp 7283745d9fbSchristosLike 7293745d9fbSchristos.Sx The Object Section , 730f3752eafSwizthe function section is encoded in the order of the symbol table. 731f3752eafSwizIt has 732f3752eafSwizsimilar, but slightly different considerations from objects. 733f3752eafSwizWhile iterating the 7343745d9fbSchristossymbol table, if any of the following conditions are true, then the entry is 7353745d9fbSchristosskipped and no corresponding entry is written: 7363745d9fbSchristos.Lp 7373745d9fbSchristos.Bl -bullet -offset indent -compact 7383745d9fbSchristos.It 7393745d9fbSchristosThe symbol type is not 7403745d9fbSchristos.Sy STT_FUNCTION 7413745d9fbSchristos.It 7423745d9fbSchristosThe symbol's section index is 7433745d9fbSchristos.Sy SHN_UNDEF 7443745d9fbSchristos.It 7453745d9fbSchristosThe symbol's name offset is zero 7463745d9fbSchristos.It 7473745d9fbSchristosThe symbol's name is 7483745d9fbSchristos.Li _START_ 7493745d9fbSchristosor 7503745d9fbSchristos.Li _END_ . 7513745d9fbSchristosThese are skipped because they are used for scoping local symbols in 7523745d9fbSchristosELF. 7533745d9fbSchristos.El 7543745d9fbSchristos.Ss The Type Section 7553745d9fbSchristosThe type section is the heart of the 7563745d9fbSchristos.Nm 757f3752eafSwizdata. 758f3752eafSwizIt encodes all of the information about the types themselves. 759f3752eafSwizThe base of 7603745d9fbSchristosthe type information comes in two forms, a short form and a long form, each of 761f3752eafSwizwhich may be followed by a variable number of arguments. 762f3752eafSwizThe following 7633745d9fbSchristosdefinitions describe the short and long forms: 7643745d9fbSchristos.Bd -literal 7653745d9fbSchristos#define CTF_MAX_SIZE 0xfffe /* max size of a type in bytes */ 7663745d9fbSchristos#define CTF_LSIZE_SENT 0xffff /* sentinel for ctt_size */ 7673745d9fbSchristos#define CTF_MAX_LSIZE UINT64_MAX 7683745d9fbSchristos 7693745d9fbSchristostypedef struct ctf_stype { 7703745d9fbSchristos uint_t ctt_name; /* reference to name in string table */ 7713745d9fbSchristos ushort_t ctt_info; /* encoded kind, variant length */ 7723745d9fbSchristos union { 7733745d9fbSchristos ushort_t _size; /* size of entire type in bytes */ 7743745d9fbSchristos ushort_t _type; /* reference to another type */ 7753745d9fbSchristos } _u; 7763745d9fbSchristos} ctf_stype_t; 7773745d9fbSchristos 7783745d9fbSchristostypedef struct ctf_type { 7793745d9fbSchristos uint_t ctt_name; /* reference to name in string table */ 7803745d9fbSchristos ushort_t ctt_info; /* encoded kind, variant length */ 7813745d9fbSchristos union { 7823745d9fbSchristos ushort_t _size; /* always CTF_LSIZE_SENT */ 7833745d9fbSchristos ushort_t _type; /* do not use */ 7843745d9fbSchristos } _u; 7853745d9fbSchristos uint_t ctt_lsizehi; /* high 32 bits of type size in bytes */ 7863745d9fbSchristos uint_t ctt_lsizelo; /* low 32 bits of type size in bytes */ 7873745d9fbSchristos} ctf_type_t; 7883745d9fbSchristos 7893745d9fbSchristos#define ctt_size _u._size /* for fundamental types that have a size */ 7903745d9fbSchristos#define ctt_type _u._type /* for types that reference another type */ 7913745d9fbSchristos.Ed 7923745d9fbSchristos.Pp 7933745d9fbSchristosType sizes are stored in 7943745d9fbSchristos.Sy bytes . 7953745d9fbSchristosThe basic small form uses a 7963745d9fbSchristos.Sy ushort_t 797f3752eafSwizto store the number of bytes. 798f3752eafSwizIf the number of bytes in a structure would exceed 7993745d9fbSchristos0xfffe, then the alternate form, the 8003745d9fbSchristos.Sy ctf_type_t , 801f3752eafSwizis used instead. 802f3752eafSwizTo indicate that the larger form is being used, the member 8033745d9fbSchristos.Em ctt_size 8043745d9fbSchristosis set to value of 8053745d9fbSchristos.Sy CTF_LSIZE_SENT 806f3752eafSwiz(0xffff). 807f3752eafSwizIn general, when going through the type section, consumers use the 8083745d9fbSchristos.Sy ctf_type_t 8093745d9fbSchristosstructure, but pay attention to the value of the member 8103745d9fbSchristos.Em ctt_size 8113745d9fbSchristosto determine whether they should increment their scan by the size of the 8123745d9fbSchristos.Sy ctf_stype_t 8133745d9fbSchristosor 8143745d9fbSchristos.Sy ctf_type_t . 8153745d9fbSchristosNot all kinds of types use 8163745d9fbSchristos.Sy ctt_size . 8173745d9fbSchristosThose which do not, will always use the 8183745d9fbSchristos.Sy ctf_stype_t 819f3752eafSwizstructure. 820f3752eafSwizThe individual sections for each kind have more information. 8213745d9fbSchristos.Lp 822f3752eafSwizTypes are written out in order. 823f3752eafSwizTherefore the first entry encountered has a type 824f3752eafSwizid of 0x1, or 0x8000 if a child. 825f3752eafSwizThe member 8263745d9fbSchristos.Em ctt_name 8273745d9fbSchristosis encoded as described in the section 8283745d9fbSchristos.Sx String Identifiers . 829f3752eafSwizThe string that it points to is the name of the type. 830f3752eafSwizIf the identifier points 8313745d9fbSchristosto an empty string (one that consists solely of a null terminator) then the type 8323745d9fbSchristosdoes not have a name, this is common with anonymous structures and unions that 8333745d9fbSchristosonly have a typedef to name them, as well as, pointers and qualifiers. 8343745d9fbSchristos.Lp 8353745d9fbSchristosThe next member, the 8363745d9fbSchristos.Em ctt_info , 8373745d9fbSchristosis encoded as described in the section 8383745d9fbSchristos.Sx Type Encoding . 8393745d9fbSchristosThe types kind tells us how to interpret the remaining data in the 8403745d9fbSchristos.Sy ctf_type_t 841f3752eafSwizand any variable length data that may exist. 842f3752eafSwizThe rest of this section will be 8433745d9fbSchristosbroken down into the interpretation of the various kinds. 8443745d9fbSchristos.Ss Encoding of Integers 8453745d9fbSchristosIntegers, which are of type 8463745d9fbSchristos.Sy CTF_K_INTEGER , 847f3752eafSwizhave no variable length arguments. 848f3752eafSwizInstead, they are followed by a four byte 8493745d9fbSchristos.Sy uint_t 850f3752eafSwizwhich describes their encoding. 851f3752eafSwizAll integers must be encoded with a variable 852f3752eafSwizlength of zero. 853f3752eafSwizThe 8543745d9fbSchristos.Em ctt_size 855f3752eafSwizmember describes the length of the integer in bytes. 856f3752eafSwizIn general, integer sizes 8573745d9fbSchristoswill be rounded up to the closest power of two. 8583745d9fbSchristos.Lp 8593745d9fbSchristosThe integer encoding contains three different pieces of information: 8603745d9fbSchristos.Bl -bullet -offset indent -compact 8613745d9fbSchristos.It 8623745d9fbSchristosThe encoding of the integer 8633745d9fbSchristos.It 8643745d9fbSchristosThe offset in 8653745d9fbSchristos.Sy bits 8663745d9fbSchristosof the type 8673745d9fbSchristos.It 8683745d9fbSchristosThe size in 8693745d9fbSchristos.Sy bits 8703745d9fbSchristosof the type 8713745d9fbSchristos.El 8723745d9fbSchristos.Pp 8733745d9fbSchristosThis encoding can be expressed through the following macros: 8743745d9fbSchristos.Bd -literal -offset indent 8753745d9fbSchristos#define CTF_INT_ENCODING(data) (((data) & 0xff000000) >> 24) 8763745d9fbSchristos#define CTF_INT_OFFSET(data) (((data) & 0x00ff0000) >> 16) 8773745d9fbSchristos#define CTF_INT_BITS(data) (((data) & 0x0000ffff)) 8783745d9fbSchristos 8793745d9fbSchristos#define CTF_INT_DATA(encoding, offset, bits) \\ 8803745d9fbSchristos (((encoding) << 24) | ((offset) << 16) | (bits)) 8813745d9fbSchristos.Ed 8823745d9fbSchristos.Pp 8833745d9fbSchristosThe following flags are defined for the encoding at this time: 8843745d9fbSchristos.Bd -literal -offset indent 8853745d9fbSchristos#define CTF_INT_SIGNED 0x01 8863745d9fbSchristos#define CTF_INT_CHAR 0x02 8873745d9fbSchristos#define CTF_INT_BOOL 0x04 8883745d9fbSchristos#define CTF_INT_VARARGS 0x08 8893745d9fbSchristos.Ed 8903745d9fbSchristos.Lp 8913745d9fbSchristosBy default, an integer is considered to be unsigned, unless it has the 8923745d9fbSchristos.Sy CTF_INT_SIGNED 893f3752eafSwizflag set. 894f3752eafSwizIf the flag 8953745d9fbSchristos.Sy CTF_INT_CHAR 8963745d9fbSchristosis set, that indicates that the integer is of a type that stores character 8973745d9fbSchristosdata, for example the intrinsic C type 8983745d9fbSchristos.Sy char 8993745d9fbSchristoswould have the 9003745d9fbSchristos.Sy CTF_INT_CHAR 901f3752eafSwizflag set. 902f3752eafSwizIf the flag 9033745d9fbSchristos.Sy CTF_INT_BOOL 904f3752eafSwizis set, that indicates that the integer represents a boolean type. 905f3752eafSwizFor example, 9063745d9fbSchristosthe intrinsic C type 9073745d9fbSchristos.Sy _Bool 9083745d9fbSchristoswould have the 9093745d9fbSchristos.Sy CTF_INT_BOOL 910f3752eafSwizflag set. 911f3752eafSwizFinally, the flag 9123745d9fbSchristos.Sy CTF_INT_VARARGS 9133745d9fbSchristosindicates that the integer is used as part of a variable number of arguments. 9143745d9fbSchristosThis encoding is rather uncommon. 9153745d9fbSchristos.Ss Encoding of Floats 9163745d9fbSchristosFloats, which are of type 9173745d9fbSchristos.Sy CTF_K_FLOAT , 918f3752eafSwizare similar to their integer counterparts. 919f3752eafSwizThey have no variable length 9203745d9fbSchristosarguments and are followed by a four byte encoding which describes the kind of 921f3752eafSwizfloat that exists. 922f3752eafSwizThe 9233745d9fbSchristos.Em ctt_size 924f3752eafSwizmember is the size, in bytes, of the float. 925f3752eafSwizThe float encoding has three 9263745d9fbSchristosdifferent pieces of information inside of it: 9273745d9fbSchristos.Lp 9283745d9fbSchristos.Bl -bullet -offset indent -compact 9293745d9fbSchristos.It 9303745d9fbSchristosThe specific kind of float that exists 9313745d9fbSchristos.It 9323745d9fbSchristosThe offset in 9333745d9fbSchristos.Sy bits 9343745d9fbSchristosof the float 9353745d9fbSchristos.It 9363745d9fbSchristosThe size in 9373745d9fbSchristos.Sy bits 9383745d9fbSchristosof the float 9393745d9fbSchristos.El 9403745d9fbSchristos.Lp 9413745d9fbSchristosThis encoding can be expressed through the following macros: 9423745d9fbSchristos.Bd -literal -offset indent 9433745d9fbSchristos#define CTF_FP_ENCODING(data) (((data) & 0xff000000) >> 24) 9443745d9fbSchristos#define CTF_FP_OFFSET(data) (((data) & 0x00ff0000) >> 16) 9453745d9fbSchristos#define CTF_FP_BITS(data) (((data) & 0x0000ffff)) 9463745d9fbSchristos 9473745d9fbSchristos#define CTF_FP_DATA(encoding, offset, bits) \\ 9483745d9fbSchristos (((encoding) << 24) | ((offset) << 16) | (bits)) 9493745d9fbSchristos.Ed 9503745d9fbSchristos.Lp 9513745d9fbSchristosWhere as the encoding for integers was a series of flags, the encoding for 952f3752eafSwizfloats maps to a specific kind of float. 953f3752eafSwizIt is not a flag-based value. 954f3752eafSwizThe kinds of floats 955f3752eafSwizcorrespond to both their size, and the encoding. 956f3752eafSwizThis covers all of the basic C 957f3752eafSwizintrinsic floating point types. 958f3752eafSwizThe following are the different kinds of floats 9593745d9fbSchristosrepresented in the encoding: 9603745d9fbSchristos.Bd -literal -offset indent 9613745d9fbSchristos#define CTF_FP_SINGLE 1 /* IEEE 32-bit float encoding */ 9623745d9fbSchristos#define CTF_FP_DOUBLE 2 /* IEEE 64-bit float encoding */ 9633745d9fbSchristos#define CTF_FP_CPLX 3 /* Complex encoding */ 9643745d9fbSchristos#define CTF_FP_DCPLX 4 /* Double complex encoding */ 9653745d9fbSchristos#define CTF_FP_LDCPLX 5 /* Long double complex encoding */ 9663745d9fbSchristos#define CTF_FP_LDOUBLE 6 /* Long double encoding */ 9673745d9fbSchristos#define CTF_FP_INTRVL 7 /* Interval (2x32-bit) encoding */ 9683745d9fbSchristos#define CTF_FP_DINTRVL 8 /* Double interval (2x64-bit) encoding */ 9693745d9fbSchristos#define CTF_FP_LDINTRVL 9 /* Long double interval (2x128-bit) encoding */ 9703745d9fbSchristos#define CTF_FP_IMAGRY 10 /* Imaginary (32-bit) encoding */ 9713745d9fbSchristos#define CTF_FP_DIMAGRY 11 /* Long imaginary (64-bit) encoding */ 9723745d9fbSchristos#define CTF_FP_LDIMAGRY 12 /* Long double imaginary (128-bit) encoding */ 9733745d9fbSchristos.Ed 9743745d9fbSchristos.Ss Encoding of Arrays 9753745d9fbSchristosArrays, which are of type 9763745d9fbSchristos.Sy CTF_K_ARRAY , 977f3752eafSwizhave no variable length arguments. 978f3752eafSwizThey are followed by a structure which 9793745d9fbSchristosdescribes the number of elements in the array, the type identifier of the 980f3752eafSwizelements in the array, and the type identifier of the index of the array. 981f3752eafSwizWith 9823745d9fbSchristosarrays, the 9833745d9fbSchristos.Em ctt_size 984f3752eafSwizmember is set to zero. 985f3752eafSwizThe structure that follows an array is defined as: 9863745d9fbSchristos.Bd -literal 9873745d9fbSchristostypedef struct ctf_array { 9883745d9fbSchristos ushort_t cta_contents; /* reference to type of array contents */ 9893745d9fbSchristos ushort_t cta_index; /* reference to type of array index */ 9903745d9fbSchristos uint_t cta_nelems; /* number of elements */ 9913745d9fbSchristos} ctf_array_t; 9923745d9fbSchristos.Ed 9933745d9fbSchristos.Lp 9943745d9fbSchristosThe 9953745d9fbSchristos.Em cta_contents 9963745d9fbSchristosand 9973745d9fbSchristos.Em cta_index 9983745d9fbSchristosmembers of the 9993745d9fbSchristos.Sy ctf_array_t 10003745d9fbSchristosare type identifiers which are encoded as per the section 10013745d9fbSchristos.Sx Type Identifiers . 10023745d9fbSchristosThe member 10033745d9fbSchristos.Em cta_nelems 1004f3752eafSwizis a simple four byte unsigned count of the number of elements. 1005f3752eafSwizThis count may 10063745d9fbSchristosbe zero when encountering C99's flexible array members. 10073745d9fbSchristos.Ss Encoding of Functions 10083745d9fbSchristosFunction types, which are of type 10093745d9fbSchristos.Sy CTF_K_FUNCTION , 1010f3752eafSwizuse the variable length list to be the number of arguments in the function. 1011f3752eafSwizWhen 10123745d9fbSchristosthe function has a final member which is a varargs, then the argument count is 1013f3752eafSwizincremented by one to account for the variable argument. 1014f3752eafSwizHere, the 10153745d9fbSchristos.Em ctt_type 10163745d9fbSchristosmember is encoded with the type identifier of the return type of the function. 10173745d9fbSchristosNote that the 10183745d9fbSchristos.Em ctt_size 10193745d9fbSchristosmember is not used here. 10203745d9fbSchristos.Lp 10213745d9fbSchristosThe variable argument list contains the type identifiers for the arguments of 1022f3752eafSwizthe function, if any. 1023f3752eafSwizEach one is represented by a 10243745d9fbSchristos.Sy uint16_t 10253745d9fbSchristosand encoded according to the 10263745d9fbSchristos.Sx Type Identifiers 1027f3752eafSwizsection. 1028f3752eafSwizIf the function's last argument is of type varargs, then it is also 1029f3752eafSwizwritten out, but the type identifier is zero. 1030f3752eafSwizThis is included in the count of 10313745d9fbSchristosthe function's arguments. 10323745d9fbSchristos.Ss Encoding of Structures and Unions 10333745d9fbSchristosStructures and Unions, which are encoded with 10343745d9fbSchristos.Sy CTF_K_STRUCT 10353745d9fbSchristosand 10363745d9fbSchristos.Sy CTF_K_UNION 1037f3752eafSwizrespectively, are very similar constructs in C. 1038f3752eafSwizThe main difference 10393745d9fbSchristosbetween them is the fact that every member of a structure follows one another, 1040f3752eafSwizwhere as in a union, all members share the same memory. 1041f3752eafSwizThey are also very 10423745d9fbSchristossimilar in terms of their encoding in 10433745d9fbSchristos.Nm . 10443745d9fbSchristosThe variable length argument for structures and unions represents the number of 1045f3752eafSwizmembers that they have. 1046f3752eafSwizThe value of the member 10473745d9fbSchristos.Em ctt_size 1048f3752eafSwizis the size of the structure and union. 1049f3752eafSwizThere are two different structures which 1050f3752eafSwizare used to encode members in the variable list. 1051f3752eafSwizWhen the size of a structure or 10523745d9fbSchristosunion is greater than or equal to the large member threshold, 8192, then a 10533745d9fbSchristosdifferent structure is used to encode the member, all members are encoded using 1054f3752eafSwizthe same structure. 1055f3752eafSwizThe structure for members is as follows: 10563745d9fbSchristos.Bd -literal 10573745d9fbSchristostypedef struct ctf_member { 10583745d9fbSchristos uint_t ctm_name; /* reference to name in string table */ 10593745d9fbSchristos ushort_t ctm_type; /* reference to type of member */ 10603745d9fbSchristos ushort_t ctm_offset; /* offset of this member in bits */ 10613745d9fbSchristos} ctf_member_t; 10623745d9fbSchristos 10633745d9fbSchristostypedef struct ctf_lmember { 10643745d9fbSchristos uint_t ctlm_name; /* reference to name in string table */ 10653745d9fbSchristos ushort_t ctlm_type; /* reference to type of member */ 10663745d9fbSchristos ushort_t ctlm_pad; /* padding */ 10673745d9fbSchristos uint_t ctlm_offsethi; /* high 32 bits of member offset in bits */ 10683745d9fbSchristos uint_t ctlm_offsetlo; /* low 32 bits of member offset in bits */ 10693745d9fbSchristos} ctf_lmember_t; 10703745d9fbSchristos.Ed 10713745d9fbSchristos.Lp 10723745d9fbSchristosBoth the 10733745d9fbSchristos.Em ctm_name 10743745d9fbSchristosand 10753745d9fbSchristos.Em ctlm_name 1076f3752eafSwizrefer to the name of the member. 1077f3752eafSwizThe name is encoded as an offset into the 10783745d9fbSchristosstring table as described by the section 10793745d9fbSchristos.Sx String Identifiers . 10803745d9fbSchristosThe members 10813745d9fbSchristos.Sy ctm_type 10823745d9fbSchristosand 10833745d9fbSchristos.Sy ctlm_type 1084f3752eafSwizboth refer to the type of the member. 1085f3752eafSwizThey are encoded as per the section 10863745d9fbSchristos.Sx Type Identifiers . 10873745d9fbSchristos.Lp 10883745d9fbSchristosThe last piece of information that is present is the offset which describes the 1089f3752eafSwizoffset in memory that the member begins at. 1090f3752eafSwizFor unions, this value will always 1091f3752eafSwizbe zero because the start of unions in memory is always zero. 1092f3752eafSwizFor structures, 10933745d9fbSchristosthis is the offset in 10943745d9fbSchristos.Sy bits 1095f3752eafSwizthat the member begins at. 1096f3752eafSwizNote that a compiler may lay out a type with padding. 10973745d9fbSchristosThis means that the difference in offset between two consecutive members may be 1098f3752eafSwizlarger than the size of the member. 1099f3752eafSwizWhen the size of the overall structure is 11003745d9fbSchristosstrictly less than 8192 bytes, the normal structure, 11013745d9fbSchristos.Sy ctf_member_t , 11023745d9fbSchristosis used and the offset in bits is stored in the member 11033745d9fbSchristos.Em ctm_offset . 11043745d9fbSchristosHowever, when the size of the structure is greater than or equal to 8192 bytes, 1105f3752eafSwizthen the number of bits is split into two 32-bit quantities. 1106f3752eafSwizOne member, 11073745d9fbSchristos.Em ctlm_offsethi , 11083745d9fbSchristosrepresents the upper 32 bits of the offset, while the other member, 11093745d9fbSchristos.Em ctlm_offsetlo , 1110f3752eafSwizrepresents the lower 32 bits of the offset. 1111f3752eafSwizThese can be joined together to get 11123745d9fbSchristosa 64-bit sized offset in bits by shifting the member 11133745d9fbSchristos.Em ctlm_offsethi 11143745d9fbSchristosto the left by thirty two and then doing a binary or of 11153745d9fbSchristos.Em ctlm_offsetlo . 11163745d9fbSchristos.Ss Encoding of Enumerations 11173745d9fbSchristosEnumerations, noted by the type 11183745d9fbSchristos.Sy CTF_K_ENUM , 1119f3752eafSwizare similar to structures. 1120f3752eafSwizEnumerations use the variable list to note the number 1121f3752eafSwizof values that the enumeration contains, which we'll term enumerators. 1122f3752eafSwizIn C, an 11233745d9fbSchristosenumeration is always equivalent to the intrinsic type 11243745d9fbSchristos.Sy int , 11253745d9fbSchristosthus the value of the member 11263745d9fbSchristos.Em ctt_size 11273745d9fbSchristosis always the size of an integer which is determined based on the current model. 11283745d9fbSchristosFor illumos systems, this will always be 4, as an integer is always defined to 11293745d9fbSchristosbe 4 bytes large in both 11303745d9fbSchristos.Sy ILP32 11313745d9fbSchristosand 11323745d9fbSchristos.Sy LP64 , 11333745d9fbSchristosregardless of the architecture. 11343745d9fbSchristos.Lp 11353745d9fbSchristosThe enumerators encoded in an enumeration have the following structure in the 11363745d9fbSchristosvariable list: 11373745d9fbSchristos.Bd -literal 11383745d9fbSchristostypedef struct ctf_enum { 11393745d9fbSchristos uint_t cte_name; /* reference to name in string table */ 11403745d9fbSchristos int cte_value; /* value associated with this name */ 11413745d9fbSchristos} ctf_enum_t; 11423745d9fbSchristos.Ed 11433745d9fbSchristos.Pp 11443745d9fbSchristosThe member 11453745d9fbSchristos.Em cte_name 11463745d9fbSchristosrefers to the name of the enumerator's value, it is encoded according to the 11473745d9fbSchristosrules in the section 11483745d9fbSchristos.Sx String Identifiers . 11493745d9fbSchristosThe member 11503745d9fbSchristos.Em cte_value 11513745d9fbSchristoscontains the integer value of this enumerator. 11523745d9fbSchristos.Ss Encoding of Forward References 11533745d9fbSchristosForward references, types of kind 11543745d9fbSchristos.Sy CTF_K_FORWARD , 11553745d9fbSchristosin a 11563745d9fbSchristos.Nm 1157f3752eafSwizfile refer to types which may not have a definition at all, only a name. 1158f3752eafSwizIf 11593745d9fbSchristosthe 11603745d9fbSchristos.Nm 11613745d9fbSchristosfile is a child, then it may be that the forward is resolved to an 11623745d9fbSchristosactual type in the parent, otherwise the definition may be in another 11633745d9fbSchristos.Nm 1164f3752eafSwizcontainer or may not be known at all. 1165f3752eafSwizThe only member of the 11663745d9fbSchristos.Sy ctf_type_t 11673745d9fbSchristosthat matters for a forward declaration is the 11683745d9fbSchristos.Em ctt_name 11693745d9fbSchristoswhich points to the name of the forward reference in the string table as 1170f3752eafSwizdescribed earlier. 1171f3752eafSwizThere is no other information recorded for forward 11723745d9fbSchristosreferences. 11733745d9fbSchristos.Ss Encoding of Pointers, Typedefs, Volatile, Const, and Restrict 11743745d9fbSchristosPointers, typedefs, volatile, const, and restrict are all similar in 11753745d9fbSchristos.Nm . 1176f3752eafSwizThey all refer to another type. 1177f3752eafSwizIn the case of typedefs, they provide an 11783745d9fbSchristosalternate name, while volatile, const, and restrict change how the type is 1179f3752eafSwizinterpreted in the C programming language. 1180f3752eafSwizThis covers the 11813745d9fbSchristos.Nm 11823745d9fbSchristoskinds 11833745d9fbSchristos.Sy CTF_K_POINTER , 11843745d9fbSchristos.Sy CTF_K_TYPEDEF , 11853745d9fbSchristos.Sy CTF_K_VOLATILE , 11863745d9fbSchristos.Sy CTF_K_RESTRICT , 11873745d9fbSchristosand 11883745d9fbSchristos.Sy CTF_K_CONST . 11893745d9fbSchristos.Lp 11903745d9fbSchristosThese types have no variable list entries and use the member 11913745d9fbSchristos.Em ctt_type 11923745d9fbSchristosto refer to the base type that they modify. 11933745d9fbSchristos.Ss Encoding of Unknown Types 11943745d9fbSchristosTypes with the kind 11953745d9fbSchristos.Sy CTF_K_UNKNOWN 1196f3752eafSwizare used to indicate gaps in the type identifier space. 1197f3752eafSwizThese entries consume an 1198f3752eafSwizidentifier, but do not define anything. 1199f3752eafSwizNothing should refer to these gap 12003745d9fbSchristosidentifiers. 12013745d9fbSchristos.Ss Dependencies Between Types 1202f3752eafSwizC types can be imagined as a directed, cyclic, graph. 1203f3752eafSwizStructures and unions may 1204f3752eafSwizrefer to each other in a way that creates a cyclic dependency. 1205f3752eafSwizIn cases such as 1206f3752eafSwizthese, the entire type section must be read in and processed. 1207f3752eafSwizConsumers must 12083745d9fbSchristosnot assume that every type can be laid out in dependency order; they 12093745d9fbSchristoscannot. 12103745d9fbSchristos.Ss The String Section 12113745d9fbSchristosThe last section of the 12123745d9fbSchristos.Nm 12133745d9fbSchristosfile is the 12143745d9fbSchristos.Sy string 1215f3752eafSwizsection. 1216f3752eafSwizThis section encodes all of the strings that appear throughout 1217f3752eafSwizthe other sections. 1218f3752eafSwizIt is laid out as a series of characters followed by 1219f3752eafSwiza null terminator. 1220f3752eafSwizGenerally, all names are written out in ASCII, as 12213745d9fbSchristosmost C compilers do not allow and characters to appear in identifiers 1222f3752eafSwizoutside of a subset of ASCII. 1223f3752eafSwizHowever, any extended characters sets 12243745d9fbSchristosshould be written out as a series of UTF-8 bytes. 12253745d9fbSchristos.Lp 12263745d9fbSchristosThe first entry in the section, at offset zero, is a single null 1227f3752eafSwizterminator to reference the empty string. 1228f3752eafSwizFollowing that, each C string 1229f3752eafSwizshould be written out, including the null terminator. 1230f3752eafSwizOffsets that refer 12313745d9fbSchristosto something in this section should refer to the first byte which begins 1232f3752eafSwiza string. 1233f3752eafSwizBeyond the first byte in the section being the null 12343745d9fbSchristosterminator, the order of strings is unimportant. 12353745d9fbSchristos.Ss Data Encoding and ELF Considerations 12363745d9fbSchristos.Nm 12373745d9fbSchristosdata is generally included in ELF objects which specify information to 1238f3752eafSwizidentify the architecture and endianness of the file. 1239f3752eafSwizA 12403745d9fbSchristos.Nm 12413745d9fbSchristoscontainer inside such an object must match the endianness of the ELF 1242f3752eafSwizobject. 1243f3752eafSwizAside from the question of the endian encoding of data, there 1244f3752eafSwizshould be no other differences between architectures. 1245f3752eafSwizWhile many of the 12463745d9fbSchristostypes in this document refer to non-fixed size C integral types, they 12473745d9fbSchristosare equivalent in the models 12483745d9fbSchristos.Sy ILP32 12493745d9fbSchristosand 12503745d9fbSchristos.Sy LP64 . 12513745d9fbSchristosIf any other model is being used with 12523745d9fbSchristos.Nm 12533745d9fbSchristosdata that has different sizes, then it must not use the model's sizes for 12543745d9fbSchristosthose integral types and instead use the fixed size equivalents based on an 12553745d9fbSchristos.Sy ILP32 12563745d9fbSchristosenvironment. 12573745d9fbSchristos.Lp 12583745d9fbSchristosWhen placing a 12593745d9fbSchristos.Nm 12603745d9fbSchristoscontainer inside of an ELF object, there are certain conventions that are 12613745d9fbSchristosexpected for the purposes of tooling being able to find the 12623745d9fbSchristos.Nm 1263f3752eafSwizdata. 1264f3752eafSwizIn particular, a given ELF object should only contain a single 12653745d9fbSchristos.Nm 1266f3752eafSwizsection. 1267f3752eafSwizMultiple containers should be merged together into a single 12683745d9fbSchristosone. 12693745d9fbSchristos.Lp 12703745d9fbSchristosThe 12713745d9fbSchristos.Nm 1272f3752eafSwizfile should be included in its own ELF section. 1273f3752eafSwizThe section's name 12743745d9fbSchristosmust be 12753745d9fbSchristos.Ql .SUNW_ctf . 12763745d9fbSchristosThe type of the section must be 12773745d9fbSchristos.Sy SHT_PROGBITS . 12783745d9fbSchristosThe section should have a link set to the symbol table and its address 12793745d9fbSchristosalignment must be 4. 12803745d9fbSchristos.Sh SEE ALSO 12813745d9fbSchristos.Xr dtrace 1 , 12823745d9fbSchristos.Xr elf 3 , 12833745d9fbSchristos.Xr gelf 3 , 12843745d9fbSchristos.Xr a.out 5 , 12853745d9fbSchristos.Xr elf 5 1286