From: Indu Bhagat Date: Tue, 15 Nov 2022 23:07:28 +0000 (-0800) Subject: doc: add SFrame spec file X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=c1c57352f56b802393453cfa76326922fd8da2f9;p=binutils-gdb.git doc: add SFrame spec file ChangeLog: * libsframe/Makefile.am: Add info-in-builddir to AUTOMAKE_OPTIONS. Include doc/local.mk. * libsframe/Makefile.in: Regenerated. * libsframe/configure: Likewise. * libsframe/configure.ac: Check for makeinfo and set BUILD_INFO. * libsframe/doc/local.mk: New file. * libsframe/doc/sframe-spec.texi: Likewise. --- diff --git a/libsframe/Makefile.am b/libsframe/Makefile.am index d8198a166c5..a976a7e6090 100644 --- a/libsframe/Makefile.am +++ b/libsframe/Makefile.am @@ -18,7 +18,12 @@ # ACLOCAL_AMFLAGS = -I .. -I ../config -I ../bfd -AUTOMAKE_OPTIONS = dejagnu foreign no-texinfo.tex subdir-objects +AUTOMAKE_OPTIONS = dejagnu foreign no-texinfo.tex info-in-builddir subdir-objects + +# Variables that we might accumulate conditionally or in subdirs. +info_TEXINFOS = +DISTCLEANFILES = +MAINTAINERCLEANFILES = INCDIR = $(srcdir)/../include # include libctf for swap.h @@ -36,4 +41,6 @@ endif libsframe_la_SOURCES = sframe.c sframe-dump.c sframe-error.c libsframe_la_CPPFLAGS = $(AM_CPPFLAGS) +include doc/local.mk + include testsuite/local.mk diff --git a/libsframe/Makefile.in b/libsframe/Makefile.in index 340bfe88060..8622d8bb688 100644 --- a/libsframe/Makefile.in +++ b/libsframe/Makefile.in @@ -14,6 +14,24 @@ @SET_MAKE@ +# +# Copyright (C) 2019-2022 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 +# . +# + VPATH = @srcdir@ am__is_gnu_make = { \ @@ -89,8 +107,11 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ +@BUILD_INFO_TRUE@am__append_1 = doc/sframe-spec.texi +@BUILD_INFO_TRUE@am__append_2 = texput.log +@BUILD_INFO_TRUE@am__append_3 = doc/sframe-spec.info check_PROGRAMS = $(am__EXEEXT_1) -@HAVE_COMPAT_DEJAGNU_TRUE@am__append_1 = testsuite/libsframe.decode/be-flipping \ +@HAVE_COMPAT_DEJAGNU_TRUE@am__append_4 = testsuite/libsframe.decode/be-flipping \ @HAVE_COMPAT_DEJAGNU_TRUE@ testsuite/libsframe.decode/frecnt-1 \ @HAVE_COMPAT_DEJAGNU_TRUE@ testsuite/libsframe.decode/frecnt-2 \ @HAVE_COMPAT_DEJAGNU_TRUE@ testsuite/libsframe.encode/encode-1 @@ -145,7 +166,8 @@ am__uninstall_files_from_dir = { \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } -am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)" +am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(infodir)" \ + "$(DESTDIR)$(includedir)" LTLIBRARIES = $(lib_LTLIBRARIES) $(noinst_LTLIBRARIES) libsframe_la_LIBADD = am_libsframe_la_OBJECTS = libsframe_la-sframe.lo \ @@ -226,6 +248,46 @@ DIST_SOURCES = $(libsframe_la_SOURCES) \ $(testsuite_libsframe_decode_frecnt_1_SOURCES) \ $(testsuite_libsframe_decode_frecnt_2_SOURCES) \ $(testsuite_libsframe_encode_encode_1_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 = doc/sframe-spec.info +am__TEXINFO_TEX_DIR = $(srcdir) +DVIS = doc/sframe-spec.dvi +PDFS = doc/sframe-spec.pdf +PSS = doc/sframe-spec.ps +HTMLS = doc/sframe-spec.html +TEXINFOS = $(am__append_1) +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;; \ @@ -258,6 +320,7 @@ AM_RECURSIVE_TARGETS = cscope DEJATOOL = $(PACKAGE) RUNTESTDEFAULTFLAGS = --tool $$tool --srcdir $$srcdir am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in \ + $(srcdir)/doc/local.mk \ $(srcdir)/testsuite/libsframe.decode/local.mk \ $(srcdir)/testsuite/libsframe.encode/local.mk \ $(srcdir)/testsuite/local.mk $(top_srcdir)/../ar-lib \ @@ -418,7 +481,12 @@ top_srcdir = @top_srcdir@ # . # ACLOCAL_AMFLAGS = -I .. -I ../config -I ../bfd -AUTOMAKE_OPTIONS = dejagnu foreign no-texinfo.tex subdir-objects +AUTOMAKE_OPTIONS = dejagnu foreign no-texinfo.tex info-in-builddir subdir-objects + +# Variables that we might accumulate conditionally or in subdirs. +info_TEXINFOS = $(am__append_1) +DISTCLEANFILES = $(am__append_2) +MAINTAINERCLEANFILES = $(am__append_3) INCDIR = $(srcdir)/../include # include libctf for swap.h AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/../include -I$(srcdir)/../libctf @@ -429,6 +497,7 @@ AM_CFLAGS = @ac_libsframe_warn_cflags@ @INSTALL_LIBBFD_FALSE@noinst_LTLIBRARIES = libsframe.la libsframe_la_SOURCES = sframe.c sframe-dump.c sframe-error.c libsframe_la_CPPFLAGS = $(AM_CPPFLAGS) +@BUILD_INFO_TRUE@AM_MAKEINFOFLAGS = --no-split # Setup the testing framework EXPECT = expect @@ -450,10 +519,10 @@ all: config.h $(MAKE) $(AM_MAKEFLAGS) all-am .SUFFIXES: -.SUFFIXES: .c .lo .o .obj +.SUFFIXES: .c .dvi .lo .o .obj .ps am--refresh: Makefile @: -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(srcdir)/testsuite/local.mk $(srcdir)/testsuite/libsframe.decode/local.mk $(srcdir)/testsuite/libsframe.encode/local.mk $(am__configure_deps) +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(srcdir)/doc/local.mk $(srcdir)/testsuite/local.mk $(srcdir)/testsuite/libsframe.decode/local.mk $(srcdir)/testsuite/libsframe.encode/local.mk $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ @@ -475,7 +544,7 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ esac; -$(srcdir)/testsuite/local.mk $(srcdir)/testsuite/libsframe.decode/local.mk $(srcdir)/testsuite/libsframe.encode/local.mk $(am__empty): +$(srcdir)/doc/local.mk $(srcdir)/testsuite/local.mk $(srcdir)/testsuite/libsframe.decode/local.mk $(srcdir)/testsuite/libsframe.encode/local.mk $(am__empty): $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck @@ -726,6 +795,145 @@ clean-libtool: distclean-libtool: -rm -f libtool config.lt +doc/$(am__dirstamp): + @$(MKDIR_P) doc + @: > doc/$(am__dirstamp) + +@BUILD_INFO_TRUE@doc/sframe-spec.info: doc/sframe-spec.texi +@BUILD_INFO_TRUE@ @test -f doc/$(am__dirstamp) || $(MAKE) $(AM_MAKEFLAGS) doc/$(am__dirstamp) +@BUILD_INFO_TRUE@ $(AM_V_MAKEINFO)restore=: && backupdir="$(am__leading_dot)am$$$$" && \ +@BUILD_INFO_TRUE@ rm -rf $$backupdir && mkdir $$backupdir && \ +@BUILD_INFO_TRUE@ if ($(MAKEINFO) --version) >/dev/null 2>&1; then \ +@BUILD_INFO_TRUE@ for f in $@ $@-[0-9] $@-[0-9][0-9] $(@:.info=).i[0-9] $(@:.info=).i[0-9][0-9]; do \ +@BUILD_INFO_TRUE@ if test -f $$f; then mv $$f $$backupdir; restore=mv; else :; fi; \ +@BUILD_INFO_TRUE@ done; \ +@BUILD_INFO_TRUE@ else :; fi && \ +@BUILD_INFO_TRUE@ if $(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I doc -I $(srcdir)/doc \ +@BUILD_INFO_TRUE@ -o $@ `test -f 'doc/sframe-spec.texi' || echo '$(srcdir)/'`doc/sframe-spec.texi; \ +@BUILD_INFO_TRUE@ then \ +@BUILD_INFO_TRUE@ rc=0; \ +@BUILD_INFO_TRUE@ else \ +@BUILD_INFO_TRUE@ rc=$$?; \ +@BUILD_INFO_TRUE@ $$restore $$backupdir/* `echo "./$@" | sed 's|[^/]*$$||'`; \ +@BUILD_INFO_TRUE@ fi; \ +@BUILD_INFO_TRUE@ rm -rf $$backupdir; exit $$rc + +doc/sframe-spec.dvi: doc/sframe-spec.texi doc/$(am__dirstamp) + $(AM_V_TEXI2DVI)TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \ + MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I doc -I $(srcdir)/doc' \ + $(TEXI2DVI) $(AM_V_texinfo) --build-dir=$(@:.dvi=.t2d) -o $@ $(AM_V_texidevnull) \ + `test -f 'doc/sframe-spec.texi' || echo '$(srcdir)/'`doc/sframe-spec.texi + +doc/sframe-spec.pdf: doc/sframe-spec.texi doc/$(am__dirstamp) + $(AM_V_TEXI2PDF)TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \ + MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I doc -I $(srcdir)/doc' \ + $(TEXI2PDF) $(AM_V_texinfo) --build-dir=$(@:.pdf=.t2p) -o $@ $(AM_V_texidevnull) \ + `test -f 'doc/sframe-spec.texi' || echo '$(srcdir)/'`doc/sframe-spec.texi + +doc/sframe-spec.html: doc/sframe-spec.texi doc/$(am__dirstamp) + $(AM_V_MAKEINFO)rm -rf $(@:.html=.htp) + $(AM_V_at)if $(MAKEINFOHTML) $(AM_MAKEINFOHTMLFLAGS) $(MAKEINFOFLAGS) -I doc -I $(srcdir)/doc \ + -o $(@:.html=.htp) `test -f 'doc/sframe-spec.texi' || echo '$(srcdir)/'`doc/sframe-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 doc/sframe-spec.t2d doc/sframe-spec.t2p + +clean-aminfo: + -test -z "doc/sframe-spec.dvi doc/sframe-spec.pdf doc/sframe-spec.ps \ + doc/sframe-spec.html" \ + || rm -rf doc/sframe-spec.dvi doc/sframe-spec.pdf doc/sframe-spec.ps \ + doc/sframe-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 install-includeHEADERS: $(include_HEADERS) @$(NORMAL_INSTALL) @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ @@ -869,6 +1077,9 @@ distdir: $(DISTFILES) || exit 1; \ fi; \ done + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$(top_distdir)" distdir="$(distdir)" \ + dist-info -test -n "$(am__skip_mode_fix)" \ || find "$(distdir)" -type d ! -perm -755 \ -exec chmod u+rwx,go+rx {} \; -o \ @@ -1004,9 +1215,9 @@ check-am: all-am $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) $(MAKE) $(AM_MAKEFLAGS) check-DEJAGNU check: check-am -all-am: Makefile $(LTLIBRARIES) $(HEADERS) config.h +all-am: Makefile $(INFO_DEPS) $(LTLIBRARIES) $(HEADERS) config.h installdirs: - for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)"; do \ + for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(infodir)" "$(DESTDIR)$(includedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am @@ -1035,18 +1246,23 @@ 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) + -rm -f doc/$(am__dirstamp) -rm -f testsuite/libsframe.decode/$(DEPDIR)/$(am__dirstamp) -rm -f testsuite/libsframe.decode/$(am__dirstamp) -rm -f testsuite/libsframe.encode/$(DEPDIR)/$(am__dirstamp) -rm -f testsuite/libsframe.encode/$(am__dirstamp) + -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) +@BUILD_INFO_FALSE@html-local: clean: clean-am -clean-am: clean-checkPROGRAMS clean-generic clean-libLTLIBRARIES \ - clean-libtool clean-noinstLTLIBRARIES mostlyclean-am +clean-am: clean-aminfo clean-checkPROGRAMS clean-generic \ + clean-libLTLIBRARIES clean-libtool clean-noinstLTLIBRARIES \ + mostlyclean-am distclean: distclean-am -rm -f $(am__CONFIG_DISTCLEAN_FILES) @@ -1058,42 +1274,133 @@ distclean-am: clean-am distclean-DEJAGNU distclean-compile \ dvi: dvi-am -dvi-am: +dvi-am: $(DVIS) html: html-am -html-am: +html-am: $(HTMLS) html-local info: info-am -info-am: +info-am: $(INFO_DEPS) -install-data-am: install-includeHEADERS +install-data-am: install-includeHEADERS install-info-am install-dvi: install-dvi-am -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-libLTLIBRARIES install-html: install-html-am -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: - +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: - +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: - +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 @@ -1101,48 +1408,63 @@ maintainer-clean: maintainer-clean-am -rm -rf $(top_srcdir)/autom4te.cache -rm -rf ./$(DEPDIR) testsuite/libsframe.decode/$(DEPDIR) testsuite/libsframe.encode/$(DEPDIR) -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic +maintainer-clean-am: distclean-am maintainer-clean-aminfo \ + maintainer-clean-generic mostlyclean: mostlyclean-am -mostlyclean-am: mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool +mostlyclean-am: mostlyclean-aminfo mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf: pdf-am -pdf-am: +pdf-am: $(PDFS) ps: ps-am -ps-am: +ps-am: $(PSS) -uninstall-am: uninstall-includeHEADERS uninstall-libLTLIBRARIES +uninstall-am: uninstall-dvi-am uninstall-html-am \ + uninstall-includeHEADERS uninstall-info-am \ + uninstall-libLTLIBRARIES uninstall-pdf-am uninstall-ps-am .MAKE: all check-am install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--refresh check check-DEJAGNU \ - check-am clean clean-checkPROGRAMS 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 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-includeHEADERS 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 + check-am clean clean-aminfo clean-checkPROGRAMS clean-cscope \ + clean-generic clean-libLTLIBRARIES clean-libtool \ + clean-noinstLTLIBRARIES cscope cscopelist-am ctags ctags-am \ + dist dist-all dist-bzip2 dist-gzip dist-info 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 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-includeHEADERS \ + 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-aminfo \ + maintainer-clean-generic mostlyclean mostlyclean-aminfo \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags tags-am uninstall uninstall-am \ + uninstall-dvi-am uninstall-html-am uninstall-includeHEADERS \ + uninstall-info-am uninstall-libLTLIBRARIES uninstall-pdf-am \ + uninstall-ps-am .PRECIOUS: Makefile +@BUILD_INFO_TRUE@html-local: doc/sframe-spec/index.html +@BUILD_INFO_TRUE@doc/sframe-spec/index.html: doc/sframe-spec.texi doc/$(am__dirstamp) +@BUILD_INFO_TRUE@ $(AM_V_GEN)$(MAKEINFOHTML) $(AM_MAKEINFOHTMLFLAGS) $(MAKEINFOFLAGS) \ +@BUILD_INFO_TRUE@ --split=node -I$(srcdir) --output doc/sframe-spec $(srcdir)/doc/sframe-spec.texi + +# Workaround bug in automake: it can't handle conditionally building info pages +# since GNU projects normally include info pages in the source distributions. +@BUILD_INFO_FALSE@doc/sframe-spec.info: + check-DEJAGNU: site.exp srcroot=`cd $(srcdir) && pwd`; export srcroot; \ r=`pwd`; export r; \ diff --git a/libsframe/configure b/libsframe/configure index f95900c862c..7bbed5d8ccf 100755 --- a/libsframe/configure +++ b/libsframe/configure @@ -643,6 +643,8 @@ INSTALL_LIBBFD_TRUE MAINT MAINTAINER_MODE_FALSE MAINTAINER_MODE_TRUE +BUILD_INFO_FALSE +BUILD_INFO_TRUE COMPAT_DEJAGNU HAVE_COMPAT_DEJAGNU_FALSE HAVE_COMPAT_DEJAGNU_TRUE @@ -11441,7 +11443,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11444 "configure" +#line 11446 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -11547,7 +11549,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11550 "configure" +#line 11552 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -12223,6 +12225,77 @@ fi COMPAT_DEJAGNU=$ac_cv_dejagnu_compat +build_info= +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="makeinfo" + +if test "x$MAKEINFO" = "x"; then + MAKEINFO="@echo makeinfo missing; true" + build_info= +else + BUILD_INFO=info + case "$MAKEINFO" in + */missing\ makeinfo*) + build_info= + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: +*** Makeinfo is missing. Info documentation will not be built." >&5 +$as_echo "$as_me: WARNING: +*** Makeinfo is missing. Info documentation will not be built." >&2;} + ;; + *) + build_info=yes + ;; + esac +fi + if test "${build_info}" = yes; then + BUILD_INFO_TRUE= + BUILD_INFO_FALSE='#' +else + BUILD_INFO_TRUE='#' + BUILD_INFO_FALSE= +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5 $as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; } @@ -12694,6 +12767,10 @@ if test -z "${HAVE_COMPAT_DEJAGNU_TRUE}" && test -z "${HAVE_COMPAT_DEJAGNU_FALSE as_fn_error $? "conditional \"HAVE_COMPAT_DEJAGNU\" 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 "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 diff --git a/libsframe/configure.ac b/libsframe/configure.ac index a6c1d26bbbb..4182a0dc0ab 100644 --- a/libsframe/configure.ac +++ b/libsframe/configure.ac @@ -59,6 +59,27 @@ AM_CONDITIONAL([HAVE_COMPAT_DEJAGNU], [test "x$ac_cv_dejagnu_compat" = "xyes"]) COMPAT_DEJAGNU=$ac_cv_dejagnu_compat AC_SUBST(COMPAT_DEJAGNU) +dnl Check for makeinfo for building documentation +build_info= +AC_CHECK_PROGS([MAKEINFO], makeinfo, makeinfo, ) +if test "x$MAKEINFO" = "x"; then + MAKEINFO="@echo makeinfo missing; true" + build_info= +else + BUILD_INFO=info + case "$MAKEINFO" in + */missing\ makeinfo*) + build_info= + AC_MSG_WARN([ +*** Makeinfo is missing. Info documentation will not be built.]) + ;; + *) + build_info=yes + ;; + esac +fi +AM_CONDITIONAL(BUILD_INFO, test "${build_info}" = yes) + AM_MAINTAINER_MODE AM_INSTALL_LIBBFD diff --git a/libsframe/doc/local.mk b/libsframe/doc/local.mk new file mode 100644 index 00000000000..bdd1312e040 --- /dev/null +++ b/libsframe/doc/local.mk @@ -0,0 +1,40 @@ +## Process this file with automake to produce Makefile.in. +# +# Copyright (C) 2019-2022 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 +# . +# + +if BUILD_INFO + +info_TEXINFOS += %D%/sframe-spec.texi + +AM_MAKEINFOFLAGS = --no-split + +DISTCLEANFILES += texput.log +MAINTAINERCLEANFILES += %D%/sframe-spec.info + +html-local: %D%/sframe-spec/index.html +%D%/sframe-spec/index.html: %D%/sframe-spec.texi %D%/$(am__dirstamp) + $(AM_V_GEN)$(MAKEINFOHTML) $(AM_MAKEINFOHTMLFLAGS) $(MAKEINFOFLAGS) \ + --split=node -I$(srcdir) --output %D%/sframe-spec $(srcdir)/%D%/sframe-spec.texi + +else + +# Workaround bug in automake: it can't handle conditionally building info pages +# since GNU projects normally include info pages in the source distributions. +%D%/sframe-spec.info: + +endif diff --git a/libsframe/doc/sframe-spec.texi b/libsframe/doc/sframe-spec.texi new file mode 100644 index 00000000000..41f4ba17d83 --- /dev/null +++ b/libsframe/doc/sframe-spec.texi @@ -0,0 +1,619 @@ +\input texinfo @c -*- Texinfo -*- +@setfilename sframe-spec.info +@settitle The SFrame Format +@ifnottex +@xrefautomaticsectiontitle on +@end ifnottex + +@copying +Copyright @copyright{} 2021-2022 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 +* SFrame: (sframe-spec). The Simple Frame format. +@end direntry + +@titlepage +@title The SFrame Format +@subtitle Version 1 +@author Indu Bhagat + +@page +@vskip 0pt plus 1filll +@insertcopying +@end titlepage +@contents + +@ifnottex +@node Top +@top The SFrame format + +This manual describes version 1 of the SFrame file format. SFrame stands for +Simple Frame format. SFrame format keeps track of the minimal necessary +information needed for stack unwinding: + +@itemize @minus +@item +Canonical Frame Address (CFA). +@item +Frame Pointer (FP). +@item +Return Address (RA). +@end itemize + +The reason for existence of the SFrame format is to support fast, online +backtracing using a simple unwinder. + +@menu +* Overview:: +* SFrame section:: +* Index:: +@end menu + +@end ifnottex + +@node Overview +@unnumbered Overview +@cindex Overview +@tindex PT_GNU_SFRAME + +The SFrame unwind information is provided in a loaded section, known as the +@code{.sframe} section. When available, the @code{.sframe} section appears in +a new segment of its own, PT_GNU_SFRAME. + +The SFrame format is currently supported only for select ABIs, namely, AMD64 +and AAPCS64. + +The contents of the SFrame section are stored in the target endianness, i.e., +in the endianness of the system on which the section is targetted to be used. +An SFrame section reader may use the magic number in the SFrame header to +identify the endianness of the SFrame section. + +Addresses in this specification are expressed in bytes. + +The associated API to decode, probe and encode the SFrame section, provided via +@code{libsframe}, is not accompanied here at this time. This will be added +later. + +This document is intended to be in sync with the C code in @file{sframe.h}. +Please report descrepancies between the two, if any. + +@node SFrame section +@chapter SFrame section +@cindex SFrame section + +The SFrame section consists of an SFrame header, starting with a preamble, and +two other sub-sections, namely the SFrame Function Descriptor Entry (SFrame +FDE) sub-section, and the SFrame Frame Row Entry (SFrame FRE) sub-section. + +@menu +* SFrame Preamble:: +* SFrame Header:: +* SFrame Function Descriptor Entries:: +* SFrame Frame Row Entries:: +@end menu + +@node SFrame Preamble +@section SFrame Preamble +@cindex SFrame preamble + +The preamble is a 32-bit packed structure; the only part of the SFrame whose +format cannot vary between versions. + +@example +typedef struct sframe_preamble +@{ + uint16_t sfp_magic; + uint8_t sfp_version; + uint8_t sfp_flags; +@} ATTRIBUTE_PACKED sframe_preamble; +@end example + +All values are stored in the endianness of the target system for which the +SFrame section is intended. Further details: + +@multitable {Offset} {@code{uint8_t sfp_version}} {The magic number for SFrame section: 0xdee2. Defined} +@headitem Offset @tab Name @tab Description +@item 0x00 +@tab @code{uint16_t sfp_magic} +@tab The magic number for SFrame section: 0xdee2. Defined as a macro @code{SFRAME_MAGIC}. +@tindex SFRAME_MAGIC + +@item 0x02 +@tab @code{uint8_t sfp_version} +@tab The version number of this SFrame section. @xref{SFrame version}, for the +set of valid values. Current version is +@code{SFRAME_VERSION_1}. + +@item 0x03 +@tab @code{uint8_t sfp_flags} +@tab Flags (section-wide) for this SFrame section. @xref{SFrame flags}, for the +set of valid values. +@end multitable + +@menu +* SFrame endianness:: +* SFrame version:: +* SFrame flags:: +@end menu + +@node SFrame endianness +@subsection SFrame endianness + +@cindex endianness +SFrame sections are stored in the target endianness of the system that consumes +them. The SFrame library (@code{libsframe}) can, however, detect whether to +endian-flip an SFrame section at decode time, by inspecting the +@code{sfp_magic} field in the SFrame header (If it appears as 0xe2de, +endian-flipping is needed). + +@node SFrame version +@subsection SFrame version + +The version of the SFrame format can be determined by inspecting +@code{sfp_version}. The following versions are currently valid: + +@tindex SFRAME_VERSION_1 +@cindex SFrame versions +@multitable {SFRAME_VERSION_1} {Number} {First version, under development.} +@headitem Version @tab Number @tab Description +@item @code{SFRAME_VERSION_1} +@tab 1 @tab First version, under development. +@end multitable + +This section documents @code{SFRAME_VERSION_1}. + +@node SFrame flags +@subsection SFrame flags +@cindex SFrame flags +@comment @vindex sfp_flags +@comment @vindex SFrame section-wide flags +@comment @subsection SFrame section-wide flags + +The preamble contains bitflags in its @code{sfp_flags} field that +describe various section-wide properties. + +The following flags are currently defined. + +@multitable {@code{SFRAME_F_FRAME_POINTER}} {Versions} {Value} {Function Descriptor Entries} +@headitem Flag @tab Versions @tab Value @tab Meaning +@tindex SFRAME_F_FDE_SORTED +@item @code{SFRAME_F_FDE_SORTED} @tab All @tab 0x1 @tab Function Descriptor +Entries are sorted on PC. +@tindex SFRAME_F_FRAME_POINTER +@item @code{SFRAME_F_FRAME_POINTER} @tab All @tab 0x2 +@tab Functions preserve frame-pointer. +@end multitable + +Further flags may be added in future. + +@node SFrame Header +@section SFrame Header +@cindex SFrame header + +The SFrame header is the first part of an SFrame section. It begins with the +SFrame preamble. All parts of it other than the preamble +(@pxref{SFrame Preamble}) can vary between SFrame file versions. It contains +things that apply to the section as a whole, and offsets to the various other +sub-sections defined in the format. As with the rest of the SFrame section, +all values are stored in the endianness of the target system. + +The two sub-sections tile the SFrame section: each section runs from the offset +given until the start of the next section. An explicit length is given for the +last sub-section, the SFrame Frame Row Entry (SFrame FRE) sub-section. + +@example +typedef struct sframe_header +@{ + sframe_preamble sfh_preamble; + uint8_t sfh_abi_arch; + int8_t sfh_cfa_fixed_fp_offset; + int8_t sfh_cfa_fixed_ra_offset; + uint8_t sfh_auxhdr_len; + uint32_t sfh_num_fdes; + uint32_t sfh_num_fres; + uint32_t sfh_fre_len; + uint32_t sfh_fdeoff; + uint32_t sfh_freoff; +@} ATTRIBUTE_PACKED sframe_header; +@end example + +The sub-section offsets, namely @code{sfh_fdeoff} and @code{sfh_freoff}, in the +SFrame header are relative to the @emph{end} of the SFrame header; they are +each an offset in bytes into the SFrame section where the SFrame FDE +sub-section and the SFrame FRE sub-section respectively start. + +SFrame header allows specifying explicitly the fixed offsets from CFA, if any, +from which FP or RA may be recovered. For example, in AMD64, the stack offset +of the return address is @code{CFA - 8}. Since this offset is in close +vicinity with the CFA in most ABIs, @code{sfh_cfa_fixed_fp_offset} and +@code{sfh_cfa_fixed_ra_offset} are limited to signed 8-bit integers. + +SFrame format has provisioned for future ABIs/architectures that it may +support. The @code{sframe_header} structure provides an unsigned 8-bit +integral field to denote the size of an auxilliary SFrame header. The +auxilliary SFrame header follows right after the @code{sframe_header} +structure. As for the offset calculations, the @emph{end} of SFrame header +must be the end of the auxilliary SFrame header, if the latter is present. + +Tieing it all together: + +@multitable {Offset} {@code{int8_t sfh_cfa_fixed_fp_offset}} {The ABI/arch identifier. See above} +@headitem Offset @tab Name @tab Description +@item 0x00 +@tab @code{sframe_preamble sfh_preamble} +@tab The SFrame preamble. @xref{SFrame Preamble}. + +@item 0x04 +@tab @code{uint8_t sfh_abi_arch} +@tab The ABI/arch identifier. @xref{SFrame ABI/arch identifier}. + +@item 0x05 +@tab @code{int8_t sfh_cfa_fixed_fp_offset} +@tab The CFA fixed FP offset, if any. + +@item 0x06 +@tab @code{int8_t sfh_cfa_fixed_ra_offset} +@tab The CFA fixed RA offset, if any. + +@item 0x07 +@tab @code{uint8_t sfh_auxhdr_len} +@tab Size in bytes of the auxilliary header that follows the +@code{sframe_header} structure. + +@item 0x08 +@tab @code{uint32_t sfh_num_fdes} +@tab The number of SFrame FDEs in the section. + +@item 0xc +@tab @code{uint32_t sfh_num_fres} +@tab The number of SFrame FREs in the section. + +@item 0x10 +@tab @code{uint32_t sfh_fre_len} +@tab The length in bytes of the SFrame FRE sub-section. + +@item 0x14 +@tab @code{uint32_t sfh_fdeoff} +@tab The offset in bytes of the SFrame FDE sub-section. This sub-section +contains @code{sfh_num_fdes} number of fixed-length array elements. The array +element is of type SFrame function desciptor entry, each providing a +high-level function description for backtracing. +@xref{SFrame Function Descriptor Entries}. + +@item 0x18 +@tab @code{uint32_t sfh_freoff} +@tab The offset in bytes of the SFrame FRE sub-section, the core of the SFrame +section, which describes the unwind information using variable-length array +elements. @xref{SFrame Frame Row Entries}. + +@end multitable + +@menu +* SFrame ABI/arch identifier:: +@end menu + +@node SFrame ABI/arch identifier +@subsection SFrame ABI/arch identifier +@cindex SFrame ABI/arch identifier + +SFrame header identifies the ABI/arch of the target system for which the +executable and it's unwind information is intended. There are currently three +identifiable ABI/arch values in the format. + +@multitable {SFRAME_ABI_AARCH64_ENDIAN_LITTLE} {Value} {@code{AARCH64 little-endian}} +@headitem ABI/arch Identifier @tab Value @tab Description + +@tindex SFRAME_ABI_AARCH64_ENDIAN_BIG +@item @code{SFRAME_ABI_AARCH64_ENDIAN_BIG} +@tab 1 @tab AARCH64 big-endian + +@tindex SFRAME_ABI_AARCH64_ENDIAN_LITTLE +@item @code{SFRAME_ABI_AARCH64_ENDIAN_LITTLE} +@tab 2 @tab AARCH64 little-endian + +@tindex SFRAME_ABI_AMD64_ENDIAN_LITTLE +@item @code{SFRAME_ABI_AMD64_ENDIAN_LITTLE} +@tab 3 @tab AMD64 little-endian + +@end multitable + +The presence of an explicit identification of ABI/arch in SFrame may allow +unwinders to make certain ABI-specific decisions. + +@node SFrame Function Descriptor Entries +@section SFrame FDE +@cindex SFrame FDE + +The SFrame Function Descriptor Entry sub-section is a sorted array of +fixed-length SFrame function descriptor entries (SFrame FDEs). Each SFrame FDE +is a packed structure which contains information to describe a function's unwind +information at a high-level. + +@example +typedef struct sframe_func_desc_entry +@{ + int32_t sfde_func_start_address; + uint32_t sfde_func_size; + uint32_t sfde_func_start_fre_off; + uint32_t sfde_func_num_fres; + uint8_t sfde_func_info; +@} ATTRIBUTE_PACKED sframe_func_desc_entry; +@end example + +@code{sfde_func_start_fre_off} is the offset to the first SFrame FRE for the +function. This offset is relative to the @emph{end of the SFrame FDE} +sub-section (unlike the offsets in the SFrame header, which are relative to the +@emph{end} of the SFrame header). + +@code{sfde_func_info} is the "info word", containing information on the FRE +type and the FDE type for the function @xref{The SFrame FDE info word}. + +Following table describes each component of the SFrame FDE structure: + +@multitable {Offset} {@code{uint32_t sfde_func_start_fre_off}} {The ABI/arch identifier. See above} +@headitem Offset @tab Name @tab Description +@item 0x00 +@tab @code{int32_t sfde_func_start_address} +@tab Signed 32-bit integral field denoting the virtual memory address of the +described function. + +@item 0x04 +@tab @code{uint32_t sfde_func_size} +@tab Unsigned 32-bit integral field specifying the size of the function in +bytes. + +@item 0x08 +@tab @code{uint32_t sfde_func_start_fre_off} +@tab Unsigned 32-bit integral field specifying the offset in bytes of the +function's first SFrame FRE in the SFrame section. + +@item 0x0c +@tab @code{uint32_t sfde_func_num_fres} +@tab Unsigned 32-bit integral field specifying the total number of SFrame FREs +used for the function. + +@item 0x10 +@tab @code{uint8_t sfde_func_info} +@tab The SFrame FDE info word. @xref{The SFrame FDE info word}. + +@end multitable + +@menu +* The SFrame FDE info word:: +* The SFrame FDE types:: +* The SFrame FRE types:: +@end menu + +@cindex The SFrame FDE info word +@node The SFrame FDE info word +@subsection The SFrame FDE info word, sfde_func_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 7--5 +@tab @code{unused} +@tab Unused bits. + +@item 4 +@tab @code{fdetype} +@tab SFRAME_FDE_TYPE_PCMASK (1) or SFRAME_FDE_TYPE_PCINC (0). @xref{The SFrame FDE types}. + +@item 0--3 +@tab @code{fretype} +@tab Choice of three SFrame FRE types. @xref{The SFrame FRE types}. +@end multitable + +@node The SFrame FDE types +@subsection The SFrame FDE types +@tindex SFRAME_FDE_TYPE_PCMASK +@tindex SFRAME_FDE_TYPE_PCINC + +SFrame format defines two types of FDE entries. The choice of which SFrame FDE +type to use is made based on the instruction patterns in the relevant program +stub. + +An SFrame FDE of type @code{SFRAME_FDE_TYPE_PCINC} is an indication that the PCs in the +FREs should be treated as increments in bytes. This is used fo the the bulk of +the executable code of a program, which contains instructions with no specific +pattern. + +In contrast, an SFrame FDE of type @code{SFRAME_FDE_TYPE_PCMASK} is an +indication that the PCs in the FREs should be treated as masks. This type is +useful for the cases where a small pattern of instructions in a program stub is +used repeatedly for a specific functionality. Typical usecases are pltN +entries and trampolines. + +@multitable {Name of SFrame FDE type} {Value} {Unwinders perform a (PC >= FRE_START_ADDR)} +@headitem Name of SFrame FDE type @tab Value @tab Description + +@item SFRAME_FDE_TYPE_PCINC +@tab 0 @tab Unwinders perform a (PC >= FRE_START_ADDR) to look up a matching FRE. + +@item SFRAME_FDE_TYPE_PCMASK +@tab 1 @tab Unwinders perform a (PC & FRE_START_ADDR_AS_MASK >= FRE_START_ADDR_AS_MASK) +to look up a matching FRE. + +@end multitable + +@node The SFrame FRE types +@subsection The SFrame FRE types + +A real world application can have functions of size big and small. SFrame +format defines three types of SFrame FRE entries to represent the unwind +information for such a variety of function sizes. These representations vary +in the number of bits needed to encode the start address offset in the SFrame +FRE. + +The following constants are defined and used to identify the SFrame FRE types: + +@multitable {SFRAME_FRE_TYPE_ADDR1} {@code{Value}} {The start address offset of FRE is an} +@headitem Name @tab Value @tab Description + +@tindex SFRAME_FRE_TYPE_ADDR1 +@item @code{SFRAME_FRE_TYPE_ADDR1} +@tab 0 +@tab The start address offset (in bytes) of the SFrame FRE is an unsigned +8-bit value. + +@tindex SFRAME_FRE_TYPE_ADDR2 +@item @code{SFRAME_FRE_TYPE_ADDR2} +@tab 1 +@tab The start address offset (in bytes) of the SFrame FRE is an unsigned +16-bit value. + +@tindex SFRAME_FRE_TYPE_ADDR4 +@item @code{SFRAME_FRE_TYPE_ADDR4} +@tab 2 +@tab The start address offset (in bytes) of the SFrame FRE is an unsigned +32-bit value. +@end multitable + +A single function must use the same type of FRE throughout. The choice of +which SFrame FRE is used to encode the unwind information of a function, is +stored in the @xref{The SFrame FDE info word}. + +@node SFrame Frame Row Entries +@section SFrame FRE +@cindex SFrame FRE + +The SFrame Frame Row Entry sub-section contains the core of the unwind +information. + +An SFrame Frame Row Entry is a self-sufficient record containing SFrame unwind +info for a range of contiguous addresses, starting at the specified offset from +the start of the function. Each SFrame Frame Row Entry is followed by S*N +bytes, where: + +@itemize @minus +@item +@code{S} is the size of the stack frame offset for the FRE, and +@item +@code{N} is the number of stack frame offsets in the FRE +@end itemize + +The stack offsets, following the FRE, are interpreted in order as follows: + +@itemize @minus +@item +The first offset is always used to locate the CFA, by interpreting it as: +CFA = @code{BASE_REG} + offset1. +@item +If RA is being tracked, the second offset is always used to locate the RA, by +interpreting it as: RA = CFA + offset2. If RA is @emph{not} being tracked +@emph{and} FP is being tracked, the second offset will be used to locate the +FP, by interpreting it as: FP = CFA + offset2. +@item +If both RA and FP are being tracked, the third offset will be used to locate +the FP, by interpreting it as FP = CFA + offset3. +@end itemize + +The entities @code{S}, @code{N} and @code{BASE_REG} are identified using the +SFrame FRE info word, a.k.a. the @code{sframe_fre_info} +@xref{The SFrame FRE info word}. + +Following are the definitions of the allowed SFrame FRE: + +@example +typedef struct sframe_frame_row_entry_addr1 +@{ + uint8_t sfre_start_address; + sframe_fre_info sfre_info; +@} ATTRIBUTE_PACKED sframe_frame_row_entry_addr1; +@end example + +@example +typedef struct sframe_frame_row_entry_addr2 +@{ + uint16_t sfre_start_address; + sframe_fre_info sfre_info; +@} ATTRIBUTE_PACKED sframe_frame_row_entry_addr2; +@end example + +@example +typedef struct sframe_frame_row_entry_addr4 +@{ + uint32_t sfre_start_address; + sframe_fre_info sfre_info; +@} ATTRIBUTE_PACKED sframe_frame_row_entry_addr4; +@end example + +@code{sfre_start_address} is an unsigned 8-bit/16-bit/32-bit integral field +identifies the start address of the range of program counters, for which the +SFrame FRE applies. The value encoded in the @code{sfre_start_address} field +is the offset in bytes of the start address of the SFrame FRE, from the start +address of the function. + +Further FRE types may be added in future. + +@menu +* The SFrame FRE info word:: +@end menu + +@cindex The SFrame FRE info word +@node The SFrame FRE info word +@subsection The SFrame FRE info word, sfre_info + +The SFrame FRE info word is a bitfield split into four parts. From MSB to LSB: + +@multitable {Bit offset} {@code{fre_cfa_base_reg_id}} {Size of stack offsets in bytes. Valid values} +@headitem Bit offset @tab Name @tab Description +@item 7 +@tab @code{unused} +@tab Unused bit. + +@item 5-6 +@tab @code{fre_offset_size} +@tab Size of stack offsets in bytes. Valid values are SFRAME_FRE_OFFSET_1B, +SFRAME_FRE_OFFSET_2B, and SFRAME_FRE_OFFSET_4B. + +@item 1-4 +@tab @code{fre_offset_count} +@tab A value of upto 3 is allowed to track all three of CFA, FP and RA. + +@item 0 +@tab @code{fre_cfa_base_reg_id} +@tab Distinguish between SP or FP based CFA recovery. + +@end multitable + +@multitable {SFRAME_FRE_OFFSET_4B} {@code{Value}} {All stack offsets following the fixed-length} +@headitem Name @tab Value @tab Description + +@tindex SFRAME_FRE_OFFSET_1B +@item @code{SFRAME_FRE_OFFSET_1B} +@tab 0 +@tab All stack offsets following the fixed-length FRE structure are 1 byte +long. + +@tindex SFRAME_FRE_OFFSET_2B +@item @code{SFRAME_FRE_OFFSET_2B} +@tab 1 +@tab All stack offsets following the fixed-length FRE structure are 2 bytes +long. + +@tindex SFRAME_FRE_OFFSET_4B +@item @code{SFRAME_FRE_OFFSET_4B} +@tab 2 +@tab All stack offsets following the fixed-length FRE structure are 4 bytes +long. + +@end multitable + +@node Index +@unnumbered Index + +@syncodeindex tp cp +@printindex cp + +@bye