+2020-02-08 Tom Tromey <tom@tromey.com>
+
+ * dwarf2read.c (struct attribute, DW_STRING)
+ (DW_STRING_IS_CANONICAL, DW_UNSND, DW_BLOCK, DW_SND, DW_ADDR)
+ (DW_SIGNATURE, struct dwarf_block, attr_value_as_address)
+ (attr_form_is_block, attr_form_is_section_offset)
+ (attr_form_is_constant, attr_form_is_ref): Move.
+ * dwarf2/attribute.h: New file.
+ * dwarf2/attribute.c: New file, from dwarf2read.c.
+ * Makefile.in (COMMON_SFILES): Add dwarf2/attribute.c.
+
2020-02-08 Tom Tromey <tom@tromey.com>
* dwarf2read.c (abbrev_table_up, struct abbrev_info)
dwarf2loc.c \
dwarf2read.c \
dwarf2/abbrev.c \
+ dwarf2/attribute.c \
dwarf2/leb.c \
dwarf2/section.c \
eval.c \
--- /dev/null
+/* DWARF attributes
+
+ Copyright (C) 1994-2020 Free Software Foundation, Inc.
+
+ Adapted by Gary Funck (gary@intrepid.com), Intrepid Technology,
+ Inc. with support from Florida State University (under contract
+ with the Ada Joint Program Office), and Silicon Graphics, Inc.
+ Initial contribution by Brent Benson, Harris Computer Systems, Inc.,
+ based on Fred Fish's (Cygnus Support) implementation of DWARF 1
+ support.
+
+ This file is part of GDB.
+
+ This program 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; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program 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 this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "dwarf2/attribute.h"
+
+/* See attribute.h. */
+
+CORE_ADDR
+attr_value_as_address (struct attribute *attr)
+{
+ CORE_ADDR addr;
+
+ if (attr->form != DW_FORM_addr && attr->form != DW_FORM_addrx
+ && attr->form != DW_FORM_GNU_addr_index)
+ {
+ /* Aside from a few clearly defined exceptions, attributes that
+ contain an address must always be in DW_FORM_addr form.
+ Unfortunately, some compilers happen to be violating this
+ requirement by encoding addresses using other forms, such
+ as DW_FORM_data4 for example. For those broken compilers,
+ we try to do our best, without any guarantee of success,
+ to interpret the address correctly. It would also be nice
+ to generate a complaint, but that would require us to maintain
+ a list of legitimate cases where a non-address form is allowed,
+ as well as update callers to pass in at least the CU's DWARF
+ version. This is more overhead than what we're willing to
+ expand for a pretty rare case. */
+ addr = DW_UNSND (attr);
+ }
+ else
+ addr = DW_ADDR (attr);
+
+ return addr;
+}
+
+/* See attribute.h. */
+
+int
+attr_form_is_block (const struct attribute *attr)
+{
+ return (attr == NULL ? 0 :
+ attr->form == DW_FORM_block1
+ || attr->form == DW_FORM_block2
+ || attr->form == DW_FORM_block4
+ || attr->form == DW_FORM_block
+ || attr->form == DW_FORM_exprloc);
+}
+
+/* See attribute.h. */
+
+int
+attr_form_is_section_offset (const struct attribute *attr)
+{
+ return (attr->form == DW_FORM_data4
+ || attr->form == DW_FORM_data8
+ || attr->form == DW_FORM_sec_offset);
+}
+
+/* See attribute.h. */
+
+int
+attr_form_is_constant (const struct attribute *attr)
+{
+ switch (attr->form)
+ {
+ case DW_FORM_sdata:
+ case DW_FORM_udata:
+ case DW_FORM_data1:
+ case DW_FORM_data2:
+ case DW_FORM_data4:
+ case DW_FORM_data8:
+ case DW_FORM_implicit_const:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+/* DW_ADDR is always stored already as sect_offset; despite for the forms
+ besides DW_FORM_ref_addr it is stored as cu_offset in the DWARF file. */
+
+int
+attr_form_is_ref (const struct attribute *attr)
+{
+ switch (attr->form)
+ {
+ case DW_FORM_ref_addr:
+ case DW_FORM_ref1:
+ case DW_FORM_ref2:
+ case DW_FORM_ref4:
+ case DW_FORM_ref8:
+ case DW_FORM_ref_udata:
+ case DW_FORM_GNU_ref_alt:
+ return 1;
+ default:
+ return 0;
+ }
+}
--- /dev/null
+/* DWARF attributes
+
+ Copyright (C) 1994-2020 Free Software Foundation, Inc.
+
+ Adapted by Gary Funck (gary@intrepid.com), Intrepid Technology,
+ Inc. with support from Florida State University (under contract
+ with the Ada Joint Program Office), and Silicon Graphics, Inc.
+ Initial contribution by Brent Benson, Harris Computer Systems, Inc.,
+ based on Fred Fish's (Cygnus Support) implementation of DWARF 1
+ support.
+
+ This file is part of GDB.
+
+ This program 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; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program 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 this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef GDB_DWARF2_ATTRIBUTE_H
+#define GDB_DWARF2_ATTRIBUTE_H
+
+#include "dwarf2.h"
+
+/* Blocks are a bunch of untyped bytes. */
+struct dwarf_block
+{
+ size_t size;
+
+ /* Valid only if SIZE is not zero. */
+ const gdb_byte *data;
+};
+
+/* Attributes have a name and a value. */
+struct attribute
+{
+ ENUM_BITFIELD(dwarf_attribute) name : 16;
+ ENUM_BITFIELD(dwarf_form) form : 15;
+
+ /* Has DW_STRING already been updated by dwarf2_canonicalize_name? This
+ field should be in u.str (existing only for DW_STRING) but it is kept
+ here for better struct attribute alignment. */
+ unsigned int string_is_canonical : 1;
+
+ union
+ {
+ const char *str;
+ struct dwarf_block *blk;
+ ULONGEST unsnd;
+ LONGEST snd;
+ CORE_ADDR addr;
+ ULONGEST signature;
+ }
+ u;
+};
+
+/* Get at parts of an attribute structure. */
+
+#define DW_STRING(attr) ((attr)->u.str)
+#define DW_STRING_IS_CANONICAL(attr) ((attr)->string_is_canonical)
+#define DW_UNSND(attr) ((attr)->u.unsnd)
+#define DW_BLOCK(attr) ((attr)->u.blk)
+#define DW_SND(attr) ((attr)->u.snd)
+#define DW_ADDR(attr) ((attr)->u.addr)
+#define DW_SIGNATURE(attr) ((attr)->u.signature)
+
+/* Read the given attribute value as an address, taking the attribute's
+ form into account. */
+
+extern CORE_ADDR attr_value_as_address (struct attribute *attr);
+
+/* Check if the attribute's form is a DW_FORM_block*
+ if so return true else false. */
+
+extern int attr_form_is_block (const struct attribute *attr);
+
+/* Return non-zero if ATTR's value is a section offset --- classes
+ lineptr, loclistptr, macptr or rangelistptr --- or zero, otherwise.
+ You may use DW_UNSND (attr) to retrieve such offsets.
+
+ Section 7.5.4, "Attribute Encodings", explains that no attribute
+ may have a value that belongs to more than one of these classes; it
+ would be ambiguous if we did, because we use the same forms for all
+ of them. */
+
+extern int attr_form_is_section_offset (const struct attribute *attr);
+
+/* Return non-zero if ATTR's value falls in the 'constant' class, or
+ zero otherwise. When this function returns true, you can apply
+ dwarf2_get_attr_constant_value to it.
+
+ However, note that for some attributes you must check
+ attr_form_is_section_offset before using this test. DW_FORM_data4
+ and DW_FORM_data8 are members of both the constant class, and of
+ the classes that contain offsets into other debug sections
+ (lineptr, loclistptr, macptr or rangelistptr). The DWARF spec says
+ that, if an attribute's can be either a constant or one of the
+ section offset classes, DW_FORM_data4 and DW_FORM_data8 should be
+ taken as section offsets, not constants.
+
+ DW_FORM_data16 is not considered as dwarf2_get_attr_constant_value
+ cannot handle that. */
+
+extern int attr_form_is_constant (const struct attribute *attr);
+
+/* DW_ADDR is always stored already as sect_offset; despite for the forms
+ besides DW_FORM_ref_addr it is stored as cu_offset in the DWARF file. */
+
+extern int attr_form_is_ref (const struct attribute *attr);
+
+#endif /* GDB_DWARF2_ATTRIBUTE_H */
#include "defs.h"
#include "dwarf2read.h"
#include "dwarf2/abbrev.h"
+#include "dwarf2/attribute.h"
#include "dwarf-index-cache.h"
#include "dwarf-index-common.h"
#include "dwarf2/leb.h"
}
};
-/* Attributes have a name and a value. */
-struct attribute
- {
- ENUM_BITFIELD(dwarf_attribute) name : 16;
- ENUM_BITFIELD(dwarf_form) form : 15;
-
- /* Has DW_STRING already been updated by dwarf2_canonicalize_name? This
- field should be in u.str (existing only for DW_STRING) but it is kept
- here for better struct attribute alignment. */
- unsigned int string_is_canonical : 1;
-
- union
- {
- const char *str;
- struct dwarf_block *blk;
- ULONGEST unsnd;
- LONGEST snd;
- CORE_ADDR addr;
- ULONGEST signature;
- }
- u;
- };
-
/* This data structure holds a complete die structure. */
struct die_info
{
struct attribute attrs[1];
};
-/* Get at parts of an attribute structure. */
-
-#define DW_STRING(attr) ((attr)->u.str)
-#define DW_STRING_IS_CANONICAL(attr) ((attr)->string_is_canonical)
-#define DW_UNSND(attr) ((attr)->u.unsnd)
-#define DW_BLOCK(attr) ((attr)->u.blk)
-#define DW_SND(attr) ((attr)->u.snd)
-#define DW_ADDR(attr) ((attr)->u.addr)
-#define DW_SIGNATURE(attr) ((attr)->u.signature)
-
-/* Blocks are a bunch of untyped bytes. */
-struct dwarf_block
- {
- size_t size;
-
- /* Valid only if SIZE is not zero. */
- const gdb_byte *data;
- };
-
/* FIXME: We might want to set this from BFD via bfd_arch_bits_per_byte,
but this would require a corresponding change in unpack_field_as_long
and friends. */
static void dwarf_decode_macros (struct dwarf2_cu *, unsigned int, int);
-static int attr_form_is_block (const struct attribute *);
-
-static int attr_form_is_section_offset (const struct attribute *);
-
-static int attr_form_is_constant (const struct attribute *);
-
-static int attr_form_is_ref (const struct attribute *);
-
static void fill_in_loclist_baton (struct dwarf2_cu *cu,
struct dwarf2_loclist_baton *baton,
const struct attribute *attr);
\f
-/* Read the given attribute value as an address, taking the attribute's
- form into account. */
-
-static CORE_ADDR
-attr_value_as_address (struct attribute *attr)
-{
- CORE_ADDR addr;
-
- if (attr->form != DW_FORM_addr && attr->form != DW_FORM_addrx
- && attr->form != DW_FORM_GNU_addr_index)
- {
- /* Aside from a few clearly defined exceptions, attributes that
- contain an address must always be in DW_FORM_addr form.
- Unfortunately, some compilers happen to be violating this
- requirement by encoding addresses using other forms, such
- as DW_FORM_data4 for example. For those broken compilers,
- we try to do our best, without any guarantee of success,
- to interpret the address correctly. It would also be nice
- to generate a complaint, but that would require us to maintain
- a list of legitimate cases where a non-address form is allowed,
- as well as update callers to pass in at least the CU's DWARF
- version. This is more overhead than what we're willing to
- expand for a pretty rare case. */
- addr = DW_UNSND (attr);
- }
- else
- addr = DW_ADDR (attr);
-
- return addr;
-}
-
/* See declaration. */
dwarf2_per_objfile::dwarf2_per_objfile (struct objfile *objfile_,
include_hash.get ());
}
-/* Check if the attribute's form is a DW_FORM_block*
- if so return true else false. */
-
-static int
-attr_form_is_block (const struct attribute *attr)
-{
- return (attr == NULL ? 0 :
- attr->form == DW_FORM_block1
- || attr->form == DW_FORM_block2
- || attr->form == DW_FORM_block4
- || attr->form == DW_FORM_block
- || attr->form == DW_FORM_exprloc);
-}
-
-/* Return non-zero if ATTR's value is a section offset --- classes
- lineptr, loclistptr, macptr or rangelistptr --- or zero, otherwise.
- You may use DW_UNSND (attr) to retrieve such offsets.
-
- Section 7.5.4, "Attribute Encodings", explains that no attribute
- may have a value that belongs to more than one of these classes; it
- would be ambiguous if we did, because we use the same forms for all
- of them. */
-
-static int
-attr_form_is_section_offset (const struct attribute *attr)
-{
- return (attr->form == DW_FORM_data4
- || attr->form == DW_FORM_data8
- || attr->form == DW_FORM_sec_offset);
-}
-
-/* Return non-zero if ATTR's value falls in the 'constant' class, or
- zero otherwise. When this function returns true, you can apply
- dwarf2_get_attr_constant_value to it.
-
- However, note that for some attributes you must check
- attr_form_is_section_offset before using this test. DW_FORM_data4
- and DW_FORM_data8 are members of both the constant class, and of
- the classes that contain offsets into other debug sections
- (lineptr, loclistptr, macptr or rangelistptr). The DWARF spec says
- that, if an attribute's can be either a constant or one of the
- section offset classes, DW_FORM_data4 and DW_FORM_data8 should be
- taken as section offsets, not constants.
-
- DW_FORM_data16 is not considered as dwarf2_get_attr_constant_value
- cannot handle that. */
-
-static int
-attr_form_is_constant (const struct attribute *attr)
-{
- switch (attr->form)
- {
- case DW_FORM_sdata:
- case DW_FORM_udata:
- case DW_FORM_data1:
- case DW_FORM_data2:
- case DW_FORM_data4:
- case DW_FORM_data8:
- case DW_FORM_implicit_const:
- return 1;
- default:
- return 0;
- }
-}
-
-
-/* DW_ADDR is always stored already as sect_offset; despite for the forms
- besides DW_FORM_ref_addr it is stored as cu_offset in the DWARF file. */
-
-static int
-attr_form_is_ref (const struct attribute *attr)
-{
- switch (attr->form)
- {
- case DW_FORM_ref_addr:
- case DW_FORM_ref1:
- case DW_FORM_ref2:
- case DW_FORM_ref4:
- case DW_FORM_ref8:
- case DW_FORM_ref_udata:
- case DW_FORM_GNU_ref_alt:
- return 1;
- default:
- return 0;
- }
-}
-
/* Return the .debug_loc section to use for CU.
For DWO files use .debug_loc.dwo. */