Compare commits

...

10 Commits

Author SHA1 Message Date
Indu Bhagat
8e7c22636c binutils/NEWS: add note about upcoming libsframe changes
Some of these changes update the ABI in an incompatible way.
2023-06-23 09:37:48 -07:00
Indu Bhagat
67e07c11b5 libsframe: use uint8_t for return type of sframe_fre_get_base_reg_id
Use a more appropriate data type.

include/
	* sframe-api.h (sframe_fre_get_base_reg_id): Use uint8_t as
	return type.
libsframe/
	* sframe-dump.c (dump_sframe_func_with_fres): Use uint8_t type
	for base reg id.
	* sframe.c (sframe_fre_get_base_reg_id): Use uin8_t as return
	type.
2023-06-23 09:37:48 -07:00
Indu Bhagat
4d5e6646a4 libsframe: use uint8_t instead of unsigned char for abi_arch
Use uint8_t consistently for identifying ABI/arch in SFrame format.

bfd/
	* elf-sframe.c (_bfd_elf_merge_section_sframe):
libsframe/
	* sframe-dump.c (is_sframe_abi_arch_aarch64): Use uint8_t for
	local variable.
	* sframe.c (sframe_decoder_get_abi_arch): Update return type to
	uint8_t.
	(sframe_encoder_get_abi_arch): Likewise.
include/
	* sframe-api.h (sframe_decoder_get_abi_arch): Likewise.
	(sframe_encoder_get_abi_arch): Likewise.
2023-06-23 09:37:48 -07:00
Indu Bhagat
dc7b82cac5 bfd: libsframe: use uint32_t for return type of sframe_calc_fre_type
Use uint32_t type alias consistently for all APIs in libsframe.

bfd/
	* elfxx-x86.c (_bfd_x86_elf_create_sframe_plt): Adjust for the
	changed return type.
libsframe/
	* sframe.c (sframe_calc_fre_type): Use uint32_t for return type.
include/
	* sframe-api.h (sframe_calc_fre_type): Likewise.
2023-06-23 09:37:48 -07:00
Indu Bhagat
28a1110665 libsframe: use uint32_t for fre_type and fde_type function args
The API sframe_fde_create_func_info is provided by libsframe.  Current
users are the bfd linker.  Adjust the argument type for the variables
carrying the SFrame FRE type and SFrame FDE type to consistenly use
uint32_t type alias.

include/
	* sframe-api.h (sframe_fde_create_func_info): Use uint32_t
	instead of unsigned int.

libsframe/
	* sframe.c (sframe_get_fre_type): Likewise.
	(sframe_get_fde_type): Likewise.
	(flip_fre_start_address): Likewise.
	(sframe_fre_start_addr_size): Likewise.
	(sframe_fre_entry_size): Likewise.
	(flip_fre): Likewise.
	(flip_sframe): Likewise.
	(sframe_fde_create_func_info): Likewise.
	(sframe_calc_fre_type): Likewise.
	(sframe_decode_fre_start_address): Likewise.
	(sframe_decode_fre): Likewise.
	(sframe_find_fre): Likewise.
	(sframe_decoder_get_fre): Likewise.
	(sframe_encoder_add_fre): Likewise.
	(sframe_encoder_write_fre_start_addr): Likewise.
	(sframe_encoder_write_fre): Likewise.
	(sframe_encoder_write_sframe): Likewise.
2023-06-23 09:37:48 -07:00
Indu Bhagat
34b4ed457e libsframe: update the semantics of sframe_fre_get_fp_offset
Until now, sframe_fre_get_fp_offset () would return
SFRAME_ERR_FREOFFSET_NOPRESENT if the ABI uses fixed FP offset.  A stack
tracer, then, would call an explicit sframe_decoder_get_fixed_fp_offset ()
to get the FP offset.

On second look, it appears to make sense to hide these details of
whether the FP offset is fixed or not in an ABI from the consumer.  Now,
with the changed semantics, the call to sframe_fre_get_fp_offset () will
fetch the fixed FP offset if applicable, or get the FP offset from FRE
when there is no fixed FP offset.

This patch changes the behavior of sframe_fre_get_fp_offset (): it turns
an error into non-error.  This change will be included with the next
release of libsframe, where all the exposed symbols will be versioned
with version node LIBSFRAME_1.0 for the first time.

libsframe/
	* sframe.c (sframe_fre_get_fp_offset): Return the fixed offset, if
	applicable. Else return the FP offset from the FRE.
2023-06-23 09:37:48 -07:00
Indu Bhagat
9a1d95f8ab libsframe: update the semantics of sframe_fre_get_ra_offset
Until now, sframe_fre_get_ra_offset () would return
SFRAME_ERR_FREOFFSET_NOPRESENT if the ABI uses fixed RA offset (e.g.,
AMD64).  A stack tracer, then, will call an explicit
sframe_decoder_get_fixed_ra_offset () to get the RA offset.

On second look, it appears to make sense to hide these details of
whether the RA offset is fixed or not from the consumer.  Now, with the
changed semantics, the call to sframe_fre_get_ra_offset () will fetch
the fixed RA offset if applicable, or get the RA offset from FRE when
there is no fixed RA offset.

Adjustments need to be made to ensure the textual dump remains the same
as preivous.  Currently, e.g., if RA is not being tracked per FRE,
following is seen with objdump --sframe:

    STARTPC         CFA       FP        RA
    000000000000NNNN  sp+X      u         u

This patch changes the behavior of sframe_fre_get_ra_offset: it turns an
error into non-error.  This change will be included with the next
release of libsframe, where all exposed symbols will be versioned for
the first time.

libsframe/
	* sframe.c (sframe_fre_get_ra_offset): Return the fixed offset,
	if applicable.  Else return the RA offset from the FRE.
	* sframe-dump.c (dump_sframe_func_with_fres): Make adjustments
	to keep the textual dump same as previous.
2023-06-23 09:37:48 -07:00
Indu Bhagat
8c48a36643 libsframe: add symbol versioning
Define an empty base version LIBSFRAME_0.0 and add all symbols to
version LIBSFRAME_1.0.

The previous release of libsframe (libsframe.so.0) did not have
versioned symbols.  Adding a libsframe.ver file so that future releases
of the library (and its consumers) can manage the changes better.

For Solaris ld, use -M mapfile command line option.  libsframe does not
restrict the set of exported symbols, so at this time there is no need
to fall back on the libtool's -export-symbols option for platforms where
some other linker (with a different command line option for symbol
versioning) may be used.

libsframe/
	* Makefile.am: Use symbol versioning for libsframe.
	* Makefile.in: Regenerated.
	* configure: Check for Solaris ld.
	* configure.ac: Regenerated.
	* libsframe.ver: New file.
2023-06-23 09:37:48 -07:00
Indu Bhagat
8635c11914 libsframe: remove sframe_get_funcdesc_with_addr API
This is an incompatible ABI change in libsframe.

The interface provided by this function is not a healthy abstraction to
expose: the return type sframe_func_desc_entry, which is defined in
include/sframe.h (the SFrame binary format definition).  This ties up
the library in a undesirable way.  Most importantly, this function
should technically not be directly necessary for a stack tracer.  A
stack tracer will likely only need to do a sframe_find_fre ().

Rename the API to continue to use the functionality internally in the
library.  bfd/linker does not use this function.

Change the return type of the previous definition and make a note about
its planned deprecation.

include/
	* sframe-api.h:  Change return type of sframe_get_funcdesc_with_addr.
	Add comment for intention to deprecate.
libsframe/
	*sframe.c (sframe_get_funcdesc_with_addr): Change return type
	and set error code. This API is deprecated.
        (sframe_get_funcdesc_with_addr_internal): New definition for
	internal use.
	(sframe_find_fre): Use sframe_get_funcdesc_with_addr_internal
	instead.
2023-06-23 09:37:48 -07:00
Indu Bhagat
dedaa93a32 libsframe: add library versioning
lisbframe was first released with Bintuils 2.40.  As the library
evolves, some changes will break the ABI.  Add library versioning for
users to manage these changes.

For the next release of the library (libsframe.so.1), incompatible ABI
changes are planned. These will include:
 - Deprecation of some APIs, like sframe_get_funcdesc_with_addr (),
 - Change in the contract of some APIs (e.g., return type, behavior)

In libtool-version, set the current to 1 to prepare for the upcoming
release.  Reset revision and age to 0.

Add libtool-version to EXTRA_DIST.

libsframe/
	* Makefile.am: Use libtool versioning.
	* Makefile.in: Regenerated.
	* libtool-version: New file.
2023-06-23 09:37:48 -07:00
12 changed files with 277 additions and 63 deletions

View File

@@ -325,7 +325,7 @@ _bfd_elf_merge_section_sframe (bfd *abfd,
struct sframe_enc_info *sfe_info;
sframe_decoder_ctx *sfd_ctx;
sframe_encoder_ctx *sfe_ctx;
unsigned char sfd_ctx_abi_arch;
uint8_t sfd_ctx_abi_arch;
int8_t sfd_ctx_fixed_fp_offset;
int8_t sfd_ctx_fixed_ra_offset;
int encerr = 0;

View File

@@ -1832,7 +1832,7 @@ _bfd_x86_elf_create_sframe_plt (bfd *output_bfd,
bool plt0_generated_p;
unsigned int plt0_entry_size;
unsigned char func_info;
unsigned int fre_type;
uint32_t fre_type;
/* The dynamic plt section for which .sframe stack trace information is being
created. */
asection *dpltsec;

View File

@@ -7,6 +7,12 @@
* Objdump's --private option can now be used on PE format files to display the
fields in the file header and section headers.
* New versioned release of libsframe: libsframe.so.1. This release introduces
versioned symbols with version node name LIBSFRAME_1.0. This release also
updates the ABI in an incompatible way: this includes removal of
sframe_get_funcdesc_with_addr API, change in the behavior of
sframe_fre_get_ra_offset and sframe_fre_get_fp_offset APIs.
Changes in 2.40:

View File

@@ -94,11 +94,11 @@ sframe_errmsg (int error);
/* Create an FDE function info bye given an FRE_TYPE and an FDE_TYPE. */
extern unsigned char
sframe_fde_create_func_info (unsigned int fre_type, unsigned int fde_type);
sframe_fde_create_func_info (uint32_t fre_type, uint32_t fde_type);
/* Gather the FRE type given the function size. */
extern unsigned int
extern uint32_t
sframe_calc_fre_type (size_t func_size);
/* The SFrame Decoder. */
@@ -117,7 +117,7 @@ extern unsigned int
sframe_decoder_get_hdr_size (sframe_decoder_ctx *dctx);
/* Get the SFrame's abi/arch info. */
extern unsigned char
extern uint8_t
sframe_decoder_get_abi_arch (sframe_decoder_ctx *dctx);
/* Return the number of function descriptor entries in the SFrame decoder
@@ -133,10 +133,13 @@ sframe_decoder_get_fixed_fp_offset (sframe_decoder_ctx *dctx);
extern int8_t
sframe_decoder_get_fixed_ra_offset (sframe_decoder_ctx *dctx);
/* Find the function descriptor entry which contains the specified address. */
extern sframe_func_desc_entry *
sframe_get_funcdesc_with_addr (sframe_decoder_ctx *dctx,
int32_t addr, int *errp);
/* Find the function descriptor entry which contains the specified address.
Note: This function is deprecated and will be removed from future release
X+2 of the library. */
extern void *
sframe_get_funcdesc_with_addr (sframe_decoder_ctx *dctx, int32_t addr,
int *errp);
/* Find the SFrame Frame Row Entry which contains the PC. Returns
SFRAME_ERR if failure. */
@@ -170,7 +173,7 @@ extern void
dump_sframe (sframe_decoder_ctx *decoder, uint64_t addr);
/* Get the base reg id from the FRE info. Sets errp if fails. */
extern unsigned int
extern uint8_t
sframe_fre_get_base_reg_id (sframe_frame_row_entry *fre, int *errp);
/* Get the CFA offset from the FRE. If the offset is invalid, sets errp. */
@@ -211,7 +214,7 @@ extern unsigned int
sframe_encoder_get_hdr_size (sframe_encoder_ctx *encoder);
/* Get the abi/arch info from the SFrame encoder context CTX. */
extern unsigned char
extern uint8_t
sframe_encoder_get_abi_arch (sframe_encoder_ctx *encoder);
/* Return the number of function descriptor entries in the SFrame encoder

View File

@@ -29,6 +29,17 @@ INCDIR = $(srcdir)/../include
# include libctf for swap.h
AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/../include -I$(srcdir)/../libctf
AM_CFLAGS = @ac_libsframe_warn_cflags@
libsframe_version_info = -version-info `grep -v '^\#' $(srcdir)/libtool-version`
# libsframe does not restrict the set of exported symbols. So, if linker does
# not support symbol versioning, there is no need to fall back on libtool's
# -export-symbols option.
if HAVE_LD_VERSION_SCRIPT
if HAVE_SOLARIS_LD
libsframe_version_script = -Wl,-M -Wl,$(srcdir)/libsframe.ver
else
libsframe_version_script = -Wl,--version-script=$(srcdir)/libsframe.ver
endif
endif
if INSTALL_LIBBFD
lib_LTLIBRARIES = libsframe.la
@@ -40,6 +51,10 @@ endif
libsframe_la_SOURCES = sframe.c sframe-dump.c sframe-error.c
libsframe_la_CPPFLAGS = $(AM_CPPFLAGS)
libsframe_la_LDFLAGS = $(libsframe_version_info) $(libsframe_version_script)
EXTRA_DIST = libtool-version libsframe.ver
diststuff: $(EXTRA_DIST) info
include doc/local.mk

View File

@@ -180,6 +180,9 @@ AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
am__v_lt_0 = --silent
am__v_lt_1 =
libsframe_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(libsframe_la_LDFLAGS) $(LDFLAGS) -o $@
@INSTALL_LIBBFD_FALSE@am_libsframe_la_rpath =
@INSTALL_LIBBFD_TRUE@am_libsframe_la_rpath = -rpath $(libdir)
@HAVE_COMPAT_DEJAGNU_TRUE@am__EXEEXT_1 = testsuite/libsframe.decode/be-flipping$(EXEEXT) \
@@ -519,12 +522,20 @@ INCDIR = $(srcdir)/../include
# include libctf for swap.h
AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/../include -I$(srcdir)/../libctf
AM_CFLAGS = @ac_libsframe_warn_cflags@
libsframe_version_info = -version-info `grep -v '^\#' $(srcdir)/libtool-version`
@HAVE_LD_VERSION_SCRIPT_TRUE@@HAVE_SOLARIS_LD_FALSE@libsframe_version_script = -Wl,--version-script=$(srcdir)/libsframe.ver
# libsframe does not restrict the set of exported symbols. So, if linker does
# not support symbol versioning, there is no need to fall back on libtool's
# -export-symbols option.
@HAVE_LD_VERSION_SCRIPT_TRUE@@HAVE_SOLARIS_LD_TRUE@libsframe_version_script = -Wl,-M -Wl,$(srcdir)/libsframe.ver
@INSTALL_LIBBFD_TRUE@lib_LTLIBRARIES = libsframe.la
@INSTALL_LIBBFD_FALSE@include_HEADERS =
@INSTALL_LIBBFD_TRUE@include_HEADERS = $(INCDIR)/sframe.h $(INCDIR)/sframe-api.h
@INSTALL_LIBBFD_FALSE@noinst_LTLIBRARIES = libsframe.la
libsframe_la_SOURCES = sframe.c sframe-dump.c sframe-error.c
libsframe_la_CPPFLAGS = $(AM_CPPFLAGS)
libsframe_la_LDFLAGS = $(libsframe_version_info) $(libsframe_version_script)
EXTRA_DIST = libtool-version libsframe.ver
@BUILD_INFO_TRUE@AM_MAKEINFOFLAGS = --no-split
# Setup the testing framework
@@ -654,7 +665,7 @@ clean-noinstLTLIBRARIES:
}
libsframe.la: $(libsframe_la_OBJECTS) $(libsframe_la_DEPENDENCIES) $(EXTRA_libsframe_la_DEPENDENCIES)
$(AM_V_CCLD)$(LINK) $(am_libsframe_la_rpath) $(libsframe_la_OBJECTS) $(libsframe_la_LIBADD) $(LIBS)
$(AM_V_CCLD)$(libsframe_la_LINK) $(am_libsframe_la_rpath) $(libsframe_la_OBJECTS) $(libsframe_la_LIBADD) $(LIBS)
clean-checkPROGRAMS:
@list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \
@@ -1568,6 +1579,7 @@ uninstall-am: uninstall-dvi-am uninstall-html-am \
.PRECIOUS: Makefile
diststuff: $(EXTRA_DIST) info
@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)

63
libsframe/configure vendored
View File

@@ -643,6 +643,10 @@ INSTALL_LIBBFD_TRUE
MAINT
MAINTAINER_MODE_FALSE
MAINTAINER_MODE_TRUE
HAVE_LD_VERSION_SCRIPT_FALSE
HAVE_LD_VERSION_SCRIPT_TRUE
HAVE_SOLARIS_LD_FALSE
HAVE_SOLARIS_LD_TRUE
BUILD_INFO_FALSE
BUILD_INFO_TRUE
COMPAT_DEJAGNU
@@ -11482,7 +11486,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
#line 11485 "configure"
#line 11489 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -11588,7 +11592,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 11595 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -12335,6 +12339,53 @@ else
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if using Solaris linker" >&5
$as_echo_n "checking if using Solaris linker... " >&6; }
SLD=`$LD --version 2>&1 | grep Solaris`
if test "$SLD"; then
have_solaris_ld=yes
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
else
have_solaris_ld=no
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
if test "$have_solaris_ld" = "yes"; then
HAVE_SOLARIS_LD_TRUE=
HAVE_SOLARIS_LD_FALSE='#'
else
HAVE_SOLARIS_LD_TRUE='#'
HAVE_SOLARIS_LD_FALSE=
fi
if test "$have_solaris_ld" = "yes"; then
GLD=`$LD --help < /dev/null 2>&1 | grep 'M mapfile'`
else
GLD=`$LD --help < /dev/null 2>/dev/null | grep version-script`
fi
if test "$GLD"; then
have_ld_version_script=yes
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
else
have_ld_version_script=no
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: *** Versioned symbols not enabled." >&5
$as_echo "$as_me: WARNING: *** Versioned symbols not enabled." >&2;}
fi
if test "$have_ld_version_script" = "yes"; then
HAVE_LD_VERSION_SCRIPT_TRUE=
HAVE_LD_VERSION_SCRIPT_FALSE='#'
else
HAVE_LD_VERSION_SCRIPT_TRUE='#'
HAVE_LD_VERSION_SCRIPT_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; }
@@ -12810,6 +12861,14 @@ 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 "${HAVE_SOLARIS_LD_TRUE}" && test -z "${HAVE_SOLARIS_LD_FALSE}"; then
as_fn_error $? "conditional \"HAVE_SOLARIS_LD\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
fi
if test -z "${HAVE_LD_VERSION_SCRIPT_TRUE}" && test -z "${HAVE_LD_VERSION_SCRIPT_FALSE}"; then
as_fn_error $? "conditional \"HAVE_LD_VERSION_SCRIPT\" 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

View File

@@ -81,6 +81,34 @@ else
fi
AM_CONDITIONAL(BUILD_INFO, test "${build_info}" = yes)
dnl Determine if using Solaris linker
AC_MSG_CHECKING([if using Solaris linker])
SLD=`$LD --version 2>&1 | grep Solaris`
if test "$SLD"; then
have_solaris_ld=yes
AC_MSG_RESULT(yes)
else
have_solaris_ld=no
AC_MSG_RESULT(no)
fi
AM_CONDITIONAL(HAVE_SOLARIS_LD, test "$have_solaris_ld" = "yes")
if test "$have_solaris_ld" = "yes"; then
GLD=`$LD --help < /dev/null 2>&1 | grep 'M mapfile'`
else
GLD=`$LD --help < /dev/null 2>/dev/null | grep version-script`
fi
if test "$GLD"; then
have_ld_version_script=yes
AC_MSG_RESULT(yes)
else
have_ld_version_script=no
AC_MSG_RESULT(no)
AC_MSG_WARN(*** Versioned symbols not enabled.)
fi
AM_CONDITIONAL(HAVE_LD_VERSION_SCRIPT, test "$have_ld_version_script" = "yes")
AM_MAINTAINER_MODE
AM_INSTALL_LIBBFD

36
libsframe/libsframe.ver Normal file
View File

@@ -0,0 +1,36 @@
LIBSFRAME_0.0 { };
LIBSFRAME_1.0 {
global:
sframe_decoder_free;
sframe_fde_create_func_info;
sframe_calc_fre_type;
sframe_fre_get_base_reg_id;
sframe_fre_get_cfa_offset;
sframe_fre_get_fp_offset;
sframe_fre_get_ra_offset;
sframe_fre_get_ra_mangled_p;
sframe_decode;
sframe_decoder_get_hdr_size;
sframe_decoder_get_abi_arch;
sframe_decoder_get_fixed_fp_offset;
sframe_decoder_get_fixed_ra_offset;
sframe_get_funcdesc_with_addr;
sframe_find_fre;
sframe_decoder_get_num_fidx;
sframe_decoder_get_funcdesc;
sframe_decoder_get_fre;
sframe_encode;
sframe_encoder_free;
sframe_encoder_get_hdr_size;
sframe_encoder_get_abi_arch;
sframe_encoder_get_num_fidx;
sframe_encoder_add_fre;
sframe_encoder_add_funcdesc;
sframe_encoder_write;
dump_sframe;
sframe_errmsg;
local:
*;
} LIBSFRAME_0.0;

30
libsframe/libtool-version Normal file
View File

@@ -0,0 +1,30 @@
# This file is used to maintain libtool version info for libsframe. See
# the libtool manual to understand the meaning of the fields. This is
# a separate file so that version updates don't involve re-running
# automake.
#
# Here are a set of rules to help you update your library version
# information:
#
# 1. Start with version information of `0:0:0' for each libtool library.
#
# 2. Update the version information only immediately before a public
# release of your software. More frequent updates are unnecessary,
# and only guarantee that the current interface number gets larger
# faster.
#
# 3. If the library source code has changed at all since the last
# update, then increment revision (`c:r:a' becomes `c:r+1:a').
#
# 4. If any interfaces have been added, removed, or changed since the
# last update, increment current, and set revision to 0.
#
# 5. Increase the age value only if the changes made to the ABI are backward
# compatible.
# a. If any interfaces have been added since the last public release,
# then increment age.
# b. If any interfaces have been removed since the last public release,
# then set age to 0.
#
# CURRENT:REVISION:AGE
1:0:0

View File

@@ -32,9 +32,9 @@ is_sframe_abi_arch_aarch64 (sframe_decoder_ctx *sfd_ctx)
{
bool aarch64_p = false;
unsigned char abi_arch = sframe_decoder_get_abi_arch (sfd_ctx);
if ((abi_arch == SFRAME_ABI_AARCH64_ENDIAN_BIG)
|| (abi_arch == SFRAME_ABI_AARCH64_ENDIAN_LITTLE))
uint8_t abi_arch = sframe_decoder_get_abi_arch (sfd_ctx);
if (abi_arch == SFRAME_ABI_AARCH64_ENDIAN_BIG
|| abi_arch == SFRAME_ABI_AARCH64_ENDIAN_LITTLE)
aarch64_p = true;
return aarch64_p;
@@ -105,7 +105,7 @@ dump_sframe_func_with_fres (sframe_decoder_ctx *sfd_ctx,
int32_t cfa_offset = 0;
int32_t fp_offset = 0;
int32_t ra_offset = 0;
unsigned int base_reg_id = 0;
uint8_t base_reg_id = 0;
int err[3] = {0, 0, 0};
sframe_frame_row_entry fre;
@@ -164,11 +164,15 @@ dump_sframe_func_with_fres (sframe_decoder_ctx *sfd_ctx,
strcpy (temp, "u");
printf ("%-10s", temp);
/* Dump RA info. */
if (err[2] == 0)
sprintf (temp, "c%+d", ra_offset);
else
/* Dump RA info.
If an ABI does not track RA offset, e.g., AMD64, display a 'u',
else display the offset d as 'c+-d'. */
if (sframe_decoder_get_fixed_ra_offset(sfd_ctx)
!= SFRAME_CFA_FIXED_RA_INVALID)
strcpy (temp, "u");
else if (err[2] == 0)
sprintf (temp, "c%+d", ra_offset);
/* Mark SFrame FRE's RA information with "[s]" if the RA is mangled
with signature bits. */
const char *ra_mangled_p_str

View File

@@ -132,19 +132,19 @@ sframe_get_fre_ra_mangled_p (uint8_t fre_info)
/* Access functions for info from function descriptor entry. */
static unsigned int
static uint32_t
sframe_get_fre_type (sframe_func_desc_entry *fdep)
{
unsigned int fre_type = 0;
uint32_t fre_type = 0;
if (fdep)
fre_type = SFRAME_V1_FUNC_FRE_TYPE (fdep->sfde_func_info);
return fre_type;
}
static unsigned int
static uint32_t
sframe_get_fde_type (sframe_func_desc_entry *fdep)
{
unsigned int fde_type = 0;
uint32_t fde_type = 0;
if (fdep)
fde_type = SFRAME_V1_FUNC_FDE_TYPE (fdep->sfde_func_info);
return fde_type;
@@ -221,7 +221,7 @@ sframe_header_sanity_check_p (sframe_header *hp)
/* Flip the start address pointed to by FP. */
static void
flip_fre_start_address (char *addr, unsigned int fre_type)
flip_fre_start_address (char *addr, uint32_t fre_type)
{
if (fre_type == SFRAME_FRE_TYPE_ADDR2)
{
@@ -257,7 +257,7 @@ flip_fre_stack_offsets (char *offsets, uint8_t offset_size, uint8_t offset_cnt)
/* Get the FRE start address size, given the FRE_TYPE. */
static size_t
sframe_fre_start_addr_size (unsigned int fre_type)
sframe_fre_start_addr_size (uint32_t fre_type)
{
size_t addr_size = 0;
switch (fre_type)
@@ -329,7 +329,7 @@ sframe_fre_offset_bytes_size (uint8_t fre_info)
includes the starting address, FRE info, and all the offsets. */
static size_t
sframe_fre_entry_size (sframe_frame_row_entry *frep, unsigned int fre_type)
sframe_fre_entry_size (sframe_frame_row_entry *frep, uint32_t fre_type)
{
if (frep == NULL)
return 0;
@@ -363,7 +363,7 @@ sframe_decoder_get_funcdesc_at_index (sframe_decoder_ctx *ctx,
}
static int
flip_fre (char *fp, unsigned int fre_type, size_t *fre_size)
flip_fre (char *fp, uint32_t fre_type, size_t *fre_size)
{
uint8_t fre_info;
uint8_t offset_size, offset_cnt;
@@ -416,7 +416,7 @@ flip_sframe (char *frame_buf, size_t buf_size, uint32_t to_foreign)
sframe_func_desc_entry *fdep;
unsigned int num_fdes = 0;
unsigned int num_fres = 0;
unsigned int fre_type = 0;
uint32_t fre_type = 0;
uint32_t fre_offset = 0;
size_t esz = 0;
size_t hdrsz = 0;
@@ -585,8 +585,8 @@ sframe_decoder_free (sframe_decoder_ctx **dctxp)
/* FIXME API for linker. Revisit if its better placed somewhere else? */
unsigned char
sframe_fde_create_func_info (unsigned int fre_type,
unsigned int fde_type)
sframe_fde_create_func_info (uint32_t fre_type,
uint32_t fde_type)
{
unsigned char func_info;
sframe_assert (fre_type == SFRAME_FRE_TYPE_ADDR1
@@ -601,10 +601,10 @@ sframe_fde_create_func_info (unsigned int fre_type,
/* Get the FRE type given the function size. */
/* FIXME API for linker. Revisit if its better placed somewhere else? */
unsigned int
uint32_t
sframe_calc_fre_type (size_t func_size)
{
unsigned int fre_type = 0;
uint32_t fre_type = 0;
if (func_size < SFRAME_FRE_TYPE_ADDR1_LIMIT)
fre_type = SFRAME_FRE_TYPE_ADDR1;
else if (func_size < SFRAME_FRE_TYPE_ADDR2_LIMIT)
@@ -618,7 +618,7 @@ sframe_calc_fre_type (size_t func_size)
/* Get the base reg id from the FRE info. Set errp if failure. */
unsigned int
uint8_t
sframe_fre_get_base_reg_id (sframe_frame_row_entry *fre, int *errp)
{
if (fre == NULL)
@@ -644,16 +644,21 @@ sframe_fre_get_fp_offset (sframe_decoder_ctx *dctx,
sframe_frame_row_entry *fre, int *errp)
{
uint32_t fp_offset_idx = 0;
sframe_header *dhp = sframe_decoder_get_header (dctx);
/* If the FP offset is not being tracked, return an error code so the caller
can gather the fixed FP offset from the SFrame header. */
if (dhp->sfh_cfa_fixed_fp_offset != SFRAME_CFA_FIXED_FP_INVALID)
return sframe_set_errno (errp, SFRAME_ERR_FREOFFSET_NOPRESENT);
int8_t fp_offset = sframe_decoder_get_fixed_fp_offset (dctx);
/* If the FP offset is not being tracked, return the fixed FP offset
from the SFrame header. */
if (fp_offset != SFRAME_CFA_FIXED_FP_INVALID)
{
if (errp)
*errp = 0;
return fp_offset;
}
/* In some ABIs, the stack offset to recover RA (using the CFA) from is
fixed (like AMD64). In such cases, the stack offset to recover FP will
appear at the second index. */
fp_offset_idx = ((dhp->sfh_cfa_fixed_ra_offset != SFRAME_CFA_FIXED_RA_INVALID)
fp_offset_idx = ((sframe_decoder_get_fixed_ra_offset (dctx)
!= SFRAME_CFA_FIXED_RA_INVALID)
? SFRAME_FRE_RA_OFFSET_IDX
: SFRAME_FRE_FP_OFFSET_IDX);
return sframe_get_fre_offset (fre, fp_offset_idx, errp);
@@ -665,11 +670,15 @@ int32_t
sframe_fre_get_ra_offset (sframe_decoder_ctx *dctx,
sframe_frame_row_entry *fre, int *errp)
{
sframe_header *dhp = sframe_decoder_get_header (dctx);
/* If the RA offset was not being tracked, return an error code so the caller
can gather the fixed RA offset from the SFrame header. */
if (dhp->sfh_cfa_fixed_ra_offset != SFRAME_CFA_FIXED_RA_INVALID)
return sframe_set_errno (errp, SFRAME_ERR_FREOFFSET_NOPRESENT);
int8_t ra_offset = sframe_decoder_get_fixed_ra_offset (dctx);
/* If the RA offset was not being tracked, return the fixed RA offset
from the SFrame header. */
if (ra_offset != SFRAME_CFA_FIXED_RA_INVALID)
{
if (errp)
*errp = 0;
return ra_offset;
}
/* Otherwise, get the RA offset from the FRE. */
return sframe_get_fre_offset (fre, SFRAME_FRE_RA_OFFSET_IDX, errp);
@@ -708,7 +717,7 @@ sframe_frame_row_entry_copy (sframe_frame_row_entry *dst,
static int
sframe_decode_fre_start_address (const char *fre_buf,
uint32_t *fre_start_addr,
unsigned int fre_type)
uint32_t fre_type)
{
uint32_t saddr = 0;
int err = 0;
@@ -753,7 +762,7 @@ sframe_decode_fre_start_address (const char *fre_buf,
static int
sframe_decode_fre (const char *fre_buf, sframe_frame_row_entry *fre,
unsigned int fre_type, size_t *esz)
uint32_t fre_type, size_t *esz)
{
int err = 0;
const char *stack_offsets = NULL;
@@ -924,7 +933,7 @@ sframe_decoder_get_hdr_size (sframe_decoder_ctx *ctx)
/* Get the SFrame's abi/arch info given the decoder context CTX. */
unsigned char
uint8_t
sframe_decoder_get_abi_arch (sframe_decoder_ctx *ctx)
{
sframe_header *sframe_header;
@@ -950,12 +959,24 @@ sframe_decoder_get_fixed_ra_offset (sframe_decoder_ctx *ctx)
return dhp->sfh_cfa_fixed_ra_offset;
}
/* Find the function descriptor entry which contains the specified address
ADDR.
This function is deprecated and will be removed from libsframe.so.2. */
void *
sframe_get_funcdesc_with_addr (sframe_decoder_ctx *ctx __attribute__ ((unused)),
int32_t addr __attribute__ ((unused)),
int *errp)
{
return sframe_ret_set_errno (errp, SFRAME_ERR_INVAL);
}
/* Find the function descriptor entry starting which contains the specified
address ADDR. */
sframe_func_desc_entry *
sframe_get_funcdesc_with_addr (sframe_decoder_ctx *ctx,
int32_t addr, int *errp)
static sframe_func_desc_entry *
sframe_get_funcdesc_with_addr_internal (sframe_decoder_ctx *ctx, int32_t addr,
int *errp)
{
sframe_header *dhp;
sframe_func_desc_entry *fdp;
@@ -1035,7 +1056,7 @@ sframe_find_fre (sframe_decoder_ctx *ctx, int32_t pc,
{
sframe_frame_row_entry cur_fre;
sframe_func_desc_entry *fdep;
unsigned int fre_type, fde_type;
uint32_t fre_type, fde_type;
uint32_t end_ip_offset, i;
int32_t start_ip, end_ip;
int32_t func_start_addr;
@@ -1053,7 +1074,7 @@ sframe_find_fre (sframe_decoder_ctx *ctx, int32_t pc,
return sframe_set_errno (&err, SFRAME_ERR_INVAL);
/* Find the FDE which contains the PC, then scan its fre entries. */
fdep = sframe_get_funcdesc_with_addr (ctx, pc, &err);
fdep = sframe_get_funcdesc_with_addr_internal (ctx, pc, &err);
if (fdep == NULL || ctx->sfd_fres == NULL)
return sframe_set_errno (&err, SFRAME_ERR_DCTX_INVAL);
@@ -1157,7 +1178,7 @@ sframe_decoder_get_fre (sframe_decoder_ctx *ctx,
sframe_frame_row_entry ifre;
const char *fres;
uint32_t i;
unsigned int fre_type;
uint32_t fre_type;
size_t esz = 0;
int err = 0;
@@ -1301,10 +1322,10 @@ sframe_encoder_get_hdr_size (sframe_encoder_ctx *encoder)
/* Get the abi/arch info from the SFrame encoder context ENCODER. */
unsigned char
uint8_t
sframe_encoder_get_abi_arch (sframe_encoder_ctx *encoder)
{
unsigned char abi_arch = 0;
uint8_t abi_arch = 0;
sframe_header *ehp;
ehp = sframe_encoder_get_header (encoder);
if (ehp)
@@ -1338,7 +1359,7 @@ sframe_encoder_add_fre (sframe_encoder_ctx *encoder,
sframe_func_desc_entry *fdep;
sframe_frame_row_entry *ectx_frep;
size_t offsets_sz, esz;
unsigned int fre_type;
uint32_t fre_type;
size_t fre_tbl_sz;
int err = 0;
@@ -1484,7 +1505,7 @@ sframe_encoder_add_funcdesc (sframe_encoder_ctx *encoder,
= encoder->sfe_fre_nbytes;
#if 0
// Linker optimization test code cleanup later ibhagat TODO FIXME
unsigned int fre_type = sframe_calc_fre_type (func_size);
uint32_t fre_type = sframe_calc_fre_type (func_size);
fd_info->entry[fd_info->count].sfde_func_info
= sframe_fde_func_info (fre_type);
@@ -1528,7 +1549,7 @@ sframe_sort_funcdesc (sframe_encoder_ctx *encoder)
static int
sframe_encoder_write_fre_start_addr (char *contents,
uint32_t fre_start_addr,
unsigned int fre_type,
uint32_t fre_type,
size_t fre_start_addr_sz)
{
int err = 0;
@@ -1563,7 +1584,7 @@ sframe_encoder_write_fre_start_addr (char *contents,
static int
sframe_encoder_write_fre (char *contents, sframe_frame_row_entry *frep,
unsigned int fre_type, size_t *esz)
uint32_t fre_type, size_t *esz)
{
size_t fre_sz;
size_t fre_start_addr_sz;
@@ -1623,7 +1644,7 @@ sframe_encoder_write_sframe (sframe_encoder_ctx *encoder)
sframe_func_desc_entry *fdep;
sframe_frame_row_entry *frep;
unsigned int fre_type;
uint32_t fre_type;
int err = 0;
contents = encoder->sfe_data;