libabigail/include/abg-writer.h
Giuliano Procida 29de666641 abg-writer: Add support for stable hash type ids.
The type ids currently emitted by the XML writer are simply type-id-1,
type-id-2 etc. Additions or removals of types early in this sequence
result in cascading changes to many other XML elements.

This commit adds support for stable type ids in the form of hashes of
libabigail's internal type names. On fairly rare occasions (typically
involving unnamed types), the names of two distinct types can be the
same. In any case, if there is a hash collision the XML writer will
find the next unused id and so preserve uniqueness.

Diffs between large XML files produced using --type-id-style hash will
be much smaller and easier to review.

This also commit adds some test cases to verify that the hashing is
actually stable across architectures.

	* doc/manuals/abidw.rst: Replace stray documentation of
	--named-type-ids with documention of new --type-id-style
	option.
	* include/abg-writer.h (type_id_style_kind): Add new enum.
	(set_type_id_style): Add new write_context setter.
	(set_common_options): Set type id style in write context.
	* include/abg-hash.h (fnv_hash): Declare new 32-bit FNV-1a
        hash function in abigail::hashing namespace.
	* src/abg-hash.h (fnv_hash): Define new 32-bit FNV-1a hash
        function in abigail::hashing namespace.
	* src/abg-writer.cc (write_context): Add m_type_id_style
        member to record type style to use, defaulting to
        SEQUENCE_TYPE_ID_STYLE; add m_used_type_id_hashes to record
        already-used hashes.
	(write_context::get_type_id_style): Add new getter.
	(write_context::set_type_id_style): Add new setter.
	(get_id_for_type): Add support for HASH_TYPE_ID_STYLE style.
	(set_type_id_style): Add new helper function.
	* tools/abidw.cc (options): Add type_id_style member.
	(display_usage): Add description of --type-id-style option.
	(parse_command_line): Parse --type-id-style option.
	* tests/data/Makefile.am: Add new hash type id ABI files.
	* tests/test-read-dwarf.cc: (InOutSpec): Add type_id_style
	member.
	(in_out_specs): Set type_id_style to SEQUENCE_TYPE_ID_STYLE in
        existing test specifications. Duplicate first 9 test cases
        with type_id_style set to HASH_TYPE_ID_STYLE.
	* tests/data/test-read-dwarf/test0.hash.abi: New ABI XML file
	with hash type ids.
	* tests/data/test-read-dwarf/test1.hash.abi: Ditto.
	* tests/data/test-read-dwarf/test2.so.hash.abi: Ditto.
	* tests/data/test-read-dwarf/test3.so.hash.abi: Ditto.
	* tests/data/test-read-dwarf/test4.so.hash.abi: Ditto.
	* tests/data/test-read-dwarf/test5.o.hash.abi: Ditto.
	* tests/data/test-read-dwarf/test6.so.hash.abi: Ditto.
	* tests/data/test-read-dwarf/test7.so.hash.abi: Ditto.
	* tests/data/test-read-dwarf/test8-qualified-this-pointer.so.hash.abi:
	Ditto.

Signed-off-by: Giuliano Procida <gprocida@google.com>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2020-06-16 10:13:01 +02:00

148 lines
3.9 KiB
C++

// -*- Mode: C++ -*-
//
// Copyright (C) 2013-2020 Red Hat, Inc.
//
// This file is part of the GNU Application Binary Interface Generic
// Analysis and Instrumentation Library (libabigail). This library is
// free software; you can redistribute it and/or modify it under the
// terms of the GNU Lesser General Public License as published by the
// Free Software Foundation; either version 3, or (at your option) any
// later version.
// This library 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 Lesser Public License for more details.
// You should have received a copy of the GNU Lesser General Public
// License along with this program; see the file COPYING-LGPLV3. If
// not, see <http://www.gnu.org/licenses/>.
//
// Author: Dodji Seketeli
/// @file
///
/// This file contains the declarations of the entry points to
/// de-serialize an instance of @ref abigail::translation_unit to an
/// ABI Instrumentation file in libabigail native XML format.
#ifndef __ABG_WRITER_H__
#define __ABG_WRITER_H__
#include "abg-fwd.h"
namespace abigail
{
namespace xml_writer
{
using namespace abigail::ir;
/// The style of type id the XML writer will output.
enum type_id_style_kind
{
SEQUENCE_TYPE_ID_STYLE,
HASH_TYPE_ID_STYLE
};
class write_context;
/// A convenience typedef for a shared pointer to write_context.
typedef shared_ptr<write_context> write_context_sptr;
write_context_sptr
create_write_context(const environment *env,
ostream& output_stream);
void
set_show_locs(write_context& ctxt, bool flag);
void
set_annotate(write_context& ctxt, bool flag);
void
set_write_architecture(write_context& ctxt, bool flag);
void
set_write_corpus_path(write_context& ctxt, bool flag);
void
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);
void
set_write_parameter_names(write_context& ctxt, bool flag);
void
set_type_id_style(write_context& ctxt, type_id_style_kind style);
/// A convenience generic function to set common options (usually used
/// by Libabigail tools) from a generic options carrying-object, into
/// a given @ref write_context.
///
/// @param ctxt the @ref the write_context to consider.
///
/// @param opts the option-carrying object to set the options from.
/// It must contain data members named: annotate, and show_locs, at
/// very least.
template <typename OPTS>
void
set_common_options(write_context& ctxt, const OPTS& opts)
{
set_annotate(ctxt, opts.annotate);
set_show_locs(ctxt, opts.show_locs);
set_write_architecture(ctxt, opts.write_architecture);
set_write_corpus_path(ctxt, opts.write_corpus_path);
set_write_comp_dir(ctxt, opts.write_comp_dir);
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);
set_type_id_style(ctxt, opts.type_id_style);
}
void
set_ostream(write_context& ctxt, ostream& os);
bool
write_translation_unit(write_context& ctxt,
const translation_unit& tu,
const unsigned indent);
bool
write_corpus_to_archive(const corpus& corp,
const string& path,
const bool annotate = false);
bool
write_corpus_to_archive(const corpus& corp,
const bool annotate = false);
bool
write_corpus_to_archive(const corpus_sptr corp,
const bool annotate = false);
bool
write_corpus(write_context& ctxt,
const corpus_sptr& corpus,
unsigned indent,
bool member_of_group = false);
bool
write_corpus_group(write_context& ctx,
const corpus_group_sptr& group,
unsigned indent);
}// end namespace xml_writer
}// end namespace abigail
#endif // __ABG_WRITER_H__