Add --no-write-default-sizes option.

abidw will write out the exact same size-in-bits address for every
pointer type, reference type, function declaration and function type
even though it is always the same as the translation unit address
size. When giving the --no-write-default-sizes option these aren't
written out anymore. The reader is updated to set the default size
when none is given in the XML description.

Even though size and alignment are handled together in the reader,
default alignment is still set to zero, following commit a05384675

Note that this isn't backward compatible with older libabigail
readers, which will set the size to zero when none is given. So this
option isn't the default.

	* doc/manuals/abidw.rst: Document --no-write-default-sizes.
	* include/abg-writer.h (set_write_default_sizes): New function
	declaration.
	(set_common_options): Call set_write_default_sizes.
	* src/abg-reader.cc (build_function_decl): Get default size.
	(build_pointer_type_def): Likewise.
	(build_reference_type_def): Likewise.
	(build_function_type): Likewise.
	* src/abg-writer.cc (write_context): Add m_write_default_sizes
	bool.
	(get_write_default_sizes): New method.
	(set_write_default_sizes): Likewise.
	(write_size_and_alignment): Add default size and alignment
	parameters.
	(set_write_default_sizes): New function.
	(write_type_decl): Set default size and alignment.
	(write_pointer_type_def): Likewise.
	(write_reference_type_def): Likewise.
	(write_function_decl): Likewise.
	(write_function_type): Likewise.
	(write_class_decl_opening_tag): Likewise.
	(write_union_decl_opening_tag): Likewise.
	* tests/test-types-stability.cc (perform): Also test --abidiff
	with --no-write-default-sizes.
	* tools/abidw.cc (option): Add default_sizes bool.
	(parse_command_line): Parse --no-write-default-sizes.
	(display_usage): Add doc string for --no-write-default-sizes.

Signed-off-by: Mark Wielaard <mark@klomp.org>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
This commit is contained in:
Mark Wielaard 2020-04-27 01:28:52 +02:00 committed by Dodji Seketeli
parent 440fc7f4be
commit a9f5fb4089
6 changed files with 102 additions and 21 deletions

View File

@ -188,6 +188,15 @@ Options
In the emitted ABI representation, do not show names of function
parameters, just the types.
* ``--no-write-default-sizes``
In the XML ABI representation, do not write the size-in-bits for
pointer type definitions, reference type definitions, function
declarations and function types when they are equal to the default
address size of the translation unit. Note that libabigail before
1.8 will not set the default size and will interpret types without
a size-in-bits attribute as zero sized.
* ``--named-type-ids``
Without this option ids used to reference types in the XML file

View File

@ -65,6 +65,9 @@ set_write_comp_dir(write_context& ctxt, bool flag);
void
set_write_elf_needed(write_context& ctxt, bool flag);
void
set_write_default_sizes(write_context& ctxt, bool flag);
void
set_short_locs(write_context& ctxt, bool flag);
@ -92,6 +95,7 @@ set_common_options(write_context& ctxt, const OPTS& opts)
set_write_elf_needed(ctxt, opts.write_elf_needed);
set_write_parameter_names(ctxt, opts.write_parameter_names);
set_short_locs(ctxt, opts.short_locs);
set_write_default_sizes(ctxt, opts.default_sizes);
}
void

View File

@ -3154,7 +3154,7 @@ build_function_decl(read_context& ctxt,
decl_base::binding bind = decl_base::BINDING_NONE;
read_binding(node, bind);
size_t size = 0, align = 0;
size_t size = ctxt.get_translation_unit()->get_address_size(), align = 0;
read_size_and_alignment(node, size, align);
location loc;
@ -3677,11 +3677,9 @@ build_pointer_type_def(read_context& ctxt,
return result;
}
size_t size_in_bits = 0, alignment_in_bits = 0;
if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "size-in-bits"))
size_in_bits = atoi(CHAR_STR(s));
if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "alignment-in-bits"))
alignment_in_bits = atoi(CHAR_STR(s));
size_t size_in_bits = ctxt.get_translation_unit()->get_address_size();
size_t alignment_in_bits = 0;
read_size_and_alignment(node, size_in_bits, alignment_in_bits);
string id;
if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "id"))
@ -3765,11 +3763,9 @@ build_reference_type_def(read_context& ctxt,
return result;
}
size_t size_in_bits = 0, alignment_in_bits = 0;
if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "size-in-bits"))
size_in_bits = atoi(CHAR_STR(s));
if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "alignment-in-bits"))
alignment_in_bits = atoi(CHAR_STR(s));
size_t size_in_bits = ctxt.get_translation_unit()->get_address_size();
size_t alignment_in_bits = 0;
read_size_and_alignment(node, size_in_bits, alignment_in_bits);
string id;
if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "id"))
@ -3834,7 +3830,7 @@ build_function_type(read_context& ctxt,
bool is_method_t = !method_class_id.empty();
size_t size = 0, align = 0;
size_t size = ctxt.get_translation_unit()->get_address_size(), align = 0;
read_size_and_alignment(node, size, align);
environment* env = ctxt.get_environment();

View File

@ -176,6 +176,7 @@ class write_context
bool m_write_elf_needed;
bool m_write_parameter_names;
bool m_short_locs;
bool m_write_default_sizes;
mutable type_ptr_map m_type_id_map;
mutable type_ptr_set_type m_emitted_type_set;
type_ptr_set_type m_emitted_decl_only_set;
@ -212,7 +213,8 @@ public:
m_write_comp_dir(true),
m_write_elf_needed(true),
m_write_parameter_names(true),
m_short_locs(false)
m_short_locs(false),
m_write_default_sizes(true)
{}
/// Getter of the environment we are operating from.
@ -282,6 +284,20 @@ public:
set_write_elf_needed(bool f)
{m_write_elf_needed = f;}
/// Getter of the default-sizes option.
///
/// @return true iff default size-in-bits needs to be emitted
bool
get_write_default_sizes()
{return m_write_default_sizes;}
/// Setter of the default-sizes option.
///
/// @param f the new value of the flag.
void
set_write_default_sizes(bool f)
{m_write_default_sizes = f;}
/// Getter of the write-corpus-path option.
///
/// @return true iff corpus-path information shall be emitted
@ -809,7 +825,9 @@ static bool write_is_non_reachable(const type_base_sptr&, ostream&);
static bool write_tracking_non_reachable_types(const corpus_sptr&, ostream&);
static void write_array_size_and_alignment(const array_type_def_sptr,
ostream&);
static void write_size_and_alignment(const type_base_sptr, ostream&);
static void write_size_and_alignment(const type_base_sptr, ostream&,
size_t default_size = 0,
size_t default_alignment = 0);
static void write_access(access_specifier, ostream&);
static void write_layout_offset(var_decl_sptr, ostream&);
static void write_layout_offset(class_decl::base_spec_sptr, ostream&);
@ -1396,15 +1414,24 @@ write_tracking_non_reachable_types(const corpus_sptr& corpus,
/// @param decl the type to consider.
///
/// @param o the output stream to serialize to.
///
/// @param default_size size in bits that is the default for the type.
/// No size-in-bits attribute is written if it
/// would be the default value.
///
/// @param default_alignment alignment in bits that is the default for
/// the type. No alignment-in-bits attribute is
/// written if it would be the default value.
static void
write_size_and_alignment(const shared_ptr<type_base> decl, ostream& o)
write_size_and_alignment(const shared_ptr<type_base> decl, ostream& o,
size_t default_size, size_t default_alignment)
{
size_t size_in_bits = decl->get_size_in_bits();
if (size_in_bits)
if (size_in_bits != default_size)
o << " size-in-bits='" << size_in_bits << "'";
size_t alignment_in_bits = decl->get_alignment_in_bits();
if (alignment_in_bits)
if (alignment_in_bits != default_alignment)
o << " alignment-in-bits='" << alignment_in_bits << "'";
}
@ -2089,6 +2116,21 @@ void
set_write_elf_needed(write_context& ctxt, bool flag)
{ctxt.set_write_elf_needed(flag);}
/// Set the 'default-sizes' flag.
///
/// When this flag is set then the XML writer will emit default
/// size-in-bits attributes for pointer type definitions, reference
/// type definitions, function declarations and function types even
/// when they are equal to the default address size of the translation
/// unit.
///
/// @param ctxt the context to set this flag on to.
///
/// @param flag the new value of the 'default-sizes' flag.
void
set_write_default_sizes(write_context& ctxt, bool flag)
{ctxt.set_write_default_sizes(flag);}
/// Serialize the canonical types of a given scope.
///
/// @param scope the scope to consider.
@ -2545,7 +2587,11 @@ write_pointer_type_def(const pointer_type_def_sptr& decl,
ctxt.record_type_as_referenced(pointed_to_type);
write_size_and_alignment(decl, o);
write_size_and_alignment(decl, o,
(ctxt.get_write_default_sizes()
? 0
: decl->get_translation_unit()->get_address_size()),
0);
string i = id;
if (i.empty())
@ -2623,7 +2669,11 @@ write_reference_type_def(const reference_type_def_sptr& decl,
if (function_type_sptr f = is_function_type(decl->get_pointed_to_type()))
ctxt.record_type_as_referenced(f);
write_size_and_alignment(decl, o);
write_size_and_alignment(decl, o,
(ctxt.get_write_default_sizes()
? 0
: decl->get_translation_unit()->get_address_size()),
0);
string i = id;
if (i.empty())
@ -3171,7 +3221,11 @@ write_function_decl(const function_decl_sptr& decl, write_context& ctxt,
write_binding(decl, o);
write_size_and_alignment(decl->get_type(), o);
write_size_and_alignment(decl->get_type(), o,
(ctxt.get_write_default_sizes()
? 0
: decl->get_translation_unit()->get_address_size()),
0);
write_elf_symbol_reference(decl->get_symbol(), o);
o << ">\n";
@ -3251,7 +3305,11 @@ write_function_type(const function_type_sptr& fn_type,
o << "<function-type";
write_size_and_alignment(fn_type, o);
write_size_and_alignment(fn_type, o,
(ctxt.get_write_default_sizes()
? 0
: fn_type->get_translation_unit()->get_address_size()),
0);
if (method_type_sptr method_type = is_method_type(fn_type))
{

View File

@ -102,6 +102,14 @@ struct test_task : public abigail::workers::task
error_message = "IR stability issue detected for binary " + elf_path;
is_ok = false;
}
cmd = abidw + " --abidiff --no-write-default-sizes " + elf_path;
if (system(cmd.c_str()))
{
error_message = "IR stability issue detected for binary " + elf_path
+ " with --no-write-default-sizes";
is_ok = false;
}
}
}; // end struct test_task

View File

@ -102,6 +102,7 @@ struct options
bool write_elf_needed;
bool write_parameter_names;
bool short_locs;
bool default_sizes;
bool load_all_types;
bool linux_kernel_mode;
bool corpus_group_for_linux;
@ -124,6 +125,7 @@ struct options
write_elf_needed(true),
write_parameter_names(true),
short_locs(false),
default_sizes(true),
load_all_types(),
linux_kernel_mode(true),
corpus_group_for_linux(false),
@ -170,6 +172,8 @@ display_usage(const string& prog_name, ostream& out)
<< " --drop-undefined-syms drop undefined symbols from representation\n"
<< " --no-comp-dir-path do not show compilation path information\n"
<< " --no-elf-needed do not show the DT_NEEDED information\n"
<< " --no-write-default-sizes do not emit pointer size when it equals"
" the default address size of the translation unit\n"
<< " --no-parameter-names do not show names of function parameters\n"
<< " --check-alternate-debug-info <elf-path> check alternate debug info "
"of <elf-path>\n"
@ -293,6 +297,8 @@ parse_command_line(int argc, char* argv[], options& opts)
opts.write_comp_dir = false;
else if (!strcmp(argv[i], "--no-elf-needed"))
opts.write_elf_needed = false;
else if (!strcmp(argv[i], "--no-write-default-sizes"))
opts.default_sizes = false;
else if (!strcmp(argv[i], "--no-parameter-names"))
opts.write_parameter_names = false;
else if (!strcmp(argv[i], "--check-alternate-debug-info")