From: Roland McGrath Date: Tue, 27 Jan 2009 11:27:58 +0000 (-0800) Subject: Comments; start dwarf_output class defn. X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=700d300ebbaaaa0e2c8e95286a3fa8b2c4c1808c;p=thirdparty%2Felfutils.git Comments; start dwarf_output class defn. --- diff --git a/libdw/c++/dwarf b/libdw/c++/dwarf index 4eda3bb54..9dd2a425f 100644 --- a/libdw/c++/dwarf +++ b/libdw/c++/dwarf @@ -128,16 +128,14 @@ of objects described above never exists in memory in its entirety. The objects are constructed on the fly in each call to a container method. - The output classes elfutils::dwarf_output are template-compatible with - the "logical view" interface above, but do not support any of the "raw" - container variants. These == and != comparisons are template-driven too, - so all different classes can be compared. + See the dwarf_edit and dwarf_output headers for other classes that are + template-compatible with the "logical view" interface above, but do not + support any of the "raw" container variants. These == and != comparisons + are template-driven too, so all different classes can be compared. The output classes have template-driven copy constructors, so they can be copied from files or substructures of the elfutils::dwarf input classes. - The elfutils::dwarf_output containers are mutable, unlike the input classes. - ------ XXX to be done: more file-level containers input side only (?): diff --git a/libdw/c++/dwarf_edit b/libdw/c++/dwarf_edit index 3c8daf15c..630a70921 100644 --- a/libdw/c++/dwarf_edit +++ b/libdw/c++/dwarf_edit @@ -1,4 +1,4 @@ -/* -*- C++ -*- interfaces for libdw. +/* elfutils::dwarf_edit -- mutable DWARF representation in -*- C++ -*- Copyright (C) 2009 Red Hat, Inc. This file is part of Red Hat elfutils. @@ -52,7 +52,28 @@ #include "dwarf" -// DWARF writer interfaces (pure object construction) +/* Read the comments for elfutils::dwarf first. + + The elfutils::dwarf_edit class is template-compatible with the logical + containers described in elfutils::dwarf, and copy-constructible from the + input class. + + The elfutils::dwarf_edit containers are mutable, unlike the input + classes. You can modify the DWARF directly in all the normal ways the + corresponding std containers have, or build it up from scratch. When + you have it how you want it, you can pass it into elfutils::dwarf_output. + + The dwarf_edit classes will use unreasonable amounts of memory for large + DWARF data sets, like from reading in whole large program and DSO files. + To transform input files efficiently, you should construct dwarf_output + directly from input dwarf with transformations applied on the fly, and + not use dwarf_edit at all. + + dwarf_edit is the only mutable representation and so it's easy to use in + a straightforward imperative style. Use it for transformations on small + data files, or for creating small data sets from scratch. */ + +// DWARF manipulation interfaces (pure object construction) namespace elfutils { class dwarf_edit diff --git a/libdw/c++/dwarf_output b/libdw/c++/dwarf_output new file mode 100644 index 000000000..d4d2ee611 --- /dev/null +++ b/libdw/c++/dwarf_output @@ -0,0 +1,224 @@ +/* elfutils::dwarf_output -- DWARF file generation in -*- C++ -*- + Copyright (C) 2009 Red Hat, Inc. + This file is part of Red Hat elfutils. + + Red Hat elfutils 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; version 2 of the License. + + Red Hat elfutils 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 Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + . */ + +#ifndef _ELFUTILS_DWARF_OUTPUT +#define _ELFUTILS_DWARF_OUTPUT 1 + +#include "dwarf" + +/* Read the comments for elfutils::dwarf first. + + The elfutils::dwarf_output class is template-compatible with the logical + containers described in elfutils::dwarf and elfutils::dwarf_edit. + + The dwarf_output representation of the DWARF data is immutable once + created. The only way to create the object is by copy-construction + from another compatible object: dwarf, dwarf_edit, or dwarf_output. + Construction collects all the information necessary to generate the + formatted DWARF sections. */ + +namespace elfutils +{ + class dwarf_output + { + public: + class compile_units; + + // XXX later + class attr_value : public dwarf::attr_value + { + public: + attr_value (const dwarf::attr_value &v) : dwarf::attr_value (v) {} + }; + + class debug_info_entry + { + public: + + class children : public std::vector + { + friend class debug_info_entry; + private: + children () {} + + template + children (const childrens &other) + : std::vector (other.begin (), other.end ()) {} + }; + + class attributes : public std::map + { + friend class debug_info_entry; + private: + attributes () {} + + template + attributes (const attrs &other) + : std::map (other.begin (), other.end ()) {} + + public: + template + inline operator attrs () const + { + return attrs (begin (), end ()); + } + }; + + private: + const int _m_tag; + const attributes _m_attributes; + const children _m_children; + + public: + /* The template constructor lets us copy in from any class that has + compatibly iterable containers for attributes and children. */ + template + debug_info_entry (const die &die) + : _m_tag (die.tag ()), + _m_attributes (die.attributes ()), + _m_children (die.children ()) + {} + + inline int tag () const + { + return _m_tag; + } + + inline bool has_children () const + { + return !_m_children.empty (); + } + + inline class children &children () + { + return _m_children; + } + inline const class children &children () const + { + return _m_children; + } + + inline class attributes &attributes () + { + return _m_attributes; + } + inline const class attributes &attributes () const + { + return _m_attributes; + } + + template + bool operator== (const die &other) const + { + return (other.attributes () == attributes () + && other.children () == children ()); + } + template + bool operator!= (const die &other) const + { + return !(*this == other);; + } + }; + + typedef debug_info_entry::attributes::value_type attribute; + + class compile_unit : public debug_info_entry + { + }; + + // Main container anchoring all the output. + class compile_units : public std::vector + { + friend class dwarf_output; + private: + // Constructor copying CUs from input container. + template + compile_units(const input &units) + : std::vector (units.begin (), units.end ()) + {} + + public: + template + bool operator== (const other_children &other) const + { + return std::equal (begin (), end (), other.begin ()); + } + template + bool operator!= (const other_children &other) const + { + return !(*this == other); + } + }; + + private: + const compile_units _m_units; + + public: + const class compile_units &compile_units () const + { + return _m_units; + } + + public: + // Constructor copying CUs from an input file (dwarf or dwarf_output). + template + dwarf_output (const input &dw) : _m_units (dw.compile_units ()) {} + + template + inline bool operator== (const file &other) const + { + return compile_units () == other.compile_units (); + } + template + inline bool operator!= (const file &other) const + { + return !(*this == other); + } + }; +}