diff options
-rw-r--r-- | libctf/ChangeLog | 12 | ||||
-rw-r--r-- | libctf/Makefile.am | 4 | ||||
-rw-r--r-- | libctf/Makefile.in | 189 | ||||
-rwxr-xr-x | libctf/configure | 88 | ||||
-rw-r--r-- | libctf/configure.ac | 26 | ||||
-rw-r--r-- | libctf/doc/Makefile.am | 33 | ||||
-rw-r--r-- | libctf/doc/Makefile.in | 808 | ||||
-rw-r--r-- | libctf/doc/ctf-spec.texi | 1737 |
8 files changed, 2857 insertions, 40 deletions
diff --git a/libctf/ChangeLog b/libctf/ChangeLog index 245987f..ff9000b 100644 --- a/libctf/ChangeLog +++ b/libctf/ChangeLog @@ -1,3 +1,15 @@ +2021-11-08 Nick Alcock <nick.alcock@oracle.com> + + * doc/ctf-spec.texi: New file. + * configure.ac (MAKEINFO): Add. + (BUILD_INFO): Likewise. + (AC_CONFIG_FILES) [doc/Makefile]: Add. + * Makefile.am [BUILD_INFO] (SUBDIRS): Add doc/. + * doc/Makefile.am: New file. + * doc/Makefile.in: Likewise. + * configure: Regenerated. + * Makefile.in: Likewise. + 2021-10-25 Nick Alcock <nick.alcock@oracle.com> * ctf-types.c (ctf_type_rvisit): Handle nonrepresentable types. diff --git a/libctf/Makefile.am b/libctf/Makefile.am index 31fcb5d..f1dda92 100644 --- a/libctf/Makefile.am +++ b/libctf/Makefile.am @@ -21,6 +21,10 @@ ACLOCAL_AMFLAGS = -I .. -I ../config -I ../bfd AUTOMAKE_OPTIONS = dejagnu foreign no-texinfo.tex +if BUILD_INFO +SUBDIRS = doc +endif + # This is where we get zlib from. zlibdir is -L../zlib and zlibinc is # -I../zlib, unless we were configured with --with-system-zlib, in which # case both are empty. diff --git a/libctf/Makefile.in b/libctf/Makefile.in index 6d2d536..b922b38 100644 --- a/libctf/Makefile.in +++ b/libctf/Makefile.in @@ -254,6 +254,14 @@ am__v_CCLD_1 = SOURCES = $(libctf_nobfd_la_SOURCES) $(libctf_la_SOURCES) DIST_SOURCES = $(am__libctf_nobfd_la_SOURCES_DIST) \ $(am__libctf_la_SOURCES_DIST) +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ @@ -261,6 +269,14 @@ am__can_run_installinfo = \ esac am__include_HEADERS_DIST = $(INCDIR)/ctf.h $(INCDIR)/ctf-api.h HEADERS = $(include_HEADERS) +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + cscope distdir dist dist-all distcheck am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \ $(LISP)config.h.in # Read a list of newline-separated strings from the standard input, @@ -282,9 +298,9 @@ am__define_uniq_tagged_files = \ ETAGS = etags CTAGS = ctags CSCOPE = cscope -AM_RECURSIVE_TARGETS = cscope DEJATOOL = $(PACKAGE) RUNTESTDEFAULTFLAGS = --tool $$tool --srcdir $$srcdir +DIST_SUBDIRS = doc am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in \ $(top_srcdir)/../ar-lib $(top_srcdir)/../compile \ $(top_srcdir)/../config.guess $(top_srcdir)/../config.sub \ @@ -301,6 +317,31 @@ am__remove_distdir = \ || { sleep 5 && rm -rf "$(distdir)"; }; \ else :; fi am__post_remove_distdir = $(am__remove_distdir) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = --best DIST_TARGETS = dist-gzip @@ -455,6 +496,7 @@ zlibdir = @zlibdir@ zlibinc = @zlibinc@ ACLOCAL_AMFLAGS = -I .. -I ../config -I ../bfd AUTOMAKE_OPTIONS = dejagnu foreign no-texinfo.tex +@BUILD_INFO_TRUE@SUBDIRS = doc # This is where we get zlib from. zlibdir is -L../zlib and zlibinc is # -I../zlib, unless we were configured with --with-system-zlib, in which @@ -510,7 +552,7 @@ RUNTESTFLAGS = @TCL_TRY_TRUE@EXTRA_DEJAGNU_SITE_CONFIG = development.exp @TCL_TRY_TRUE@DISTCLEANFILES = site.exp development.exp all: config.h - $(MAKE) $(AM_MAKEFLAGS) all-am + $(MAKE) $(AM_MAKEFLAGS) all-recursive .SUFFIXES: .SUFFIXES: .c .lo .o .obj @@ -969,14 +1011,61 @@ uninstall-includeHEADERS: files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir) +# This directory's subdirectories are mostly independent; you can cd +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique -tags: tags-am +tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ @@ -989,7 +1078,7 @@ tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $$unique; \ fi; \ fi -ctags: ctags-am +ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) @@ -1008,7 +1097,7 @@ cscope: cscope.files clean-cscope: -rm -f cscope.files cscope.files: clean-cscope cscopelist -cscopelist: cscopelist-am +cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ @@ -1104,6 +1193,31 @@ distdir: $(DISTFILES) || exit 1; \ fi; \ done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done -test -n "$(am__skip_mode_fix)" \ || find "$(distdir)" -type d ! -perm -755 \ -exec chmod u+rwx,go+rx {} \; -o \ @@ -1237,21 +1351,22 @@ distcleancheck: distclean exit 1; } >&2 check-am: all-am $(MAKE) $(AM_MAKEFLAGS) check-DEJAGNU -check: check-am +check: check-recursive all-am: Makefile $(LTLIBRARIES) $(HEADERS) config.h -installdirs: +installdirs: installdirs-recursive +installdirs-am: for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am -installcheck: installcheck-am +installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ @@ -1274,12 +1389,12 @@ distclean-generic: maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -clean: clean-am +clean: clean-recursive clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ clean-noinstLTLIBRARIES mostlyclean-am -distclean: distclean-am +distclean: distclean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf ./$(DEPDIR) -rm -f Makefile @@ -1287,75 +1402,76 @@ distclean-am: clean-am distclean-DEJAGNU distclean-compile \ distclean-generic distclean-hdr distclean-libtool \ distclean-tags -dvi: dvi-am +dvi: dvi-recursive dvi-am: -html: html-am +html: html-recursive html-am: -info: info-am +info: info-recursive info-am: install-data-am: install-includeHEADERS -install-dvi: install-dvi-am +install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-libLTLIBRARIES -install-html: install-html-am +install-html: install-html-recursive install-html-am: -install-info: install-info-am +install-info: install-info-recursive install-info-am: install-man: -install-pdf: install-pdf-am +install-pdf: install-pdf-recursive install-pdf-am: -install-ps: install-ps-am +install-ps: install-ps-recursive install-ps-am: installcheck-am: -maintainer-clean: maintainer-clean-am +maintainer-clean: maintainer-clean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic -mostlyclean: mostlyclean-am +mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool -pdf: pdf-am +pdf: pdf-recursive pdf-am: -ps: ps-am +ps: ps-recursive ps-am: uninstall-am: uninstall-includeHEADERS uninstall-libLTLIBRARIES -.MAKE: all check-am install-am install-strip +.MAKE: $(am__recursive_targets) all check-am install-am install-strip -.PHONY: CTAGS GTAGS TAGS all all-am am--refresh check check-DEJAGNU \ - check-am clean clean-cscope clean-generic clean-libLTLIBRARIES \ - clean-libtool clean-noinstLTLIBRARIES cscope cscopelist-am \ - ctags ctags-am dist dist-all dist-bzip2 dist-gzip dist-lzip \ - dist-shar dist-tarZ dist-xz dist-zip distcheck distclean \ +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ + am--refresh check check-DEJAGNU check-am clean clean-cscope \ + clean-generic clean-libLTLIBRARIES clean-libtool \ + clean-noinstLTLIBRARIES cscope cscopelist-am ctags ctags-am \ + dist dist-all dist-bzip2 dist-gzip dist-lzip dist-shar \ + dist-tarZ dist-xz dist-zip distcheck distclean \ distclean-DEJAGNU distclean-compile distclean-generic \ distclean-hdr distclean-libtool distclean-tags distcleancheck \ distdir distuninstallcheck dvi dvi-am html html-am info \ @@ -1365,10 +1481,11 @@ uninstall-am: uninstall-includeHEADERS uninstall-libLTLIBRARIES install-info install-info-am install-libLTLIBRARIES \ install-man install-pdf install-pdf-am install-ps \ install-ps-am install-strip installcheck installcheck-am \ - installdirs maintainer-clean maintainer-clean-generic \ - mostlyclean mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ - uninstall-am uninstall-includeHEADERS uninstall-libLTLIBRARIES + installdirs installdirs-am maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am uninstall-includeHEADERS \ + uninstall-libLTLIBRARIES .PRECIOUS: Makefile diff --git a/libctf/configure b/libctf/configure index 1bed5e1..c683b01 100755 --- a/libctf/configure +++ b/libctf/configure @@ -642,6 +642,8 @@ TCL_TRY_TRUE EXPECT CTF_LIBADD SHARED_LDFLAGS +BUILD_INFO_FALSE +BUILD_INFO_TRUE NEED_CTF_QSORT_R_FALSE NEED_CTF_QSORT_R_TRUE ENABLE_LIBCTF_HASH_DEBUGGING_FALSE @@ -11588,7 +11590,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11591 "configure" +#line 11593 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -11694,7 +11696,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11697 "configure" +#line 11699 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -13407,6 +13409,81 @@ $as_echo "#define HAVE_O_CLOEXEC 1" >>confdefs.h fi +build_info= +makeinfo_too_old= +for ac_prog in makeinfo +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_MAKEINFO+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$MAKEINFO"; then + ac_cv_prog_MAKEINFO="$MAKEINFO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_MAKEINFO="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +MAKEINFO=$ac_cv_prog_MAKEINFO +if test -n "$MAKEINFO"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAKEINFO" >&5 +$as_echo "$MAKEINFO" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$MAKEINFO" && break +done +test -n "$MAKEINFO" || MAKEINFO="$MISSING makeinfo" + +case " $build_configdirs " in + *" texinfo "*) MAKEINFO='$$r/$(BUILD_SUBDIR)/texinfo/makeinfo/makeinfo' ;; +esac + + # We require texinfo to be 6.3 or later, for a working synindex + # and validatemenus: otherwise we fall back to /bin/true. + if ${MAKEINFO} --version \ + | egrep 'texinfo[^0-9]*(6\.[3-9]|[7-9][0-9])' >/dev/null 2>&1; then + build_info=yes + else + build_info= + makeinfo_too_old=t + fi + +if test -n "$makeinfo_too_old"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: +*** Makeinfo is too old. Info documentation will not be built." >&5 +$as_echo "$as_me: WARNING: +*** Makeinfo is too old. Info documentation will not be built." >&2;} +fi + + if test "${build_info}" = yes; then + BUILD_INFO_TRUE= + BUILD_INFO_FALSE='#' +else + BUILD_INFO_TRUE='#' + BUILD_INFO_FALSE= +fi + + CTF_LIBADD="-L`pwd`/../libiberty -liberty" SHARED_LDFLAGS= @@ -13569,7 +13646,7 @@ fi -ac_config_files="$ac_config_files Makefile" +ac_config_files="$ac_config_files Makefile doc/Makefile" ac_config_headers="$ac_config_headers config.h" @@ -13723,6 +13800,10 @@ if test -z "${NEED_CTF_QSORT_R_TRUE}" && test -z "${NEED_CTF_QSORT_R_FALSE}"; th as_fn_error $? "conditional \"NEED_CTF_QSORT_R\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${BUILD_INFO_TRUE}" && test -z "${BUILD_INFO_FALSE}"; then + as_fn_error $? "conditional \"BUILD_INFO\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${TCL_TRY_TRUE}" && test -z "${TCL_TRY_FALSE}"; then as_fn_error $? "conditional \"TCL_TRY\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -14582,6 +14663,7 @@ do "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; diff --git a/libctf/configure.ac b/libctf/configure.ac index 4e12a4f..dc06d27 100644 --- a/libctf/configure.ac +++ b/libctf/configure.ac @@ -173,6 +173,30 @@ if test $ac_cv_libctf_macro_O_CLOEXEC = yes; then [Whether the platform has a definition of O_CLOEXEC.]) fi +build_info= +makeinfo_too_old= +AC_CHECK_PROGS([MAKEINFO], makeinfo, [$MISSING makeinfo]) +case " $build_configdirs " in + *" texinfo "*) MAKEINFO='$$r/$(BUILD_SUBDIR)/texinfo/makeinfo/makeinfo' ;; +esac +changequote(,) + # We require texinfo to be 6.3 or later, for a working synindex + # and validatemenus: otherwise we fall back to /bin/true. + if ${MAKEINFO} --version \ + | egrep 'texinfo[^0-9]*(6\.[3-9]|[7-9][0-9])' >/dev/null 2>&1; then + build_info=yes + else + build_info= + makeinfo_too_old=t + fi +changequote([,]) +if test -n "$makeinfo_too_old"; then + AC_MSG_WARN([ +*** Makeinfo is too old. Info documentation will not be built.]) +fi +AC_SUBST(MAKEINFO) +AM_CONDITIONAL(BUILD_INFO, test "${build_info}" = yes) + CTF_LIBADD="-L`pwd`/../libiberty -liberty" SHARED_LDFLAGS= @@ -265,7 +289,7 @@ fi AC_SUBST(VERSION_FLAGS) AC_SUBST(VERSION_FLAGS_NOBFD) -AC_CONFIG_FILES(Makefile) +AC_CONFIG_FILES(Makefile doc/Makefile) AC_CONFIG_HEADERS(config.h) AC_OUTPUT diff --git a/libctf/doc/Makefile.am b/libctf/doc/Makefile.am new file mode 100644 index 0000000..fb6b0a8 --- /dev/null +++ b/libctf/doc/Makefile.am @@ -0,0 +1,33 @@ +## Process this file with automake to produce Makefile.in. +# +# Copyright (C) 2019-2021 Free Software Foundation, Inc. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; see the file COPYING. If not see +# <http://www.gnu.org/licenses/>. +# + +AUTOMAKE_OPTIONS = info-in-builddir foreign no-texinfo.tex + +info_TEXINFOS = ctf-spec.texi +libctf_TEXINFOS = $(info_TEXINFOS) + +AM_MAKEINFOFLAGS = --no-split + +DISTCLEANFILES = texput.log +MAINTAINERCLEANFILES = ctf-spec.info + +html-local: ctf-spec/index.html +ctf-spec/index.html: ctf-spec.texi + $(AM_V_at)$(MAKEINFOHTML) $(AM_MAKEINFOHTMLFLAGS) $(MAKEINFOFLAGS) \ + --split=node -I$(srcdir) $(srcdir)/ctf-spec.texi diff --git a/libctf/doc/Makefile.in b/libctf/doc/Makefile.in new file mode 100644 index 0000000..6e4833c --- /dev/null +++ b/libctf/doc/Makefile.in @@ -0,0 +1,808 @@ +# Makefile.in generated by automake 1.15.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2017 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# +# Copyright (C) 2019-2021 Free Software Foundation, Inc. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; see the file COPYING. If not see +# <http://www.gnu.org/licenses/>. +# +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +subdir = doc +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/../bfd/acinclude.m4 \ + $(top_srcdir)/../config/acx.m4 \ + $(top_srcdir)/../config/depstand.m4 \ + $(top_srcdir)/../config/enable.m4 \ + $(top_srcdir)/../config/gettext-sister.m4 \ + $(top_srcdir)/../config/jobserver.m4 \ + $(top_srcdir)/../config/lead-dot.m4 \ + $(top_srcdir)/../config/override.m4 \ + $(top_srcdir)/../config/warnings.m4 \ + $(top_srcdir)/../config/zlib.m4 $(top_srcdir)/../libtool.m4 \ + $(top_srcdir)/../ltoptions.m4 $(top_srcdir)/../ltsugar.m4 \ + $(top_srcdir)/../ltversion.m4 $(top_srcdir)/../lt~obsolete.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +AM_V_DVIPS = $(am__v_DVIPS_@AM_V@) +am__v_DVIPS_ = $(am__v_DVIPS_@AM_DEFAULT_V@) +am__v_DVIPS_0 = @echo " DVIPS " $@; +am__v_DVIPS_1 = +AM_V_MAKEINFO = $(am__v_MAKEINFO_@AM_V@) +am__v_MAKEINFO_ = $(am__v_MAKEINFO_@AM_DEFAULT_V@) +am__v_MAKEINFO_0 = @echo " MAKEINFO" $@; +am__v_MAKEINFO_1 = +AM_V_INFOHTML = $(am__v_INFOHTML_@AM_V@) +am__v_INFOHTML_ = $(am__v_INFOHTML_@AM_DEFAULT_V@) +am__v_INFOHTML_0 = @echo " INFOHTML" $@; +am__v_INFOHTML_1 = +AM_V_TEXI2DVI = $(am__v_TEXI2DVI_@AM_V@) +am__v_TEXI2DVI_ = $(am__v_TEXI2DVI_@AM_DEFAULT_V@) +am__v_TEXI2DVI_0 = @echo " TEXI2DVI" $@; +am__v_TEXI2DVI_1 = +AM_V_TEXI2PDF = $(am__v_TEXI2PDF_@AM_V@) +am__v_TEXI2PDF_ = $(am__v_TEXI2PDF_@AM_DEFAULT_V@) +am__v_TEXI2PDF_0 = @echo " TEXI2PDF" $@; +am__v_TEXI2PDF_1 = +AM_V_texinfo = $(am__v_texinfo_@AM_V@) +am__v_texinfo_ = $(am__v_texinfo_@AM_DEFAULT_V@) +am__v_texinfo_0 = -q +am__v_texinfo_1 = +AM_V_texidevnull = $(am__v_texidevnull_@AM_V@) +am__v_texidevnull_ = $(am__v_texidevnull_@AM_DEFAULT_V@) +am__v_texidevnull_0 = > /dev/null +am__v_texidevnull_1 = +INFO_DEPS = ctf-spec.info +am__TEXINFO_TEX_DIR = $(srcdir) +DVIS = ctf-spec.dvi +PDFS = ctf-spec.pdf +PSS = ctf-spec.ps +HTMLS = ctf-spec.html +TEXINFOS = ctf-spec.texi +TEXI2DVI = texi2dvi +TEXI2PDF = $(TEXI2DVI) --pdf --batch +MAKEINFOHTML = $(MAKEINFO) --html +AM_MAKEINFOHTMLFLAGS = $(AM_MAKEINFOFLAGS) +DVIPS = dvips +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__installdirs = "$(DESTDIR)$(infodir)" +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/../mkinstalldirs +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CATALOGS = @CATALOGS@ +CATOBJEXT = @CATOBJEXT@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CTF_LIBADD = @CTF_LIBADD@ +CYGPATH_W = @CYGPATH_W@ +DATADIRNAME = @DATADIRNAME@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +EXPECT = @EXPECT@ +FGREP = @FGREP@ +GENCAT = @GENCAT@ +GMSGFMT = @GMSGFMT@ +GREP = @GREP@ +INCINTL = @INCINTL@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INSTOBJEXT = @INSTOBJEXT@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBINTL = @LIBINTL@ +LIBINTL_DEP = @LIBINTL_DEP@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +POSUB = @POSUB@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHARED_LDFLAGS = @SHARED_LDFLAGS@ +SHELL = @SHELL@ +STRIP = @STRIP@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +VERSION_FLAGS = @VERSION_FLAGS@ +VERSION_FLAGS_NOBFD = @VERSION_FLAGS_NOBFD@ +WARN_PEDANTIC = @WARN_PEDANTIC@ +WERROR = @WERROR@ +XGETTEXT = @XGETTEXT@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +ac_libctf_warn_cflags = @ac_libctf_warn_cflags@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +c_warn = @c_warn@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_noncanonical = @host_noncanonical@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_noncanonical = @target_noncanonical@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +warn = @warn@ +zlibdir = @zlibdir@ +zlibinc = @zlibinc@ +AUTOMAKE_OPTIONS = info-in-builddir foreign no-texinfo.tex +info_TEXINFOS = ctf-spec.texi +libctf_TEXINFOS = $(info_TEXINFOS) +AM_MAKEINFOFLAGS = --no-split +DISTCLEANFILES = texput.log +MAINTAINERCLEANFILES = ctf-spec.info +all: all-am + +.SUFFIXES: +.SUFFIXES: .dvi .ps +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign doc/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign doc/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ctf-spec.info: ctf-spec.texi + $(AM_V_MAKEINFO)restore=: && backupdir="$(am__leading_dot)am$$$$" && \ + rm -rf $$backupdir && mkdir $$backupdir && \ + if ($(MAKEINFO) --version) >/dev/null 2>&1; then \ + for f in $@ $@-[0-9] $@-[0-9][0-9] $(@:.info=).i[0-9] $(@:.info=).i[0-9][0-9]; do \ + if test -f $$f; then mv $$f $$backupdir; restore=mv; else :; fi; \ + done; \ + else :; fi && \ + if $(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \ + -o $@ `test -f 'ctf-spec.texi' || echo '$(srcdir)/'`ctf-spec.texi; \ + then \ + rc=0; \ + else \ + rc=$$?; \ + $$restore $$backupdir/* `echo "./$@" | sed 's|[^/]*$$||'`; \ + fi; \ + rm -rf $$backupdir; exit $$rc + +ctf-spec.dvi: ctf-spec.texi + $(AM_V_TEXI2DVI)TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \ + MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \ + $(TEXI2DVI) $(AM_V_texinfo) --build-dir=$(@:.dvi=.t2d) -o $@ $(AM_V_texidevnull) \ + `test -f 'ctf-spec.texi' || echo '$(srcdir)/'`ctf-spec.texi + +ctf-spec.pdf: ctf-spec.texi + $(AM_V_TEXI2PDF)TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \ + MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \ + $(TEXI2PDF) $(AM_V_texinfo) --build-dir=$(@:.pdf=.t2p) -o $@ $(AM_V_texidevnull) \ + `test -f 'ctf-spec.texi' || echo '$(srcdir)/'`ctf-spec.texi + +ctf-spec.html: ctf-spec.texi + $(AM_V_MAKEINFO)rm -rf $(@:.html=.htp) + $(AM_V_at)if $(MAKEINFOHTML) $(AM_MAKEINFOHTMLFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \ + -o $(@:.html=.htp) `test -f 'ctf-spec.texi' || echo '$(srcdir)/'`ctf-spec.texi; \ + then \ + rm -rf $@ && mv $(@:.html=.htp) $@; \ + else \ + rm -rf $(@:.html=.htp); exit 1; \ + fi +.dvi.ps: + $(AM_V_DVIPS)TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \ + $(DVIPS) $(AM_V_texinfo) -o $@ $< + +uninstall-dvi-am: + @$(NORMAL_UNINSTALL) + @list='$(DVIS)'; test -n "$(dvidir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " rm -f '$(DESTDIR)$(dvidir)/$$f'"; \ + rm -f "$(DESTDIR)$(dvidir)/$$f"; \ + done + +uninstall-html-am: + @$(NORMAL_UNINSTALL) + @list='$(HTMLS)'; test -n "$(htmldir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " rm -rf '$(DESTDIR)$(htmldir)/$$f'"; \ + rm -rf "$(DESTDIR)$(htmldir)/$$f"; \ + done + +uninstall-info-am: + @$(PRE_UNINSTALL) + @if test -d '$(DESTDIR)$(infodir)' && $(am__can_run_installinfo); then \ + list='$(INFO_DEPS)'; \ + for file in $$list; do \ + relfile=`echo "$$file" | sed 's|^.*/||'`; \ + echo " install-info --info-dir='$(DESTDIR)$(infodir)' --remove '$(DESTDIR)$(infodir)/$$relfile'"; \ + if install-info --info-dir="$(DESTDIR)$(infodir)" --remove "$(DESTDIR)$(infodir)/$$relfile"; \ + then :; else test ! -f "$(DESTDIR)$(infodir)/$$relfile" || exit 1; fi; \ + done; \ + else :; fi + @$(NORMAL_UNINSTALL) + @list='$(INFO_DEPS)'; \ + for file in $$list; do \ + relfile=`echo "$$file" | sed 's|^.*/||'`; \ + relfile_i=`echo "$$relfile" | sed 's|\.info$$||;s|$$|.i|'`; \ + (if test -d "$(DESTDIR)$(infodir)" && cd "$(DESTDIR)$(infodir)"; then \ + echo " cd '$(DESTDIR)$(infodir)' && rm -f $$relfile $$relfile-[0-9] $$relfile-[0-9][0-9] $$relfile_i[0-9] $$relfile_i[0-9][0-9]"; \ + rm -f $$relfile $$relfile-[0-9] $$relfile-[0-9][0-9] $$relfile_i[0-9] $$relfile_i[0-9][0-9]; \ + else :; fi); \ + done + +uninstall-pdf-am: + @$(NORMAL_UNINSTALL) + @list='$(PDFS)'; test -n "$(pdfdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " rm -f '$(DESTDIR)$(pdfdir)/$$f'"; \ + rm -f "$(DESTDIR)$(pdfdir)/$$f"; \ + done + +uninstall-ps-am: + @$(NORMAL_UNINSTALL) + @list='$(PSS)'; test -n "$(psdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " rm -f '$(DESTDIR)$(psdir)/$$f'"; \ + rm -f "$(DESTDIR)$(psdir)/$$f"; \ + done + +dist-info: $(INFO_DEPS) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + list='$(INFO_DEPS)'; \ + for base in $$list; do \ + case $$base in \ + $(srcdir)/*) base=`echo "$$base" | sed "s|^$$srcdirstrip/||"`;; \ + esac; \ + if test -f $$base; then d=.; else d=$(srcdir); fi; \ + base_i=`echo "$$base" | sed 's|\.info$$||;s|$$|.i|'`; \ + for file in $$d/$$base $$d/$$base-[0-9] $$d/$$base-[0-9][0-9] $$d/$$base_i[0-9] $$d/$$base_i[0-9][0-9]; do \ + if test -f $$file; then \ + relfile=`expr "$$file" : "$$d/\(.*\)"`; \ + test -f "$(distdir)/$$relfile" || \ + cp -p $$file "$(distdir)/$$relfile"; \ + else :; fi; \ + done; \ + done + +mostlyclean-aminfo: + -rm -rf ctf-spec.t2d ctf-spec.t2p + +clean-aminfo: + -test -z "ctf-spec.dvi ctf-spec.pdf ctf-spec.ps ctf-spec.html" \ + || rm -rf ctf-spec.dvi ctf-spec.pdf ctf-spec.ps ctf-spec.html + +maintainer-clean-aminfo: + @list='$(INFO_DEPS)'; for i in $$list; do \ + i_i=`echo "$$i" | sed 's|\.info$$||;s|$$|.i|'`; \ + echo " rm -f $$i $$i-[0-9] $$i-[0-9][0-9] $$i_i[0-9] $$i_i[0-9][0-9]"; \ + rm -f $$i $$i-[0-9] $$i-[0-9][0-9] $$i_i[0-9] $$i_i[0-9][0-9]; \ + done +tags TAGS: + +ctags CTAGS: + +cscope cscopelist: + + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$(top_distdir)" distdir="$(distdir)" \ + dist-info +check-am: all-am +check: check-am +all-am: Makefile $(INFO_DEPS) +installdirs: + for dir in "$(DESTDIR)$(infodir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-am + +clean-am: clean-aminfo clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: $(DVIS) + +html: html-am + +html-am: $(HTMLS) html-local + +info: info-am + +info-am: $(INFO_DEPS) + +install-data-am: install-info-am + +install-dvi: install-dvi-am + +install-dvi-am: $(DVIS) + @$(NORMAL_INSTALL) + @list='$(DVIS)'; test -n "$(dvidir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(dvidir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(dvidir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(dvidir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(dvidir)" || exit $$?; \ + done +install-exec-am: + +install-html: install-html-am + +install-html-am: $(HTMLS) + @$(NORMAL_INSTALL) + @list='$(HTMLS)'; list2=; test -n "$(htmldir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(htmldir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(htmldir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p" || test -d "$$p"; then d=; else d="$(srcdir)/"; fi; \ + $(am__strip_dir) \ + d2=$$d$$p; \ + if test -d "$$d2"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(htmldir)/$$f'"; \ + $(MKDIR_P) "$(DESTDIR)$(htmldir)/$$f" || exit 1; \ + echo " $(INSTALL_DATA) '$$d2'/* '$(DESTDIR)$(htmldir)/$$f'"; \ + $(INSTALL_DATA) "$$d2"/* "$(DESTDIR)$(htmldir)/$$f" || exit $$?; \ + else \ + list2="$$list2 $$d2"; \ + fi; \ + done; \ + test -z "$$list2" || { echo "$$list2" | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(htmldir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(htmldir)" || exit $$?; \ + done; } +install-info: install-info-am + +install-info-am: $(INFO_DEPS) + @$(NORMAL_INSTALL) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + list='$(INFO_DEPS)'; test -n "$(infodir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(infodir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(infodir)" || exit 1; \ + fi; \ + for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + esac; \ + if test -f $$file; then d=.; else d=$(srcdir); fi; \ + file_i=`echo "$$file" | sed 's|\.info$$||;s|$$|.i|'`; \ + for ifile in $$d/$$file $$d/$$file-[0-9] $$d/$$file-[0-9][0-9] \ + $$d/$$file_i[0-9] $$d/$$file_i[0-9][0-9] ; do \ + if test -f $$ifile; then \ + echo "$$ifile"; \ + else : ; fi; \ + done; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(infodir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(infodir)" || exit $$?; done + @$(POST_INSTALL) + @if $(am__can_run_installinfo); then \ + list='$(INFO_DEPS)'; test -n "$(infodir)" || list=; \ + for file in $$list; do \ + relfile=`echo "$$file" | sed 's|^.*/||'`; \ + echo " install-info --info-dir='$(DESTDIR)$(infodir)' '$(DESTDIR)$(infodir)/$$relfile'";\ + install-info --info-dir="$(DESTDIR)$(infodir)" "$(DESTDIR)$(infodir)/$$relfile" || :;\ + done; \ + else : ; fi +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: $(PDFS) + @$(NORMAL_INSTALL) + @list='$(PDFS)'; test -n "$(pdfdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(pdfdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pdfdir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pdfdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(pdfdir)" || exit $$?; done +install-ps: install-ps-am + +install-ps-am: $(PSS) + @$(NORMAL_INSTALL) + @list='$(PSS)'; test -n "$(psdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(psdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(psdir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(psdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(psdir)" || exit $$?; done +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-aminfo \ + maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-aminfo mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: $(PDFS) + +ps: ps-am + +ps-am: $(PSS) + +uninstall-am: uninstall-dvi-am uninstall-html-am uninstall-info-am \ + uninstall-pdf-am uninstall-ps-am + +.MAKE: install-am install-strip + +.PHONY: all all-am check check-am clean clean-aminfo clean-generic \ + clean-libtool cscopelist-am ctags-am dist-info distclean \ + distclean-generic distclean-libtool distdir dvi dvi-am html \ + html-am html-local info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-aminfo maintainer-clean-generic mostlyclean \ + mostlyclean-aminfo mostlyclean-generic mostlyclean-libtool pdf \ + pdf-am ps ps-am tags-am uninstall uninstall-am \ + uninstall-dvi-am uninstall-html-am uninstall-info-am \ + uninstall-pdf-am uninstall-ps-am + +.PRECIOUS: Makefile + + +html-local: ctf-spec/index.html +ctf-spec/index.html: ctf-spec.texi + $(AM_V_at)$(MAKEINFOHTML) $(AM_MAKEINFOHTMLFLAGS) $(MAKEINFOFLAGS) \ + --split=node -I$(srcdir) $(srcdir)/ctf-spec.texi + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libctf/doc/ctf-spec.texi b/libctf/doc/ctf-spec.texi new file mode 100644 index 0000000..78c7aed --- /dev/null +++ b/libctf/doc/ctf-spec.texi @@ -0,0 +1,1737 @@ +\input texinfo @c -*- Texinfo -*- +@setfilename ctf-spec.info +@settitle The CTF File Format +@ifnottex +@validatemenus off +@xrefautomaticsectiontitle on +@end ifnottex +@synindex fn cp +@synindex tp cp +@synindex vr cp + +@copying +Copyright @copyright{} 2021 Free Software Foundation, Inc. + +Permission is granted to copy, distribute and/or modify this document +under the terms of the GNU General Public License, Version 3 or any +later version published by the Free Software Foundation. A copy of the +license is included in the section entitled ``GNU General Public +License''. + +@end copying + +@dircategory Software development +@direntry +* CTF: (ctf-spec). The CTF file format. +@end direntry + +@titlepage +@title The CTF File Format +@subtitle Version 3 +@author Nick Alcock + +@page +@vskip 0pt plus 1filll +@insertcopying +@end titlepage +@contents + +@ifnottex +@node Top +@top The CTF file format + +This manual describes version 3 of the CTF file format, which is +intended to model the C type system in a fashion that C programs can +consume at runtime. +@end ifnottex + +@node Overview +@unnumbered Overview +@cindex Overview + +The CTF file format compactly describes C types and the association +between function and data symbols and types: if embedded in ELF objects, +it can exploit the ELF string table to reduce duplication further. +There is no real concept of namespacing: only top-level types are +described, not types scoped to within single functions. + +CTF dictionaries can be @dfn{children} of other dictionaries, in a +one-level hierarchy: child dictionaries can refer to types in the +parent, but the opposite is not sensible (since if you refer to a child +type in the parent, the actual type you cited would vary depending on +what child was attached). This parent/child definition is recorded in +the child, but only as a recommendation: users of the API have to attach +parents to children explicitly, and can choose to attach a child to any +parent they like, or to none, though doing so might lead to unpleasant +consequences like dangling references to types. @xref{Type indexes and +type IDs}. Type lookups in child dicts that are not associated with a +parent at all will fail with @code{ECTF_NOPARENT} if a parent type was +needed. + +The associated API to generate, merge together, and query this file +format will be described in the accompanying @code{libctf} manual once +it is written. There is no API to modify dictionaries once they've been +written out: CTF is a write-once file format. (However, it is always +possible to dynamically create a new child dictionary on the fly and +attach it to a pre-existing, read-only parent.) + +There are two major pieces to CTF: the @dfn{archive} and the +@dfn{dictionary}. Some relatives and ancestors of CTF call dictionaries +@dfn{containers}: the archive format is unique to this variant of CTF. +(Much of the source code still uses the old term.) + +The archive file format is a very simple mmappable archive used to group +multiple dictionaries together into groups: it is expected to slowly go +away and be replaced by other mechanisms, but right now it is an +important part of the file format, used to group dictionaries containing +types with conflicting definitions in different TUs with the overarching +dictionary used to store all other types. (Even when archives go away, +the @code{libctf} API used to access them will remain, and access the +other mechanisms that replace it instead.) + +The CTF dictionary consists of a @dfn{preamble}, which does not vary +between versions of the CTF file format, and a @dfn{header} and some +number of @dfn{sections}, which can vary between versions. + +The rest of this specification describes the format of these sections, +first for the latest version of CTF, then for all earlier versions +supported by @code{libctf}: the earlier versions are defined in terms of +their differences from the next later one. We describe each part of the +format first by reproducing the C structure which defines that part, +then describing it at greater length in terms of file offsets. + +The description of the file format ends with a description of relevant +limits that apply to it. These limits can vary between file format +versions. + +This document is quite young, so for now the C code in @file{ctf.h} +should be presumed correct when this document conflicts with it. + +@node CTF archive +@chapter CTF archives +@cindex archive, CTF archive + +The CTF archive format maps names to CTF dictionaries. The names may +contain any character other than \0, but for now archives containing +slashes in the names may not extract correctly. It is possible to +insert multiple members with the same name, but these are quite hard to +access reliably (you have to iterate through all the members rather than +opening by name) so this is not recommended. + +CTF archives are not themselves compressed: the constituent components, +CTF dictionaries, can be compressed. (@xref{CTF header}). + +CTF archives usually contain a collection of related dictionaries, one +parent and many children of that parent. CTF archives can have a member +with a @dfn{default name}, @code{.ctf} (which can be represented as +@code{NULL} in the API). If present, this member is usually the parent +of all the children, but it is possible for CTF producers to emit +parents with different names if they wish (usually for backward- +compatibility purposes). + +@code{.ctf} sections in ELF objects consist of a single CTF dictionary +rather than an archive of dictionaries if and only if the section +contains no types with identical names but conflicting definitions: if +two conflicting definitions exist, the deduplicator will place the type +most commonly referred to by other types in the parent and will place +the other type in a child named after the translation unit it is found +in, and will emit a CTF archive containing both dictionaries instead of +a raw dictionary. All types that refer to such conflicting types are +also placed in the per-translation-unit child. + +The definition of an archive in @file{ctf.h} is as follows: + +@verbatim +struct ctf_archive +{ + uint64_t ctfa_magic; + uint64_t ctfa_model; + uint64_t ctfa_nfiles; + uint64_t ctfa_names; + uint64_t ctfa_ctfs; +}; + +typedef struct ctf_archive_modent +{ + uint64_t name_offset; + uint64_t ctf_offset; +} ctf_archive_modent_t; +@end verbatim + +(Note one irregularity here: the @code{ctf_archive_t} is not a typedef +to @code{struct ctf_archive}, but a different typedef, private to +@code{libctf}, so that things that are not really archives can be made +to appear as if they were.) + +All the above items are always in little-endian byte order, regardless +of the machine endianness. + +The archive header has the following fields: + +@tindex struct ctf_archive +@multitable {Offset} {@code{uint64_t ctfa_nfiles}} {The data model for this archive: an arbitrary integer} +@headitem Offset @tab Name @tab Description +@item 0x00 +@tab @code{uint64_t ctfa_magic} +@vindex ctfa_magic +@vindex struct ctf_archive, ctfa_magic +@tab The magic number for archives, @code{CTFA_MAGIC}: 0x8b47f2a4d7623eeb. +@tindex CTFA_MAGIC + +@item 0x08 +@tab @code{uint64_t ctfa_model} +@vindex ctfa_model +@vindex struct ctf_archive, ctfa_model +@tab The data model for this archive: an arbitrary integer that serves no +purpose but to be handed back by the libctf API. @xref{Data models}. + +@item 0x10 +@tab @code{uint64_t ctfa_nfiles} +@vindex ctfa_nfiles +@vindex struct ctf_archive, ctfa_nfiles +@tab The number of CTF dictionaries in this archive. + +@item 0x18 +@tab @code{uint64_t ctfa_names} +@vindex ctfa_names +@vindex struct ctf_archive, ctfa_names +@tab Offset of the name table, in bytes from the start of the archive. +The name table is an array of @code{struct ctf_archive_modent_t[ctfa_nfiles]}. + +@item 0x20 +@tab @code{uint64_t ctfa_ctfs} +@vindex ctfa_ctfs +@vindex struct ctf_archive, ctfa_ctfs +@tab Offset of the CTF table. Each element starts with a @code{uint64_t} size, +followed by a CTF dictionary. + +@end multitable + +The array pointed to by @code{ctfa_names} is an array of entries of +@code{ctf_archive_modent}: + +@tindex struct ctf_archive_modent +@tindex ctf_archive_modent_t +@multitable {Offset} {@code{uint64_t name_offset}} {Offset of this name, in bytes from the start} +@headitem Offset @tab Name @tab Description +@item 0x00 +@tab @code{uint64_t name_offset} +@vindex name_offset +@vindex struct ctf_archive_modent, name_offset +@vindex ctf_archive_modent_t, name_offset +@tab Offset of this name, in bytes from the start of the archive. + +@item 0x08 +@tab @code{uint64_t ctf_offset} +@vindex ctf_offset +@vindex struct ctf_archive_modent, ctf_offset +@vindex ctf_archive_modent_t, ctf_offset +@tab Offset of this CTF dictionary, in bytes from the start of the archive. + +@end multitable + +The @code{ctfa_names} array is sorted into ASCIIbetical order by name +(i.e. by the result of dereferencing the @code{name_offset}). + +The archive file also contains a name table and a table of CTF +dictionaries: these are pointed to by the structures above. The name +table is a simple strtab which is not required to be sorted; the +dictionary array is described above in the entry for @code{ctfa_ctfs}. + +The relative order of these various parts is not defined, except that +the header naturally always comes first. + +@node CTF dictionaries +@chapter CTF dictionaries +@cindex dictionary, CTF dictionary + +CTF dictionaries consist of a header, starting with a premable, and a +number of sections. + +@node CTF Preamble +@section CTF Preamble + +The preamble is the only part of the CTF dictionary whose format cannot +vary between versions. It is never compressed. It is correspondingly +simple: + +@verbatim +typedef struct ctf_preamble +{ + unsigned short ctp_magic; + unsigned char ctp_version; + unsigned char ctp_flags; +} ctf_preamble_t; +@end verbatim + +@code{#define}s are provided under the names @code{cth_magic}, +@code{cth_version} and @code{cth_flags} to make the fields of the +@code{ctf_preamble_t} appear to be part of the @code{ctf_header_t}, so +consuming programs rarely need to consider the existence of the preamble +as a separate structure. + +@tindex struct ctf_preamble +@tindex ctf_preamble_t +@multitable {Offset} {@code{unsigned char ctp_version}} {The magic number for CTF dictionaries} +@headitem Offset @tab Name @tab Description +@item 0x00 +@tab @code{unsigned short ctp_magic} +@vindex ctp_magic +@vindex cth_magic +@vindex ctf_preamble_t, ctp_magic +@vindex struct ctf_preamble, ctp_magic +@vindex ctf_header_t, cth_magic +@vindex struct ctf_header, cth_magic +@tab The magic number for CTF dictionaries, @code{CTF_MAGIC}: 0xdff2. +@tindex CTF_MAGIC + +@item 0x02 +@tab @code {unsigned char ctp_version} +@vindex ctp_version +@vindex cth_version +@vindex ctf_preamble_t, ctp_version +@vindex struct ctf_preamble, ctp_version +@vindex ctf_header_t, cth_version +@vindex struct ctf_header, cth_version +@tab The version number of this CTF dictionary. + +@item 0x03 +@tab @code{ctp_flags} +@vindex ctp_flags +@vindex cth_flags +@vindex ctf_preamble_t, ctp_flags +@vindex struct ctf_preamble, ctp_flags +@vindex ctf_header_t, cth_flags +@vindex struct ctf_header, cth_flags +@tab Flags for this CTF file. @xref{CTF file-wide flags}. +@end multitable + +@cindex alignment +Every element of a dictionary must be naturally aligned unless otherwise +specified. (This restriction will be lifted in later versions.) + +@cindex endianness +CTF dictionaries are stored in the native endianness of the system that +generates them: the consumer (e.g., @code{libctf}) can detect whether to +endian-flip a CTF dictionary by inspecting the @code{ctp_magic}. (If it +appears as 0xf2df, endian-flipping is needed.) + +The version of the CTF dictionary can be determined by inspecting +@code{ctp_version}. The following versions are currently valid, and +@code{libctf} can read all of them: + +@tindex CTF_VERSION_3 +@cindex CTF versions, versions +@multitable {@code{CTF_VERSION_1_UPGRADED_3}} {Number} {First version, rare. Very similar to Solaris CTF.} +@headitem Version @tab Number @tab Description +@item @code{CTF_VERSION_1} +@tab 1 @tab First version, rare. Very similar to Solaris CTF. + +@item @code{CTF_VERSION_1_UPGRADED_3} +@tab 2 @tab First version, upgraded to v3 or higher and written out again. +Name may change. Very rare. + +@item @code{CTF_VERSION_2} +@tab 3 @tab Second version, with many range limits lifted. + +@item @code{CTF_VERSION_3} +@tab 4 @tab Third and current version, documented here. +@end multitable + +This section documents @code{CTF_VERSION_3}. + +@vindex ctp_flags +@node CTF file-wide flags +@subsection CTF file-wide flags + +The preamble contains bitflags in its @code{ctp_flags} field that +describe various file-wide properties. Some of the flags are valid only +for particular file-format versions, which means the flags can be used +to fix file-format bugs. Consumers that see unknown flags should +accordingly assume that the dictionary is not comprehensible, and +refuse to open them. + +The following flags are currently defined. Many are bug workarounds, +valid only in CTFv3, and will not be valid in any future versions: the +same values may be reused for other flags in v4+. + +@multitable {@code{CTF_F_NEWFUNCINFO}} {Versions} {Value} {The external strtab is in @code{.dynstr} and the} +@headitem Flag @tab Versions @tab Value @tab Meaning +@tindex CTF_F_COMPRESS +@item @code{CTF_F_COMPRESS} @tab All @tab 0x1 @tab Compressed with zlib +@tindex CTF_F_NEWFUNCINFO +@item @code{CTF_F_NEWFUNCINFO} @tab 3 only @tab 0x2 +@tab ``New-format'' func info section. +@tindex CTF_F_IDXSORTED +@item @code{CTF_F_IDXSORTED} @tab 3+ @tab 0x4 @tab The index section is +in sorted order +@tindex CTF_F_DYNSTR +@item @code{CTF_F_DYNSTR} @tab 3 only @tab 0x8 @tab The external strtab is +in @code{.dynstr} and the symtab used is @code{.dynsym}. +@xref{The string section} +@end multitable + +@code{CTF_F_NEWFUNCINFO} and @code{CTF_F_IDXSORTED} relate to the +function info and data object sections. @xref{The symtypetab sections}. + +Further flags (and further compression methods) wil be added in future. + +@node CTF header +@section CTF header +@cindex CTF header +@cindex Sections, header + +The CTF header is the first part of a CTF dictionary, including the +preamble. All parts of it other than the preamble (@pxref{CTF Preamble}) +can vary between CTF file versions and are never compressed. It +contains things that apply to the dictionary as a whole, and a table of +the sections into which the rest of the dictionary is divided. The +sections tile the file: each section runs from the offset given until +the start of the next section. Only the last section cannot follow this +rule, so the header has a length for it instead. + +All section offsets, here and in the rest of the CTF file, are relative to the +@emph{end} of the header. (This is annoyingly different to how offsets in CTF +archives are handled.) + +This is the first structure to include offsets into the string table, which are +not straight references because CTF dictionaries can include references into the +ELF string table to save space, as well as into the string table internal to the +CTF dictionary. @xref{The string section} for more on these. Offset 0 is +always the null string. + +@verbatim +typedef struct ctf_header +{ + ctf_preamble_t cth_preamble; + uint32_t cth_parlabel; + uint32_t cth_parname; + uint32_t cth_cuname; + uint32_t cth_lbloff; + uint32_t cth_objtoff; + uint32_t cth_funcoff; + uint32_t cth_objtidxoff; + uint32_t cth_funcidxoff; + uint32_t cth_varoff; + uint32_t cth_typeoff; + uint32_t cth_stroff; + uint32_t cth_strlen; +} ctf_header_t; +@end verbatim + +In detail: + +@tindex struct ctf_header +@tindex ctf_header_t +@multitable {Offset} {@code{ctf_preamble_t cth_preamble}} {The parent label, if deduplication happened against} +@headitem Offset @tab Name @tab Description +@item 0x00 +@tab @code{ctf_preamble_t cth_preamble} +@vindex cth_preamble +@vindex struct ctf_header, cth_preamble +@vindex ctf_header_t, cth_preamble +@tab The preamble (conceptually embedded in the header). @xref{CTF Preamble} + +@item 0x04 +@tab @code{uint32_t cth_parlabel} +@vindex cth_parlabel +@vindex struct ctf_header, cth_parlabel +@vindex ctf_header_t, cth_parlabel +@tab The parent label, if deduplication happened against a specific label: a +strtab offset. @xref{The label section}. Currently unused and always 0, but may +be used in future when semantics are attached to the label section. + +@item 0x08 +@tab @code{uint32_t cth_parname} +@vindex cth_parname +@vindex struct ctf_header, cth_parname +@vindex ctf_header_t, cth_parname +@tab The name of the parent dictionary deduplicated against: a strtab offset. +Interpretation is up to the consumer (usually a CTF archive member name). 0 +(the null string) if this is not a child dictionary. + +@item 0x1c +@tab @code{uint32_t cth_cuname} +@vindex cth_cuname +@vindex struct ctf_header, cth_cuname +@vindex ctf_header_t, cth_cuname +@tab The name of the compilation unit, for consumers like GDB that want to +know the name of CUs associated with single CUs: a strtab offset. 0 if this +dictionary describes types from many CUs. + +@item 0x10 +@tab @code{uint32_t cth_lbloff} +@vindex cth_lbloff +@vindex struct ctf_header, cth_lbloff +@vindex ctf_header_t, cth_lbloff +@tab The offset of the label section, which tiles the type space into +named regions. @xref{The label section}. + +@item 0x14 +@tab @code{uint32_t cth_objtoff} +@vindex cth_objtoff +@vindex struct ctf_header, cth_objtoff +@vindex ctf_header_t, cth_objtoff +@tab The offset of the data object symtypetab section, which maps ELF data symbols to +types. @xref{The symtypetab sections}. + +@item 0x18 +@tab @code{uint32_t cth_funcoff} +@vindex cth_funcoff +@vindex struct ctf_header, cth_funcoff +@vindex ctf_header_t, cth_funcoff +@tab The offset of the function info symtypetab section, which maps ELF function +symbols to a return type and arg types. @xref{The symtypetab sections}. + +@item 0x1c +@tab @code{uint32_t cth_objtidxoff} +@vindex cth_objtidxoff +@vindex struct ctf_header, cth_objtidxoff +@vindex ctf_header_t, cth_objtidxoff +@tab The offset of the object index section, which maps ELF object symbols to +entries in the data object section. @xref{The symtypetab sections}. + +@item 0x20 +@tab @code{uint32_t cth_funcidxoff} +@vindex cth_funcidxoff +@vindex struct ctf_header, cth_funcidxoff +@vindex ctf_header_t, cth_funcidxoff +@tab The offset of the function info index section, which maps ELF function +symbols to entries in the function info section. @xref{The symtypetab sections}. + +@item 0x24 +@tab @code{uint32_t cth_varoff} +@vindex cth_varoff +@vindex struct ctf_header, cth_varoff +@vindex ctf_header_t, cth_varoff +@tab The offset of the variable section, which maps string names to types. +@xref{The variable section}. + +@item 0x28 +@tab @code{uint32_t cth_typeoff} +@vindex cth_typeoff +@vindex struct ctf_header, cth_typeoff +@vindex ctf_header_t, cth_typeoff +@tab The offset of the type section, the core of CTF, which describes types + using variable-length array elements. @xref{The type section}. + +@item 0x2c +@tab @code{uint32_t cth_stroff} +@vindex cth_stroff +@vindex struct ctf_header, cth_stroff +@vindex ctf_header_t, cth_stroff +@tab The offset of the string section. @xref{The string section}. + +@item 0x30 +@tab @code{uint32_t cth_strlen} +@vindex cth_strlen +@vindex struct ctf_header, cth_strlen +@vindex ctf_header_t, cth_strlen +@tab The length of the string section (not an offset!). The CTF file ends +at this point. + +@end multitable + +Everything from this point on (until the end of the file at @code{cth_stroff} + +@code{cth_strlen}) is compressed with zlib if @code{CTF_F_COMPRESS} is set in +the preamble's @code{ctp_flags}. + +@node The type section +@section The type section +@cindex Type section +@cindex Sections, type + +This section is the most important section in CTF, describing all the top-level +types in the program. It consists of an array of type structures, each of which +describes a type of some @dfn{kind}: each kind of type has some amount of +variable-length data associated with it (some kinds have none). The amount of +variable-length data associated with a given type can be determined by +inspecting the type, so the reading code can walk through the types in sequence +at opening time. + +Each type structure is one of a set of overlapping structures in a discriminated +union of sorts: the variable-length data for each type immediately follows the +type's type structure. Here's the largest of the overlapping structures, which +is only needed for huge types and so is very rarely seen: + +@verbatim +typedef struct ctf_type +{ + uint32_t ctt_name; + uint32_t ctt_info; + __extension__ + union + { + uint32_t ctt_size; + uint32_t ctt_type; + }; + uint32_t ctt_lsizehi; + uint32_t ctt_lsizelo; +} ctf_type_t; +@end verbatim + +Here's the much more common smaller form: + +@verbatim +typedef struct ctf_stype +{ + uint32_t ctt_name; + uint32_t ctt_info; + __extension__ + union + { + uint32_t ctt_size; + uint32_t ctt_type; + }; +} ctf_type_t; +@end verbatim + +If @code{ctt_size} is the #define @code{CTF_LSIZE_SENT}, 0xffffffff, this type +is described by a @code{ctf_type_t}: otherwise, a @code{ctf_stype_t}. +@tindex CTF_LSIZE_SENT + +Here's what the fields mean: + +@tindex struct ctf_type +@tindex struct ctf_stype +@tindex ctf_type_t +@tindex ctf_stype_t +@multitable {0x1c (@code{ctf_type_t}} {@code{uint32_t ctt_lsizehi}} {The size of this type, if this type is of a kind for} +@headitem Offset @tab Name @tab Description +@item 0x00 +@tab @code{uint32_t ctt_name} +@vindex ctt_name +@tab Strtab offset of the type name, if any (0 if none). + +@item 0x04 +@tab @code{uint32_t ctt_info} +@vindex ctt_info +@vindex struct ctf_type, ctt_info +@vindex ctf_type_t, ctt_info +@vindex struct ctf_stype, ctt_info +@vindex ctf_stype_t, ctt_info +@tab The @dfn{info word}, containing information on the kind of this type, its +variable-length data and whether it is visible to name lookup. See @xref{The +info word}. + +@item 0x08 +@tab @code{uint32_t ctt_size} +@vindex ctt_size +@vindex struct ctf_type, ctt_size +@vindex ctf_type_t, ctt_size +@vindex struct ctf_stype, ctt_size +@vindex ctf_stype_t, ctt_size +@tab The size of this type, if this type is of a kind for which a size needs +to be recorded (constant-size types don't need one). If this is +@code{CTF_LSIZE_SENT}, this type is a huge type described by @code{ctf_type_t}. + +@item 0x08 +@tab @code{uint32_t ctt_type} +@vindex ctt_type +@vindex struct ctf_stype, ctt_type +@vindex ctf_stype_t, ctt_type +@tab The type this type refers to, if this type is of a kind which refers to +other types (like a pointer). All such types are fixed-size, and no types that +are variable-size refer to other types, so @code{ctt_size} and @code{ctt_type} +overlap. All type kinds that use @code{ctt_type} are described by +@code{ctf_stype_t}, not @code{ctf_type_t}. @xref{Type indexes and type IDs}. + +@item 0x0c (@code{ctf_type_t} only) +@tab @code{uint32_t ctt_lsizehi} +@vindex ctt_lsizehi +@vindex struct ctf_type, ctt_lsizehi +@vindex ctf_type_t, ctt_lsizehi +@tab The high 32 bits of the size of a very large type. The @code{CTF_TYPE_LSIZE} macro +can be used to get a 64-bit size out of this field and the next one. +@code{CTF_SIZE_TO_LSIZE_HI} splits the @code{ctt_lsizehi} out of it again. +@findex CTF_TYPE_LSIZE +@findex CTF_SIZE_TO_LSIZE_HI + +@item 0x10 (@code{ctf_type_t} only) +@tab @code{uint32_t ctt_lsizelo} +@vindex ctt_lsizelo +@vindex struct ctf_type, ctt_lsizelo +@vindex ctf_type_t, ctt_lsizelo +@tab The low 32 bits of the size of a very large type. +@code{CTF_SIZE_TO_LSIZE_LO} splits the @code{ctt_lsizelo} out of a 64-bit size. +@findex CTF_SIZE_TO_LSIZE_LO +@end multitable + +Two aspects of this need further explanation: the info word, and what exactly a +type ID is and how you determine it. (Information on the various type-kind- +dependent things, like whether @code{ctt_size} or @code{ctt_type} is used, +is described in the section devoted to each kind.) + +@node The info word +@subsection The info word, ctt_info + +The info word is a bitfield split into three parts. From MSB to LSB: + +@multitable {Bit offset} {@code{isroot}} {Length of variable-length data for this type (some kinds only).} +@headitem Bit offset @tab Name @tab Description +@item 26--31 +@tab @code{kind} +@tab Type kind: @pxref{Type kinds}. + +@item 25 +@tab @code{isroot} +@tab 1 if this type is visible to name lookup + +@item 0--24 +@tab @code{vlen} +@tab Length of variable-length data for this type (some kinds only). +The variable-length data directly follows the @code{ctf_type_t} or +@code{ctf_stype_t}. This is a kind-dependent array length value, +not a length in bytes. Some kinds have no variable-length data, or +fixed-size variable-length data, and do not use this value. +@end multitable + +The most mysterious of these is undoubtedly @code{isroot}. This indicates +whether types with names (nonzero @code{ctt_name}) are visible to name lookup: +if zero, this type is considered a @dfn{non-root type} and you can't look it up +by name at all. Multiple types with the same name in the same C namespace +(struct, union, enum, other) can exist in a single dictionary, but only one of +them may have a nonzero value for @code{isroot}. @code{libctf} validates this +at open time and refuses to open dictionaries that violate this constraint. + +Historically, this feature was introduced for the encoding of bitfields +(@pxref{Integer types}): for instance, int bitfields will all be named +@code{int} with different widths or offsets, but only the full-width one at +offset zero is wanted when you look up the type named @code{int}. With the +introduction of slices (@pxref{Slices}) as a more general bitfield encoding +mechanism, this is less important, but we still use non-root types to handle +conflicts if the linker API is used to fuse multiple translation units into one +dictionary and those translation units contain types with the same name and +conflicting definitions. (We do not discuss this further here, because the +linker never does this: only specialized type mergers do, like that used for the +Linux kernel. The libctf documentation will describe this in more detail.) +@c XXX update when libctf docs are written. + +The @code{CTF_TYPE_INFO} macro can be used to compose an info word from +a @code{kind}, @code{isroot}, and @code{vlen}; @code{CTF_V2_INFO_KIND}, +@code{CTF_V2_INFO_ISROOT} and @code{CTF_V2_INFO_VLEN} pick it apart again. +@findex CTF_TYPE_INFO +@findex CTF_V2_INFO_KIND +@findex CTF_V2_INFO_ISROOT +@findex CTF_V2_INFO_VLEN + +@node Type indexes and type IDs +@subsection Type indexes and type IDs +@cindex Type indexes +@cindex Type IDs +@cindex Type, IDs of +@cindex Type, indexes of +@cindex ctf_id_t + +@cindex Parent range +@cindex Child range +@cindex Type IDs, ranges +Types are referred to within the CTF file via @dfn{type IDs}. A type ID is a +number from 0 to @math{2^32}, from a space divided in half. Types @math{2^31-1} +and below are in the @dfn{parent range}: these IDs are used for dictionaries +that have not had any other dictionary @code{ctf_import}ed into it as a parent. +Both completely standalone dictionaries and parent dictionaries with children +hanging off them have types in this range. Types @math{2^31} and above are in +the @dfn{child range}: only types in child dictionaries are in this range. + +These IDs appear in @code{ctf_type_t.ctt_type} (@pxref{The type section}), but +the types themselves have no visible ID: quite intentionally, because adding an +ID uses space, and every ID is different so they don't compress well. The IDs +are implicit: at open time, the consumer walks through the entire type section +and counts the types in the type section. The type section is an array of +variable-length elements, so each entry could be considered as having an index, +starting from 1. We count these indexes and associate each with its +corresponding @code{ctf_type_t} or @code{ctf_stype_t}. + +Lookups of types with IDs in the parent space look in the parent dictionary if +this dictionary has one associated with it; lookups of types with IDs in the +child space error out if the dictionary does not have a parent, and otherwise +convert the ID into an index by shaving off the top bit and look up the index +in the child. + +These properties mean that the same dictionary can be used as a parent of child +dictionaries and can also be used directly with no children at all, but a +dictionary created as a child dictionary must always be associated with a parent +--- usually, the same parent --- because its references to its own types have +the high bit turned on and this is only flipped off again if this is a child +dictionary. (This is not a problem, because if you @emph{don't} associate the +child with a parent, any references within it to its parent types will fail, and +there are almost certain to be many such references, or why is it a child at +all?) + +This does mean that consumers should keep a close eye on the distinction between +type IDs and type indexes: if you mix them up, everything will appear to work as +long as you're only using parent dictionaries or standalone dictionaries, but as +soon as you start using children, everything will fail horribly. + +Type index zero, and type ID zero, are used to indicate that this type cannot be +represented in CTF as currently constituted: they are emitted by the compiler, +but all type chains that terminate in the unknown type are erased at link time +(structure fields that use them just vanish, etc). So you will probably never +see a use of type zero outside the symtypetab sections, where they serve as +sentinels of sorts, to indicate symbols with no associated type. + +The macros @code{CTF_V2_TYPE_TO_INDEX} and @code{CTF_V2_INDEX_TO_TYPE} may help +in translation between types and indexes: @code{CTF_V2_TYPE_ISPARENT} and +@code{CTF_V2_TYPE_ISCHILD} can be used to tell whether a given ID is in the +parent or child range. +@findex CTF_V2_TYPE_TO_INDEX +@findex CTF_V2_INDEX_TO_TYPE +@findex CTF_V2_TYPE_ISPARENT +@findex CTF_V2_TYPE_ISCHILD + +It is quite possible and indeed common for type IDs to point forward in the +dictionary, as well as backward. + +@node Type kinds +@subsection Type kinds +@cindex Type kinds +@cindex Type, kinds of + +Every type in CTF is of some @dfn{kind}. Each kind is some variety of C type: +all structures are a single kind, as are all unions, all pointers, all arrays, +all integers regardless of their bitfield width, etc. The kind of a type is +given in the @code{kind} field of the @code{ctt_info} word (@pxref{The info +word}). + +The space of type kinds is only a quarter full so far, so there is plenty of +room for expansion. It is likely that in future versions of the file format, +types with smaller kinds will be more efficiently encoded than types with larger +kinds, so their numerical value will actually start to matter in future. (So +these IDs will probably change their numerical values in a later release of this +format, to move more frequently-used kinds like structures and cv-quals towards +the top of the space, and move rarely-used kinds like integers downwards. Yes, +integers are rare: how many kinds of @code{int} are there in a program? They're +just very frequently @emph{referenced}.) + +Here's the set of kinds so far. Each kind has a @code{#define} associated with +it, also given here. + +@multitable {Kind} {@code{CTF_K_VOLATILE}} {Indicates a type that cannot be represented in CTF, or that} {@xref{Pointers typedefs and cvr-quals}} +@headitem Kind @tab Macro @tab Purpose +@item 0 +@tab @code{CTF_K_UNKNOWN} +@tab Indicates a type that cannot be represented in CTF, or that is being skipped. +It is very similar to type ID 0, except that you can have @emph{multiple}, distinct types +of kind @code{CTF_K_UNKNOWN}. +@tindex CTF_K_UNKNOWN + +@item 1 +@tab @code{CTF_K_INTEGER} +@tab An integer type. @xref{Integer types}. + +@item 2 +@tab @code{CTF_K_FLOAT} +@tab A floating-point type. @xref{Floating-point types}. + +@item 3 +@tab @code{CTF_K_POINTER} +@tab A pointer. @xref{Pointers typedefs and cvr-quals}. + +@item 4 +@tab @code{CTF_K_ARRAY} +@tab An array. @xref{Arrays}. + +@item 5 +@tab @code{CTF_K_FUNCTION} +@tab A function pointer. @xref{Function pointers}. + +@item 6 +@tab @code{CTF_K_STRUCT} +@tab A structure. @xref{Structs and unions}. + +@item 7 +@tab @code{CTF_K_UNION} +@tab A union. @xref{Structs and unions}. + +@item 8 +@tab @code{CTF_K_ENUM} +@tab An enumerated type. @xref{Enums}. + +@item 9 +@tab @code{CTF_K_FORWARD} +@tab A forward. @xref{Forward declarations}. + +@item 10 +@tab @code{CTF_K_TYPEDEF} +@tab A typedef. @xref{Pointers typedefs and cvr-quals}. + +@item 11 +@tab @code{CTF_K_VOLATILE} +@tab A volatile-qualified type. @xref{Pointers typedefs and cvr-quals}. + +@item 12 +@tab @code{CTF_K_CONST} +@tab A const-qualified type. @xref{Pointers typedefs and cvr-quals}. + +@item 13 +@tab @code{CTF_K_RESTRICT} +@tab A restrict-qualified type. @xref{Pointers typedefs and cvr-quals}. + +@item 14 +@tab @code{CTF_K_SLICE} +@tab A slice, a change of the bit-width or offset of some other type. @xref{Slices}. +@end multitable + +Now we cover all type kinds in turn. Some are more complicated than others. + +@node Integer types +@subsection Integer types +@cindex Integer types +@cindex Types, integer +@tindex int +@tindex long +@tindex long long +@tindex short +@tindex char +@tindex bool +@tindex unsigned int +@tindex unsigned long +@tindex unsigned long long +@tindex unsigned short +@tindex unsigned char +@tindex signed int +@tindex signed long +@tindex signed long long +@tindex signed short +@tindex signed char +@cindex CTF_K_INTEGER + +Integral types are all represented as types of kind @code{CTF_K_INTEGER}. These +types fill out @code{ctt_size} in the @code{ctf_stype_t} with the size in bytes +of the integral type in question. They are always represented by +@code{ctf_stype_t}, never @code{ctf_type_t}. Their variable-length data is one +@code{uint32_t} in length: @code{vlen} in the info word should be disregarded +and is always zero. + +The variable-length data for integers has multiple items packed into it much +like the info word does. + +@multitable {Bit offset} {Encoding} {The integer encoding and desired display representation.} +@headitem Bit offset @tab Name @tab Description +@item 24--31 +@tab Encoding +@tab The desired display representation of this integer. You can extract this +field with the @code{CTF_INT_ENCODING} macro. See below. +@findex CTF_INT_ENCODING + +@item 16--23 +@tab Offset +@tab The offset of this integral type in bits from the start of its enclosing +structure field, adjusted for endianness: @pxref{Structs and unions}. You can +extract this field with the @code{CTF_INT_OFFSET} macro. +@findex CTF_INT_OFFSET + +@item 0--15 +@tab Bit-width +@tab The width of this integral type in bits. You can extract this field with +the @code{CTF_INT_BITS} macro. +@findex CTF_INT_BITS +@end multitable + +If you choose, bitfields can be represented using the things above as a sort of +integral type with the @code{isroot} bit flipped off and the offset and bits +values set in the vlen word: you can populate it with the @code{CTF_INT_DATA} +macro. (But it may be more convenient to represent them using slices of a +full-width integer: @pxref{Slices}.) +@findex CTF_INT_DATA + +Integers that are bitfields usually have a @code{ctt_size} rounded up to the +nearest power of two in bytes, for natural alignment (e.g. a 17-bit integer +would have a @code{ctt_size} of 4). However, not all types are naturally +aligned on all architectures: packed structures may in theory use integral +bitfields with different @code{ctt_size}, though this is rarely observed. + +The @dfn{encoding} for integers is a bit-field comprised of the values below, +which consumers can use to decide how to display values of this type: + +@multitable {Offset} {@code{CTF_INT_VARARGS}} {If set, this is a char type. It is platform-dependent whether unadorned} +@headitem Offset @tab Name @tab Description +@item 0x01 +@tab @code{CTF_INT_SIGNED} +@tab If set, this is a signed int: if false, unsigned. +@tindex CTF_INT_SIGNED + +@item 0x02 +@tab @code{CTF_INT_CHAR} +@tab If set, this is a char type. It is platform-dependent whether unadorned +@code{char} is signed or not: the @code{CTF_CHAR} macro produces an integral +type suitable for the definition of @code{char} on this platform. +@tindex CTF_INT_CHAR +@findex CTF_CHAR + +@item 0x04 +@tab @code{CTF_INT_BOOL} +@tab If set, this is a boolean type. (It is theoretically possible to turn this +and @code{CTF_INT_CHAR} on at the same time, but it is not clear what this would +mean.) +@tindex CTF_INT_BOOL + +@item 0x08 +@tab @code{CTF_INT_VARARGS} +@tab If set, this is a varargs-promoted value in a K&R function definition. +This is not currently produced or consumed by anything that we know of: it is set +aside for future use. +@end multitable + +The GCC ``@code{Complex int}'' and fixed-point extensions are not yet supported: +references to such types will be emitted as type 0. + +@node Floating-point types +@subsection Floating-point types +@cindex Floating-point types +@cindex Types, floating-point +@tindex float +@tindex double +@tindex signed float +@tindex signed double +@tindex unsigned float +@tindex unsigned double +@tindex Complex, float +@tindex Complex, double +@tindex Complex, signed float +@tindex Complex, signed double +@tindex Complex, unsigned float +@tindex Complex, unsigned double +@cindex CTF_K_FLOAT + +Floating-point types are all represented as types of kind @code{CTF_K_FLOAT}. +Like integers, These types fill out @code{ctt_size} in the @code{ctf_stype_t} +with the size in bytes of the floating-point type in question. They are always +represented by @code{ctf_stype_t}, never @code{ctf_type_t}. + +This part of CTF shows many rough edges in the more obscure corners of +floating-point handling, and is likely to change in format v4. + +The variable-length data for floats has multiple items packed into it just like +integers do: + +@multitable {Bit offset} {Encoding} {The floating-;point encoding and desired display representation.} +@headitem Bit offset @tab Name @tab Description +@item 24--31 +@tab Encoding +@tab The desired display representation of this float. You can extract this +field with the @code{CTF_FP_ENCODING} macro. See below. +@findex CTF_FP_ENCODING + +@item 16--23 +@tab Offset +@tab The offset of this floating-point type in bits from the start of its enclosing +structure field, adjusted for endianness: @pxref{Structs and unions}. You can +extract this field with the @code{CTF_FP_OFFSET} macro. +@findex CTF_FP_OFFSET + +@item 0--15 +@tab Bit-width +@tab The width of this floating-point type in bits. You can extract this field with +the @code{CTF_FP_BITS} macro. +@findex CTF_FP_BITS +@end multitable + +The purpose of the floating-point offset and bit-width is somewhat opaque, since +there are no such things as floating-point bitfields in C: the bit-width should +be filled out with the full width of the type in bits, and the offset should +always be zero. It is likely that these fields will go away in the future. As +with integers, you can use @code{CTF_FP_DATA} to assemble one of these vlen +items from its component parts. +@findex CTF_INT_DATA + +The @dfn{encoding} for floats is not a bitfield but a simple value indicating +the display representation. Many of these are unused, relate to +Solaris-specific compiler extensions, and will be recycled in future: some are +unused and will become used in future. + +@multitable {Offset} {@code{CTF_FP_LDIMAGRY}} {This is a @code{float} interval type, a Solaris-specific extension.} +@headitem Offset @tab Name @tab Description +@item 1 +@tab @code{CTF_FP_SINGLE} +@tab This is a single-precision IEEE 754 @code{float}. +@tindex CTF_FP_SINGLE +@item 2 +@tab @code{CTF_FP_DOUBLE} +@tab This is a double-precision IEEE 754 @code{double}. +@tindex CTF_FP_DOUBLE +@item 3 +@tab @code{CTF_FP_CPLX} +@tab This is a @code{Complex float}. +@tindex CTF_FP_CPLX +@item 4 +@tab @code{CTF_FP_DCPLX} +@tab This is a @code{Complex double}. +@tindex CTF_FP_DCPLX +@item 5 +@tab @code{CTF_FP_LDCPLX} +@tab This is a @code{Complex long double}. +@tindex CTF_FP_LDCPLX +@item 6 +@tab @code{CTF_FP_LDOUBLE} +@tab This is a @code{long double}. +@tindex CTF_FP_LDOUBLE +@item 7 +@tab @code{CTF_FP_INTRVL} +@tab This is a @code{float} interval type, a Solaris-specific extension. +Unused: will be recycled. +@tindex CTF_FP_INTRVL +@cindex Unused bits +@item 8 +@tab @code{CTF_FP_DINTRVL} +@tab This is a @code{double} interval type, a Solaris-specific extension. +Unused: will be recycled. +@tindex CTF_FP_DINTRVL +@cindex Unused bits +@item 9 +@tab @code{CTF_FP_LDINTRVL} +@tab This is a @code{long double} interval type, a Solaris-specific extension. +Unused: will be recycled. +@tindex CTF_FP_LDINTRVL +@cindex Unused bits +@item 10 +@tab @code{CTF_FP_IMAGRY} +@tab This is a the imaginary part of a @code{Complex float}. Not currently +generated. May change. +@tindex CTF_FP_IMAGRY +@cindex Unused bits +@item 11 +@tab @code{CTF_FP_DIMAGRY} +@tab This is a the imaginary part of a @code{Complex double}. Not currently +generated. May change. +@tindex CTF_FP_DIMAGRY +@cindex Unused bits +@item 12 +@tab @code{CTF_FP_LDIMAGRY} +@tab This is a the imaginary part of a @code{Complex long double}. Not currently +generated. May change. +@tindex CTF_FP_LDIMAGRY +@cindex Unused bits +@end multitable + +The use of the complex floating-point encodings is obscure: it is possible that +@code{CTF_FP_CPLX} is meant to be used for only the real part of complex types, +and @code{CTF_FP_IMAGRY} et al for the imaginary part -- but for now, we are +emitting @code{CTF_FP_CPLX} to cover the entire type, with no way to get at its +constituent parts. There appear to be no uses of these encodings anywhere, so +they are quite likely to change incompatibly in future. + +@node Slices +@subsection Slices +@cindex Slices +@cindex Types, slices of integral +@tindex CTF_K_SLICE + +Slices, with kind @code{CTF_K_SLICE}, are an unusual CTF construct: they do not +directly correspond to any C type, but are a way to model other types in a more +convenient fashion for CTF generators. + +A slice is like a pointer or other reference type in that they are always +represented by @code{ctf_stype_t}: but unlike pointers and other reference +types, they populate the @code{ctt_size} field just like integral types do, and +come with an attached encoding and transform the encoding of the underlying +type. The underlying type is described in the variable-length data, similarly +to structure and union fields: see below. Requests for the type size should +also chase down to the referenced type. + +Slices are always nameless: @code{ctt_name} is always zero for them. + +(The @code{libctf} API behaviour is unusual as well, and justifies the existence +of slices: @code{ctf_type_kind} never returns @code{CTF_K_SLICE} but always the +underlying type kind, so that consumers never need to know about slices: they +can tell if an apparent integer is actually a slice if they need to by calling +@code{ctf_type_reference}, which will uniquely return the underlying integral +type rather than erroring out with @code{ECTF_NOTREF} if this is actually a +slice. So slices act just like an integer with an encoding, but more closely +mirror DWARF and other debugging information formats by allowing CTF file +creators to represent a bitfield as a slice of an underlying integral type.) +@findex Slices, effect on ctf_type_kind +@findex Slices, effect on ctf_type_reference +@findex libctf, effect of slices + +The vlen in the info word for a slice should be ignored and is always zero. The +variable-length data for a slice is a single @code{ctf_slice_t}: + +@verbatim +typedef struct ctf_slice +{ + uint32_t cts_type; + unsigned short cts_offset; + unsigned short cts_bits; +} ctf_slice_t; +@end verbatim + +@tindex struct ctf_slice +@tindex ctf_slice_t +@multitable {Offset} {@code{unsigned short cts_offset}} {The type this slice is a slice of. Must be an} +@headitem Offset @tab Name @tab Description +@item 0x0 +@tab @code{uint32_t cts_type} +@vindex cts_type +@vindex struct ctf_slice, cts_type +@vindex ctf_slice_t, cts_type +@tab The type this slice is a slice of. Must be an integral type (or a +floating-point type, but this nonsensical option will go away in v4.) + +@item 0x4 +@tab @code{unsigned short cts_offset} +@vindex cts_offset +@vindex struct ctf_slice, cts_offset +@vindex ctf_slice_t, cts_offset +@tab The offset of this integral type in bits from the start of its enclosing +structure field, adjusted for endianness: @pxref{Structs and unions}. Identical +semantics to the @code{CTF_INT_OFFSET} field: @pxref{Integer types}. This field +is much too long, because the maximum possible offset of an integral type would +easily fit in a char: this field is bigger just for the sake of alignment. This +will change in v4. + +@item 0x6 +@tab @code{unsigned short cts_bits} +@vindex cts_bits +@vindex struct ctf_slice, cts_bits +@vindex ctf_slice_t, cts_bits +@tab The bit-width of this integral type. Identical semantics to the +@code{CTF_INT_BITS} field: @pxref{Integer types}. As above, this field is +really too large and will shrink in v4. +@end multitable + +@node Pointers typedefs and cvr-quals +@subsection Pointers, typedefs, and cvr-quals +@cindex Pointers +@cindex Typedefs +@cindex cvr-quals +@tindex typedef +@tindex const +@tindex volatile +@tindex restrict +@tindex CTF_K_POINTER +@tindex CTF_K_TYPEDEF +@tindex CTF_K_CONST +@tindex CTF_K_VOLATILE +@tindex CTF_K_RESTRICT + +Pointers, @code{typedef}s, and @code{const}, @code{volatile} and @code{restrict} +qualifiers are represented identically except for their type kind (though they +may be treated differently by consuming libraries like @code{libctf}, since +pointers affect assignment-compatibility in ways cvr-quals do not, and they may +have different alignment requirements, etc). + +All of these are represented by @code{ctf_stype_t}, have no variable data at +all, and populate @code{ctt_type} with the type ID of the type they point +to. These types can stack: a @code{CTF_K_RESTRICT} can point to a +@code{CTF_K_CONST} which can point to a @code{CTF_K_POINTER} etc. + +They are all unnamed: @code{ctt_name} is 0. + +The size of @code{CTF_K_POINTER} is derived from the data model (@pxref{Data +models}), i.e. in practice, from the target machine ABI, and is not explicitly +represented. The size of other kinds in this set should be determined by +chasing ctf_types as necessary until a non-typedef/const/volatile/restrict is +found, and using that. + +@node Arrays +@subsection Arrays +@cindex Arrays + +Arrays are encoded as types of kind @code{CTF_K_ARRAY} in a @code{ctf_stype_t}. +Both size and kind for arrays are zero. The variable-length data is a +@code{ctf_array_t}: @code{vlen} in the info word should be disregarded and is +always zero. + +@verbatim +typedef struct ctf_array +{ + uint32_t cta_contents; + uint32_t cta_index; + uint32_t cta_nelems; +} ctf_array_t; +@end verbatim + +@tindex struct ctf_array +@tindex ctf_array_t +@multitable {Offset} {@code{unsigned short cta_contents}} {The type of the array index: a type ID of an} +@headitem Offset @tab Name @tab Description +@item 0x0 +@tab @code{uint32_t cta_contents} +@vindex cta_contents +@vindex struct ctf_array, cta_contents +@vindex ctf_array_t, cta_contents +@tab The type of the array elements: a type ID. + +@item 0x4 +@tab @code{uint32_t cta_index} +@vindex cta_index +@vindex struct ctf_array, cta_index +@vindex ctf_array_t, cta_index +@tab The type of the array index: a type ID of an integral type. +If this is a variable-length array, the index type ID will be 0 +(but the actual index type of this array is probably @code{int}). +Probably redundant and may be dropped in v4. + +@item 0x8 +@tab @code{uint32_t cta_nelems} +@vindex cta_nelems +@vindex struct ctf_array, cta_nelems +@vindex ctf_array_t, cta_nelems +@tab The number of array elements. 0 for VLAs, and also for +the historical variety of VLA which has explicit zero dimensions (which will +have a nonzero @code{cta_index}.) +@end multitable + +The size of an array can be computed by simple multiplication of the size of the +@code{cta_contents} type by the @code{cta_nelems}. + +@node Function pointers +@subsection Function pointers +@cindex Function pointers +@cindex Pointers, to functions + +Function pointers are explicitly represented in the CTF type section by a type +of kind @code{CTF_K_FUNCTION}, always encoded with a @code{ctf_stype_t}. The +@code{ctt_type} is the function return type ID. The @code{vlen} in the info +word is the number of arguments, each of which is a type ID, a @code{uint32_t}: +if the last argument is 0, this is a varargs function and the number of +arguments is one less than indicated by the vlen. + +If the number of arguments is odd, a single @code{uint32_t} of padding is +inserted to maintain alignment. + +@node Enums +@subsection Enums +@cindex Enums +@tindex enum +@tindex CTF_K_ENUM + +Enumerated types are represented as types of kind @code{CTF_K_ENUM} in a +@code{ctf_stype_t}. The @code{ctt_size} is always the size of an int from the +data model (enum bitfields are implemented via slices). The @code{vlen} is a +count of enumerations, each of which is represented by a @code{ctf_enum_t} in +the vlen: + +@verbatim +typedef struct ctf_enum +{ + uint32_t cte_name; + int32_t cte_value; +} ctf_enum_t; +@end verbatim + +@tindex struct ctf_enum +@tindex ctf_enum_t +@multitable {Offset} {@code{int32_t cte_value}} {Strtab offset of the enumeration name.} +@headitem Offset @tab Name @tab Description +@item 0x0 +@tab @code{uint32_t cte_name} +@vindex cte_name +@vindex struct ctf_enum, cte_name +@vindex ctf_enum_t, cte_name +@tab Strtab offset of the enumeration name. Must not be 0. + +@item 0x4 +@tab @code{int32_t cte_value} +@vindex cte_value +@vindex struct ctf_enum, cte_value +@vindex ctf_enum_t, cte_value +@tab The enumeration value. + +@end multitable + +Enumeration values larger than @math{2^32} are not yet supported and are omitted +from the enumeration. (v4 will lift this restriction by encoding the value +differently.) + +Forward declarations of enums are not implemented with this kind: @pxref{Forward +declarations}. + +Enumerated type names, as usual in C, go into their own namespace, and do not +conflict with non-enums, structs, or unions with the same name. + +@node Structs and unions +@subsection Structs and unions +@cindex Structures +@cindex Unions +@tindex struct +@tindex union +@tindex CTF_K_STRUCT +@tindex CTF_K_UNION + +Structures and unions are represnted as types of kind @code{CTF_K_STRUCT} and +@code{CTF_K_UNION}: their representation is otherwise identical, and it is +perfectly allowed for ``structs'' to contain overlapping fields etc, so we will +treat them together for the rest of this section. + +They fill out @code{ctt_size}, and use @code{ctf_type_t} in preference to +@code{ctf_stype_t} if the structure size is greater than @code{CTF_MAX_SIZE} +(0xfffffffe). +@tindex CTF_MAX_LSIZE + +The vlen for structures and unions is a count of structure fields, but the type +used to represent a structure field (and thus the size of the variable-length +array element representing the type) depends on the size of the structure: truly +huge structures, greater than @code{CTF_LSTRUCT_THRESH} bytes in length, use a +different type. (@code{CTF_LSTRUCT_THRESH} is 536870912, so such structures are +vanishingly rare: in v4, this representation will change somewhat for greater +compactness. It's inherited from v1, where the limits were much lower.) +@tindex CTF_LSTRUCT_THRESH + +Most structures can get away with using @code{ctf_member_t}: + +@verbatim +typedef struct ctf_member_v2 +{ + uint32_t ctm_name; + uint32_t ctm_offset; + uint32_t ctm_type; +} ctf_member_t; +@end verbatim + +Huge structures that are represented by @code{ctf_type_t} rather than +@code{ctf_stype_t} have to use @code{ctf_lmember_t}, which splits the offset as +@code{ctf_type_t} splits the size: + +@verbatim +typedef struct ctf_lmember_v2 +{ + uint32_t ctlm_name; + uint32_t ctlm_offsethi; + uint32_t ctlm_type; + uint32_t ctlm_offsetlo; +} ctf_lmember_t; +@end verbatim + +Here's what the fields of @code{ctf_member} mean: + +@tindex struct ctf_member_v2 +@tindex ctf_member_t +@multitable {Offset} {@code{uint32_t ctm_offset}} {The offset of this field @emph{in bits}. (Usually, for bitfields, this is} +@headitem Offset @tab Name @tab Description +@item 0x00 +@tab @code{uint32_t ctm_name} +@vindex ctm_name +@vindex struct ctf_member_v2, ctm_name +@vindex ctf_member_t, ctm_name +@tab Strtab offset of the field name. + +@item 0x04 +@tab @code{uint32_t ctm_offset} +@vindex ctm_offset +@vindex struct ctf_member_v2, ctm_offset +@vindex ctf_member_t, ctm_offset +@tab The offset of this field @emph{in bits}. (Usually, for bitfields, this is +machine-word-aligned and the individual field has an offset in bits, but +the format allows for the offset to be encoded in bits here.) + +@item 0x08 +@tab @code{uint32_t ctm_type} +@vindex ctm_type +@vindex struct ctf_member_v2, ctm_type +@vindex ctf_member_t, ctm_type +@tab The type ID of the type of the field. +@end multitable + +Here's what the fields of the very similar @code{ctf_lmember} mean: + +@tindex struct ctf_lmember_v2 +@tindex ctf_lmember_t +@multitable {Offset} {@code{uint32_t ctlm_offsethi}} {The offset of this field @emph{in bits}. (Usually, for bitfields, this is} +@headitem Offset @tab Name @tab Description +@item 0x00 +@tab @code{uint32_t ctlm_name} +@vindex ctlm_name +@vindex struct ctf_lmember_v2, ctlm_name +@vindex ctf_lmember_t, ctlm_name +@tab Strtab offset of the field name. + +@item 0x04 +@tab @code{uint32_t ctlm_offsethi} +@vindex ctlm_offsethi +@vindex struct ctf_lmember_v2, ctlm_offsethi +@vindex ctf_lmember_t, ctlm_offsethi +@tab The high 32 bits of the offset of this field in bits. + +@item 0x08 +@tab @code{uint32_t ctlm_type} +@vindex ctm_type +@vindex struct ctf_lmember_v2, ctlm_type +@vindex ctf_member_t, ctlm_type +@tab The type ID of the type of the field. + +@item 0x0c +@tab @code{uint32_t ctlm_offsetlo} +@vindex ctlm_offsetlo +@vindex struct ctf_lmember_v2, ctlm_offsetlo +@vindex ctf_lmember_t, ctlm_offsetlo +@tab The low 32 bits of the offset of this field in bits. +@end multitable + +Macros @code{CTF_LMEM_OFFSET}, @code{CTF_OFFSET_TO_LMEMHI} and +@code{CTF_OFFSET_TO_LMEMLO} serve to extract and install the values of the +@code{ctlm_offset} fields, much as with the split size fields in +@code{ctf_type_t}. + +Unnamed structure and union fields are simply implemented by collapsing the +unnamed field's members into the containing structure or union: this does mean +that a structure containing an unnamed union can end up being a ``structure'' +with multiple members at the same offset. (A future format revision may +collapse @code{CTF_K_STRUCT} and @code{CTF_K_UNION} into the same kind and +decide among them based on whether their members do in fact overlap.) + +Structure and union type names, as usual in C, go into their own namespace, +just as enum type names do. + +Forward declarations of structures and unions are not implemented with this +kind: @pxref{Forward declarations}. + +@node Forward declarations +@subsection Forward declarations +@cindex Forwards +@tindex enum +@tindex struct +@tindex union +@tindex CTF_K_FORWARD + +When the compiler encounters a forward declaration of a struct, union, or enum, +it emits a type of kind @code{CTF_K_FORWARD}. If it later encounters a non- +forward declaration of the same thing, it marks the forward as non-root-visible: +before link time, therefore, non-root-visible forwards indicate that a +non-forward is coming. + +After link time, forwards are fused with their corresponding non-forwards by the +deduplicator where possible. They are kept if there is no non-forward +definition (maybe it's not visible from any TU at all) or if @code{multiple} +conflicting structures with the same name might match it. Otherwise, all other +forwards are converted to structures, unions, or enums as appropriate, even +across TUs if only one structure could correspond to the forward (after all, +all types across all TUs land in the same dictionary unless they conflict, +so promoting forwards to their concrete type seems most helpful). + +A forward has a rather strange representation: it is encoded with a +@code{ctf_stype_t} but the @code{ctt_type} is populated not with a type (if it's +a forward, we don't have an underlying type yet: if we did, we'd have promoted +it and this wouldn't be a forward any more) but with the @code{kind} of the +forward. This means that we can distinguish forwards to structs, enums and +unions reliably and ensure they land in the appropriate namespace even before +the actual struct, union or enum is found. + +@node The symtypetab sections +@section The symtypetab sections +@cindex Symtypetab section +@cindex Sections, symtypetab +@cindex Function info section +@cindex Sections, function info +@cindex Data object section +@cindex Sections, data object +@cindex Function info index section +@cindex Sections, function info index +@cindex Data object index section +@cindex Sections, data object index +@tindex CTF_F_IDXSORTED +@tindex CTF_F_DYNSTR +@cindex Bug workarounds, CTF_F_DYNSTR + +These are two very simple sections with identical formats, used by consumers to +map from ELF function and data symbols directly to their types. So they are +usually populated only in CTF sections that are embedded in ELF objects. + +Their format is very simple: an array of type IDs. Which symbol each type ID +corresponds to depends on whether the optional @emph{index section} associated +with this symtypetab section has any content. + +If the index section is nonempty, it is an array of @code{uint32_t} string table +offsets, each giving the name of the symbol whose type is at the same offset in +the corresponding non-index section: users can look up symbols in such a table +by name. The index section and corresponding symtypetab section is usually +ASCIIbetically sorted (indicated by the @code{CTF_F_IDXSORTED} flag in the +header): if it's sorted, it can be bsearched for a symbol name rather than +having to use a slower linear search. + +If the data object index section is empty, the entries in the data object and +function info sections are associated 1:1 with ELF symbols of type +@code{STT_OBJECT} (for data object) or @code{STT_FUNC} (for function info) with +a nonzero value: the linker shuffles the symtypetab sections to correspond with +the order of the symbols in the ELF file. Symbols with no name, undefined +symbols and symbols named ``@code{_START_}'' and ``@code{_END_}'' are skipped +and never appear in either section. Symbols that have no corresponding type are +represented by type ID 0. The section may have fewer entries than the symbol +table, in which case no later entries have associated types. This format is +more compact than an indexed form if most entries have types (since there is no +need to record any symbol names), but if the producer and consumer disagree even +slightly about which symbols are omitted, the types of all further symbols will +be wrong! + +The compiler always emits indexed symtypetab tables, because there is no symbol +table yet. The linker will always have to read them all in and always works +through them from start to end, so there is no benefit having the compiler sort +them either. The linker (actually, @code{libctf}'s linking machinery) will +automatically sort unsorted indexed sections, and convert indexed sections that +contain a lot of pads into the more compact, unindexed form. + +If child dicts are in use, only symbols that use types actually mentioned in the +child appear in the child's symtypetab: symbols that use only types in the +parent appear in the parent's symtypetab instead. So the child's symtypetab will +almost always be very sparse, and thus will usually use the indexed form even in +fully linked objects. (It is, of course, impossible for symbols to exist that +use types from multiple child dicts at once, since it's impossible to declare a +function in C that uses types that are only visible in two different, disjoint +translation units.) + +@node The variable section +@section The variable section +@cindex Variable section +@cindex Sections, variable + +The variable section is a simple array mapping names (strtab entries) to type +IDs, intended to provide a replacement for the data object section in dynamic +situations in which there is no static ELF strtab but the consumer instead hands +back names. The section is sorted into ASCIIbetical order by name for rapid +lookup, like the CTF archive name table. + +The section is an array of these structures: + +@verbatim +typedef struct ctf_varent +{ + uint32_t ctv_name; + uint32_t ctv_type; +} ctf_varent_t; +@end verbatim + +@tindex struct ctf_varent +@tindex ctf_varent_t +@multitable {Offset} {@code{uint32_t ctv_name}} {Strtab offset of the name} +@headitem Offset @tab Name @tab Description +@item 0x00 +@tab @code{uint32_t ctv_name} +@vindex ctv_name +@vindex struct ctf_varent, ctv_name +@vindex ctf_varent_t, ctv_name +@tab Strtab offset of the name + +@item 0x04 +@tab @code{uint32_t ctv_type} +@vindex ctv_type +@vindex struct ctf_varent, ctv_type +@vindex ctf_varent_t, ctv_type +@tab Type ID of this type +@end multitable + +There is no analogue of the function info section yet: v4 will probably drop +this section in favour of a way to put both indexed (thus, named) and nonindexed +symbols into the symtypetab sections at the same time. + +@node The label section +@section The label section +@cindex Label section +@cindex Sections, label + +The label section is a currently-unused facility allowing the tiling of the type +space with names taken from the strtab. The section is an array of these +structures: + +@verbatim +typedef struct ctf_lblent +{ + uint32_t ctl_label; + uint32_t ctl_type; +} ctf_lblent_t; +@end verbatim + +@tindex struct ctf_lblent +@tindex ctf_lblent_t +@multitable {Offset} {@code{uint32_t ctl_label}} {Strtab offset of the label} +@headitem Offset @tab Name @tab Description +@item 0x00 +@tab @code{uint32_t ctl_label} +@vindex ctl_label +@vindex struct ctf_lblent, ctl_label +@vindex ctf_lblent_t, ctl_label +@tab Strtab offset of the label + +@item 0x04 +@tab @code{uint32_t ctl_type} +@vindex ctl_type +@vindex struct ctf_lblent, ctl_type +@vindex ctf_lblent_t, ctl_type +@tab Type ID of the last type covered by this label +@end multitable + +Semantics will be attached to labels soon, probably in v4 (the plan is to use +them to allow multiple disjoint namespaces in a single CTF file, removing many +uses of CTF archives, in particular in the @code{.ctf} section in ELF objects). + +@node The string section +@section The string section +@cindex String section +@cindex Sections, string + +This section is a simple ELF-format strtab, starting with a zero byte (thus +ensuring that the string with offset 0 is the null string, as assumed elsewhere +in this spec). The strtab is usually ASCIIbetically sorted to somewhat improve +compression efficiency. + +Where the strtab is unusual is the @emph{references} to it. CTF has two +string tables, the internal strtab and an external strtab associated +with the CTF dictionary at open time: usually, this is the ELF dynamic +strtab (@code{.dynstr}) of a CTF dictionary embedded in an ELF file. We +distinguish between these strtabs by the most significant bit, bit 31, +of the 32-bit strtab references: if it is 0, the offset is in the +internal strtab: if 1, the offset is in the external strtab. + +@tindex CTF_F_DYNSTR +@cindex Bug workarounds, CTF_F_DYNSTR +There is a bug workaround in this area: in format v3 (the first version +to have working support for external strtabs), the external strtab is +@code{.strtab} unless the @code{CTF_F_DYNSTR} flag is set on the +dictionary (@pxref{CTF file-wide flags}). Format v4 will introduce a +header field that explicitly names the external strtab, making this flag +unnecessary. + +@node Data models +@section Data models +@cindex Data models + +The data model is a simple integer which indicates the ABI in use on this +platform. Right now, it is very simple, distinguishing only between 32- and +64-bit types: a model of 1 indicates ILP32, 2 indicats LP64. The mapping from +ABI integer to type sizes is hardwired into @code{libctf}: currently, we use +this to hardwire the size of pointers, function pointers, and enumerated types, + +This is a very kludgy corner of CTF and will probably be replaced with explicit +header fields to record this sort of thing in future. + +@node Limits of CTF +@section Limits of CTF +@cindex Limits + +The following limits are imposed by various aspects of CTF version 3: + +@table @code +@item CTF_MAX_TYPE +Maximum type identifier (maximum number of types accessible with parent and +child containers in use): 0xfffffffe +@item CTF_MAX_PTYPE +Maximum type identifier in a parent dictioanry: maximum number of types in any +one dictionary: 0x7fffffff +@item CTF_MAX_NAME +Maximum offset into a string table: 0x7fffffff +@item CTF_MAX_VLEN +Maximum number of members in a struct, union, or enum: maximum number of +function args: 0xffffff +@item CTF_MAX_SIZE +Maximum size of a @code{ctf_stype_t} in bytes before we fall back to +@code{ctf_type_t}: 0xfffffffe bytes +@end table + +Other maxima without associated macros: +@itemize +@item +Maximum value of an enumerated type: 2^32 +@item +Maximum size of an array element: 2^32 +@end itemize + +These maxima are generally considered to be too low, because C programs can and +do exceed them: they will be lifted in format v4. + +@node Index +@unnumbered Index + +@printindex cp + +@bye |