@@ -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
@@ -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
@@ -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();
@@ -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,
+ size_t default_alignment);
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.
@@ -2366,7 +2408,7 @@ write_type_decl(const type_decl_sptr& d, write_context& ctxt, unsigned indent)
write_is_anonymous(d, o);
- write_size_and_alignment(d, o);
+ write_size_and_alignment(d, o, 0, 0);
write_location(d, ctxt);
@@ -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))
{
@@ -3352,7 +3410,7 @@ write_class_decl_opening_tag(const class_decl_sptr& decl,
o << "<class-decl name='" << xml::escape_xml_string(decl->get_name()) << "'";
- write_size_and_alignment(decl, o);
+ write_size_and_alignment(decl, o, 0, 0);
write_is_struct(decl, o);
@@ -3430,7 +3488,7 @@ write_union_decl_opening_tag(const union_decl_sptr& decl,
o << "<union-decl name='" << xml::escape_xml_string(decl->get_name()) << "'";
if (!decl->get_is_declaration_only())
- write_size_and_alignment(decl, o);
+ write_size_and_alignment(decl, o, 0, 0);
write_is_anonymous(decl, o);
@@ -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
@@ -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),
@@ -293,6 +295,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")