CHECK_RTIME(1ONBLD) illumos Build Tools CHECK_RTIME(1ONBLD) NNAAMMEE cchheecckk__rrttiimmee - check ELF runtime attributes SSYYNNOOPPSSIISS cchheecckk__rrttiimmee [--iimmoossvv] [--DD _d_e_p_f_i_l_e | --dd --ddeeppddiirr] [--EE _e_r_r_f_i_l_e] [--ee _e_x_f_i_l_e] [--ff _l_i_s_t_f_i_l_e] [--II _i_n_f_o_f_i_l_e] [--ww _o_u_t_d_i_r] _f_i_l_e | _d_i_r _._._. DDEESSCCRRIIPPTTIIOONN cchheecckk__rrttiimmee attempts to check a number of ELF runtime attributes for consistency with common build rules. These checks involve running ldd(1) and elfdump(1) against a family of dynamic objects. A dynamic object can be defined explicitly as a _f_i_l_e or multiple dynamic objects can be located under the directory _d_i_r. cchheecckk__rrttiimmee is typically called from nightly(1ONBLD) when the --rr option is in effect. In this case the dynamic objects under the associated _p_r_o_t_o _a_r_e_a ($ROOT) are checked. cchheecckk__rrttiimmee can also be run standalone against any set of dynamic objects. cchheecckk__rrttiimmee uses ldd(1) to verify dependencies. This implies that by default any object inspected will bind to its dependencies as they are found in the _u_n_d_e_r_l_y_i_n_g _s_y_s_t_e_m. Use of the --DD, --dd option, or the existence of the environment variables $CODEMGR_WS or $ROOT instruct cchheecckk__rrttiimmee to establish an alternative dependency mapping using runtime configuration files generated with crle(1). cchheecckk__rrttiimmee uses ldd(1) to completely relocate any dynamic object and thus detect missing dependencies, unsatisfied symbol relocations, unused and unreferenced dependencies. These checks are carried out for the following reasons: ++oo An object that cannot find its dependencies may fail to load at runtime. This error condition often goes unnoticed because the existing use of the object is as a dependency itself, and the objects' dependencies are already satisfied by the caller. However, if the object itself is unable to satisfy its dependencies, its use in new environments may be compromised. A missing or erroneous _r_u_n_p_a_t_h is the typical reason why an object can not locate its dependencies. Use of the link-editors --zzddeeffss option when building a shared object ensures required dependencies are established. This flag is inherited from $(DYNFLAGS) in _l_i_b_/_M_a_k_e_f_i_l_e_._l_i_b. Missing dependencies are displayed as: foo: bar.so.1 => (file not found) ++oo Unsatisfied symbol relocations indicate that some thread of execution through the object will fail when it is unable to locate a referenced symbol. A missing, or mismatched version of a dependency is the typical reason for unsatisfied symbol relocations (see missing dependency discussion above). Unsatisfied symbol relocations are displayed as: foo: symbol not found: bar Note: Shared objects can make reference to symbol definitions that are expected to be defined by the caller. To indicate that such symbols are not undefined in the usual sense, you must specify these symbols in a _m_a_p_f_i_l_e, using the _E_X_T_E_R_N or _P_A_R_E_N_T symbol attributes. Without these symbol attributes, ldd(1) is unable to determine the symbols special nature, and cchheecckk__rrttiimmee will report these symbols as undefined. ++oo Unused dependencies are wasteful at runtime, as they take time to load and relocate, but will not be used by the calling object. They also result in unnecessary processing at link-edit time. Dependency lists (typically defined via $(LDLIBS)) that have been copy and pasted between _M_a_k_e_f_i_l_e_s without verifying their need, are a typicalreason why unused dependencies exist. Unused dependencies are displayed as: foo: unused object=bar.so.1 ++oo Unreferenced dependencies are also wasteful at runtime, although not to the extent of unused dependencies. They also result in unnecessary processing at link-edit time. Unreferenced dependency removal guards against a dependency becoming unused when combined with different objects, or as the other object dependencies evolve. Unreferenced dependencies are displayed as: foo: unreferenced object=bar.so.1; \ unused dependency of libfoo.so.1 \ See also the section _E_N_V_I_R_O_N_M_E_N_T _V_A_R_I_A_B_L_E_S. ++oo Unused search paths are wasteful at runtime. Unused search paths are displayed as: foo: unused search path=/usr/foo/lib \ (RUNPATH/RPATH from file libfoo.so.1) \ cchheecckk__rrttiimmee uses elfdump(1) to look for a concatenated relocation section in shared objects, the existence of text relocations, whether debugging or symbol table information exists, whether applications have a non- executable stack defined, duplicate entries in the symbol sorting sections, and for direct bindings. These checks are carried out for the following reasons: ++oo A concatenated relocation section (_._S_U_N_W___r_e_l_o_c) provides optimal symbol table access at runtime, and thus reduces the overhead of relocating the shared object. In past releases, the link-edit of a dynamic object with the --zz _c_o_m_b_r_e_l_o_c option was required to generate a combined relocation section. However, with the integration of 6642769, this section combination is a default behavior of the link- editor. In past releases, not inheriting $(DYNFLAGS) from _l_i_b_/_M_a_k_e_f_i_l_e_._l_i_b was the typical reason for not having a concatenated relocation section. The misguided use of the --zz _n_o_c_o_m_b_r_e_l_o_c option will also prevent the creation of a concatenated relocation section. A missing concatenated relocation section is displayed as: foo: .SUNW_reloc section missing ++oo Text relocations result in impure text segments. As text segments are typically read-only, they can be shared between numerous processes. If they must be updated as part of the relocation then the updated pages become unsharable and swap space must be allocated to back these pages. These events consume unnecessary system resources and reduce overall system performance. Not inheriting the $(PICS) rules from _l_i_b_/_M_a_k_e_f_i_l_e_._l_i_b is the typical reason for having non-pic code in shared objects. Text relocations are displayed as: foo: TEXTREL .dynamic tag ++oo Debugging information is unnecessary in released objects. Although extensive when compiled --gg, small quantities of debugging information are stored in _._s_t_a_b_s sections under normal compilations. This debugging information is geared towards aiding debuggers locate relocatable objects associated with the dynamic objects being debugged. As relocatable objects aren't made available as part of a software release this information has no use. Not inheriting the correct $(LDFLAGS) from _c_m_d_/_M_a_k_e_f_i_l_e_._c_m_d (which asserts --ss) or $(POST_PROCESS_SO) (which asserts ssttrriipp --xx) are typical reasons for not removing debugging information. Note, removal of debugging information is only enabled for release builds. The existence of debugging information is displayed as: foo: debugging sections should be deleted \ ++oo All objects should retain their full _._s_y_m_t_a_b symbol table. Although this consumes disk space, it provides for more extensive stack tracing when debugging user applications. Hard coding a --ss flag with $(LDFLAGS) or $(DYNFLAGS) is the typical reason for symbol tables being removed. Objects that do not contain a symbol table are displayed as: foo.so.1: symbol table should not be stripped \ ++oo Applications should have a non-executable stack defined to make them less vulnerable to buffer overflow attacks. Not inheriting the $(LDFLAGS) macro in _c_m_d_/_M_a_k_e_f_i_l_e_._c_m_d is the typical reason for not having a non-executable stack definition. Applications without this definition are displayed as: foo: application requires non-executable stack \ ++oo x86 applications should have a non-executable data segment defined to make them less vulnerable to buffer overflow attacks. Not inheriting the $(LDFLAGS) macro in _c_m_d_/_M_a_k_e_f_i_l_e_._c_m_d is the typical reason for not having a non-executable data definition. Applications without this definition are displayed as: foo: application requires non-executable data \ ++oo Solaris ELF files contain symbol sort sections used by DTrace to map addresses in memory to the related function or variable symbols. There are two such sections, _._S_U_N_W___d_y_n_s_y_m_s_o_r_t for regular symbols, and _._S_U_N_W___d_y_n_t_l_s_s_o_r_t for thread-local symbols. To ensure that the best names are shown for each such address, and that the same name is given across Solaris releases, cchheecckk__rrttiimmee enforces the rule that only one symbol can appear in the sort sections for any given address. There are two common ways in which multiple symbols or a given address occur in the ON distribution. The first is from code written in assembly language. The second is as a result of using ##pprraaggmmaa wweeaakk in C to create weak symbols. The best solution to this situation is to modify the code to avoid symbol aliasing. Alternatively, the _N_O_D_Y_N_S_O_R_T mapfile attribute can be used to eliminate the unwanted symbol. Duplicate entries in a symbol sort section are displayed in one of the following ways, depending on whether the section is for regular or thread-local symbols: foo: .SUNW_dynsymsort: duplicate ADDRESS: sym1, sym2 foo: .SUNW_dyntlssort: duplicate OFFSET: sym1, sym2 ++oo illumos dynamic ELF objects are expected to employ direct bindings whenever feasible. This runtime binding technique helps to avoid accidental interposition problems, and provides a more optimal runtime symbol search model. Not inheriting the correct $(LDFLAGS) from _c_m_d_/_M_a_k_e_f_i_l_e_._c_m_d, or the correct $(DYNFLAGS) from _l_i_b_/_M_a_k_e_f_i_l_e_._l_i_b, are the typical reasons for not enabling direct bindings. Dynamic objects that do not contain direct binding information are displayed as: foo: object has no direct bindings \ cchheecckk__rrttiimmee also uses elfdump(1) to display useful dynamic entry information under the ----ii option. This doesn't necessarily indicate an error condition, but provides information that is often useful for gatekeepers to track changes in a release. Presently the information listed is: ++oo Runpaths are printed for any dynamic object. This is a historic sanity check to insure compiler supplied runpaths (typically from CCCC) are not recorded in any objects. Runpaths are displayed as: foo: RPATH=/usr/bar/lib ++oo Needed dependencies are printed for any dynamic object. In the freeware world this often helps the introducer of a new shared object discover that an existing binary has become its consumer, and thus that binaries package dependencies may require updating. Dependencies are printed as: foo: NEEDED=bar.so.1 ++oo Dependencies may be marked as forbidden (see _E_X_C_E_P_T_I_O_N _F_I_L_E _F_O_R_M_A_T) this allows the build to warn should people use them accidentally. Forbidden dependencies are printed as: foo: NEEDED=bar.so.1 cchheecckk__rrttiimmee uses mcs(1) to inspect an object's _._c_o_m_m_e_n_t section. During development, this section contains numerous file identifiers marked with the tag "@(#)". For release builds these sections are deleted and rewritten under control of the $(POST_PROCESS) macro to produce a common release identifier. This identifier typically consists of three lines including a single comment starting with the string "@(#) SunOS". If this common identifier isn't found the following diagnostic is generated: foo: non-conforming mcs(1) comment cchheecckk__rrttiimmee uses pvs(1) to display version definitions under the --vv option. Each symbol defined by the object is shown along with the version it belongs to. Changes to the symbols defined by an object, or the versions they belong to, do not necessarily indicate an error condition, but provides information that is often useful for gatekeepers to track changes in a release. OOPPTTIIOONNSS The following options are supported: --DD _d_e_p_f_i_l_e Use _d_e_p_f_i_l_e to generate an alternative dependency mapping. _d_e_p_f_i_l_e must be created by ffiinndd__eellff --rr. The --DD and --dd options are mutually exclusive. --dd _d_e_p_f_i_l_e Use _d_e_p_d_i_r to generate an alternative dependency mapping. find_elf(1ONBLD) is used to locate the ELF sharable objects for which alternative mappings are required. The --DD and --dd options are mutually exclusive. --EE _e_r_r_f_i_l_e Direct error messages for the analyzed objects to _e_r_r_f_i_l_e instead of stdout. --ee _e_x_f_i_l_e An exception file is used to exclude objects from the usual rules. See _E_X_C_E_P_T_I_O_N _F_I_L_E _F_O_R_M_A_T. --ff _l_i_s_t_f_i_l_e Normally, iinntteerrffaaccee__cchheecckk runs ffiinndd__eellff to locate the ELF objects to analyze. The --ff option can be used to instead provide a file containing the list of objects to analyze, in the format produced by ffiinndd__eellff --rr. --II _i_n_f_o_f_i_l_e Direct informational messages ( --ii, and --vv options) for the analyzed objects to _i_n_f_o_f_i_l_e instead of stdout. --ii Provide dynamic entry information. Presently only dependencies and runpaths are printed. --mm Enable mcs(1) checking. --oo Produce a one-line output for each condition discovered, prefixed by the objects name. This output style is more terse, but is more appropriate for sorting and diffing with previous build results. --ss Determine whether _._s_t_a_b_s sections exist. --vv Provide version definition information. Each symbol defined by the object is printed along with the version it is assigned to. --ww _o_u_t_d_i_r Interpret the paths of all input and output files relative to _o_u_t_d_i_r. EEXXCCEEPPTTIIOONN FFIILLEE FFOORRMMAATT Exceptions to the rules enforced by cchheecckk__rrttiimmee are specified using an exception file. The ----ee option is used to specify an explicit exception file. Otherwise, if used in an activated workspace, the default exception file is _$_C_O_D_E_M_G_R___W_S_/_e_x_c_e_p_t_i_o_n___l_i_s_t_/_c_h_e_c_k___r_t_i_m_e if that file exists. If not used in an activated workspace, or if _$_C_O_D_E_M_G_R___W_S_/_e_x_c_e_p_t_i_o_n___l_i_s_t_/_c_h_e_c_k___r_t_i_m_e does not exist, cchheecckk__rrttiimmee will use _/_o_p_t_/_o_n_b_l_d_/_e_t_c_/_e_x_c_e_p_t_i_o_n___l_i_s_t_/_c_h_e_c_k___r_t_i_m_e as a fallback default exception file. To run cchheecckk__rrttiimmee without applying exceptions, specify --ee with a value of _/_d_e_v_/_n_u_l_l. A `#' character at the beginning of a line, or at any point in a line when preceded by whitespace, introduces a comment. Empty lines, and lines containing only comments, are ignored by cchheecckk__rrttiimmee. Exceptions are specified as space separated keyword, and perl(1) regular expression: keyword perl-regex Since whitespace is used as a separator, the regular expression cannot itself contain whitespace. Use of the `' character class to represent whitespace within the regular expression is recommended. Before the perl regular expression is used, constructs of the form _M_A_C_H_(_d_i_r_) are expanded into a regular expression that matches the directory given, as well as any 64-bit architecture subdirectory that might be present (i.e. amd64, sparcv9). For instance, _M_A_C_H_(_l_i_b_) will match any of the following: _l_i_b _l_i_b_/_a_m_d_6_4 _l_i_b_/_s_p_a_r_c_v_9 The exceptions understood by cchheecckk__rrttiimmee are: EXEC_DATA Executables that are not required to have non-executable writable data segments EXEC_STACK Executables that are not required to have a non-executable stack NOCRLEALT Objects that should be skipped when building the alternative dependency mapping via the --dd option. NODIRECT Directories and files that are allowed to have no direct bound symbols. NOSYMSORT Files for which we skip checking of duplicate addresses in the symbol sort sections. OLDDEP Objects that used to contain system functionality that has since migrated to libc. We preserve these libraries as pure filters for backward compatibility but nothing needs to link to them. SKIP Directories and/or individual objects to skip. Note that SKIP should be a last resort, used only when one of the other exceptions will not suffice. STAB Objects that are allowed to contain debugging information (stabs). TEXTREL Objects for which we allow relocations to the text segment. BUNDEF_OBJ Objects that are allowed to be unreferenced. UNDEF_REF Objects that are allowed undefined references. UNUSED_DEPS Objects that are allowed to have unused dependencies. BUNUSED_OBJ Objects that are always allowed to be unused dependencies. UNUSED_RPATH Objects that are allowed to have unused runpath directories. FORBIDDEN Specifies that dependencies on a given object are forbidden. FORBIDDEN_DEP Specifies that a given object is permitted a forbidden dependency. AALLTTEERRNNAATTIIVVEE DDEEPPEENNDDEENNCCYY MMAAPPPPIINNGG cchheecckk__rrttiimmee was primarily designed to process a nightly builds $ROOT hierarchy. It is often the case that objects within this hierarchy must bind to dependencies within the same hierarchy to satisfy their requirements. To achieve this, cchheecckk__rrttiimmee uses the shared objects specified with the --DD or --dd options. If neither option is specified, and the $CODEMGR_WS and $ROOT environment variables are defined, the proto area for the workspace is used. The objects found are used to create runtime configuration files via crle(1), that establish the new shared objects as alternatives to their underlying system location. cchheecckk__rrttiimmee passes these configuration files as LD_CONFIG environment variable settings to ldd(1) using its ----ee option. The effect of these configuration files is that the execution of an object under ldd(1) will bind to the dependencies defined as alternatives. Simply put, an object inspected in the _p_r_o_t_o area will bind to its dependencies found in the _p_r_o_t_o area. Dependencies that have no alternative mapping will continue to bind to the underlying system. EENNVVIIRROONNMMEENNTT VVAARRIIAABBLLEESS When the --DD or --dd option isn't in use, cchheecckk__rrttiimmee uses the following environment variables to establish an alternative dependency mapping: CODEMGR_WS The root of your workspace, which is the directory containing _._g_i_t. Existence of this environment variable indicates that $ROOT should be investigated. ROOT Root of the _p_r_o_t_o area of your workspace. Any shared objects under this directory will be used to establish an alternative dependency mapping. If ldd(1) supports the --UU option, it will be used to determine any unreferenced dependencies. Otherwise ldd(1) uses the older --uu option which only detects unused references. If the following environment variable exists, and indicates an earlier release than 55..1100 then ldd(1) also falls back to using the --uu option. RELEASE The release version number of the environment being built. EERRRROORR CCOONNDDIITTIIOONNSS Inspection of an object with ldd(1) assumes it is compatible with the machine on which cchheecckk__rrttiimmee is being run. Incompatible objects such as a 64-bit object encountered on a 32-bit system, or an i386 object encountered on a sparc system, can not be fully inspected. These objects are displayed as: foo: has wrong class or data encoding FFIILLEESS _$_C_O_D_E_M_G_R___W_S_/_e_x_c_e_p_t_i_o_n___l_i_s_t_/_c_h_e_c_k___r_t_i_m_e _/_o_p_t_/_o_n_b_l_d_/_e_t_c_/_e_x_c_e_p_t_i_o_n___l_i_s_t_/_c_h_e_c_k___r_t_i_m_e SSEEEE AALLSSOO crle(1), elfdump(1), ld.so.1(1), ldd(1), mcs(1), find_elf(1ONBLD) illumos February 19, 2018 illumos