diff options
-rw-r--r-- | gdb/ChangeLog | 25 | ||||
-rw-r--r-- | gdb/Makefile.in | 6 | ||||
-rw-r--r-- | gdb/common/offset-type.h | 149 | ||||
-rw-r--r-- | gdb/common/preprocessor.h | 31 | ||||
-rw-r--r-- | gdb/common/traits.h | 34 | ||||
-rw-r--r-- | gdb/common/valid-expr.h | 108 | ||||
-rw-r--r-- | gdb/dwarf2expr.c | 45 | ||||
-rw-r--r-- | gdb/dwarf2expr.h | 16 | ||||
-rw-r--r-- | gdb/dwarf2loc.c | 37 | ||||
-rw-r--r-- | gdb/dwarf2read.c | 641 | ||||
-rw-r--r-- | gdb/gdbtypes.h | 14 | ||||
-rw-r--r-- | gdb/unittests/offset-type-selftests.c | 178 |
12 files changed, 900 insertions, 384 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index de8ed99..7844360 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,30 @@ 2017-04-04 Pedro Alves <palves@redhat.com> + * Makefile.in (SUBDIR_UNITTESTS_SRCS): Add + unittests/offset-type-selftests.c. + (SUBDIR_UNITTESTS_OBS): Add offset-type-selftests.o. + * common/offset-type.h: New file. + * common/preprocessor.h: New file. + * common/traits.h: New file. + * common/valid-expr.h: New file. + * dwarf2expr.c: Include "common/underlying.h". Adjust to use + sect_offset and cu_offset strong typedefs throughout. + * dwarf2expr.h: Adjust to use sect_offset and cu_offset strong + typedefs throughout. + * dwarf2loc.c: Include "common/underlying.h". Adjust to use + sect_offset and cu_offset strong typedefs throughout. + * dwarf2read.c: Adjust to use sect_offset and cu_offset strong + typedefs throughout. + * gdbtypes.h: Include "common/offset-type.h". + (cu_offset): Now an offset type (strong typedef) instead of a + struct. + (sect_offset): Likewise. + (union call_site_parameter_u): Rename "param_offset" field to + "param_cu_off". + * unittests/offset-type-selftests.c: New file. + +2017-04-04 Pedro Alves <palves@redhat.com> + * common/underlying.h: New file. * dwarf2read.c: Include "common/gdb_optional.h" and "common/underlying.h". diff --git a/gdb/Makefile.in b/gdb/Makefile.in index 0818742..8c9c46d 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -524,10 +524,12 @@ SUBDIR_PYTHON_LDFLAGS = SUBDIR_PYTHON_CFLAGS = SUBDIR_UNITTESTS_SRCS = \ - unittests/function-view-selftests.c + unittests/function-view-selftests.c \ + unittests/offset-type-selftests.c SUBDIR_UNITTESTS_OBS = \ - function-view-selftests.o + function-view-selftests.o \ + offset-type-selftests.o # Opcodes currently live in one of two places. Either they are in the # opcode library, typically ../opcodes, or they are in a header file diff --git a/gdb/common/offset-type.h b/gdb/common/offset-type.h new file mode 100644 index 0000000..9be65e9 --- /dev/null +++ b/gdb/common/offset-type.h @@ -0,0 +1,149 @@ +/* Offset types for GDB. + + Copyright (C) 2017 Free Software Foundation, Inc. + + 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/>. */ + +/* Define an "offset" type. Offset types are distinct integer types + that are used to represent an offset into anything that is + addressable. For example, an offset into a DWARF debug section. + The idea is catch mixing unrelated offset types at compile time, in + code that needs to manipulate multiple different kinds of offsets + that are easily confused. They're safer to use than native + integers, because they have no implicit conversion to anything. + And also, since they're implemented as "enum class" strong + typedefs, they're still integers ABI-wise, making them a bit more + efficient than wrapper structs on some ABIs. + + Some properties of offset types, loosely modeled on pointers: + + - You can compare offsets of the same type for equality and order. + You can't compare an offset with an unrelated type. + + - You can add/substract an integer to/from an offset, which gives + you back a shifted offset. + + - You can subtract two offsets of the same type, which gives you + back the delta as an integer (of the enum class's underlying + type), not as an offset type. + + - You can't add two offsets of the same type, as that would not + make sense. + + However, unlike pointers, you can't deference offset types. */ + +#ifndef COMMON_OFFSET_TYPE_H +#define COMMON_OFFSET_TYPE_H + +/* Declare TYPE as being an offset type. This declares the type and + enables the operators defined below. */ +#define DEFINE_OFFSET_TYPE(TYPE, UNDERLYING) \ + enum class TYPE : UNDERLYING {}; \ + void is_offset_type (TYPE) + +/* The macro macro is all you need to know use offset types. The rest + below is all implementation detail. */ + +/* For each enum class type that you want to support relational + operators, declare an "is_offset_type" overload that has exactly + one parameter, of type that enum class. E.g.,: + + void is_offset_type (sect_offset); + + The function does not need to be defined, only declared. + DEFINE_OFFSET_TYPE declares this. + + A function declaration is preferred over a traits type, because the + former allows calling the DEFINE_OFFSET_TYPE macro inside a + namespace to define the corresponding offset type in that + namespace. The compiler finds the corresponding is_offset_type + function via ADL. +*/ + +#define DEFINE_OFFSET_REL_OP(OP) \ + template<typename E, \ + typename = decltype (is_offset_type (std::declval<E> ()))> \ + constexpr bool \ + operator OP (E lhs, E rhs) \ + { \ + using underlying = typename std::underlying_type<E>::type; \ + return (static_cast<underlying> (lhs) \ + OP static_cast<underlying> (lhs)); \ + } + +DEFINE_OFFSET_REL_OP(>) +DEFINE_OFFSET_REL_OP(>=) +DEFINE_OFFSET_REL_OP(<) +DEFINE_OFFSET_REL_OP(<=) + +/* Adding or subtracting an integer to an offset type shifts the + offset. This is like "PTR = PTR + INT" and "PTR += INT". */ + +#define DEFINE_OFFSET_ARITHM_OP(OP) \ + template<typename E, \ + typename = decltype (is_offset_type (std::declval<E> ()))> \ + constexpr E \ + operator OP (E lhs, typename std::underlying_type<E>::type rhs) \ + { \ + using underlying = typename std::underlying_type<E>::type; \ + return (E) (static_cast<underlying> (lhs) OP rhs); \ + } \ + \ + template<typename E, \ + typename = decltype (is_offset_type (std::declval<E> ()))> \ + constexpr E \ + operator OP (typename std::underlying_type<E>::type lhs, E rhs) \ + { \ + using underlying = typename std::underlying_type<E>::type; \ + return (E) (lhs OP static_cast<underlying> (rhs)); \ + } \ + \ + template<typename E, \ + typename = decltype (is_offset_type (std::declval<E> ()))> \ + E & \ + operator OP ## = (E &lhs, typename std::underlying_type<E>::type rhs) \ + { \ + using underlying = typename std::underlying_type<E>::type; \ + lhs = (E) (static_cast<underlying> (lhs) OP rhs); \ + return lhs; \ + } + +DEFINE_OFFSET_ARITHM_OP(+) +DEFINE_OFFSET_ARITHM_OP(-) + +/* Adding two offset types doesn't make sense, just like "PTR + PTR" + doesn't make sense. This is defined as a deleted function so that + a compile error easily brings you to this comment. */ + +template<typename E, + typename = decltype (is_offset_type (std::declval<E> ()))> +constexpr typename std::underlying_type<E>::type +operator+ (E lhs, E rhs) = delete; + +/* Subtracting two offset types, however, gives you back the + difference between the offsets, as an underlying type. Similar to + how "PTR2 - PTR1" returns a ptrdiff_t. */ + +template<typename E, + typename = decltype (is_offset_type (std::declval<E> ()))> +constexpr typename std::underlying_type<E>::type +operator- (E lhs, E rhs) +{ + using underlying = typename std::underlying_type<E>::type; + return static_cast<underlying> (lhs) - static_cast<underlying> (rhs); +} + +#endif /* COMMON_OFFSET_TYPE_H */ diff --git a/gdb/common/preprocessor.h b/gdb/common/preprocessor.h new file mode 100644 index 0000000..6877344 --- /dev/null +++ b/gdb/common/preprocessor.h @@ -0,0 +1,31 @@ +/* Copyright (C) 2017 Free Software Foundation, Inc. + + 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 COMMON_PREPROC_H +#define COMMON_PREPROC_H + +/* Generally useful preprocessor bits. */ + +/* Concatenate two tokens. */ +#define CONCAT_1(a, b) a ## b +#define CONCAT(a, b) CONCAT_1 (a, b) + +/* Escape parens out. Useful if you need to pass an argument that + includes commas to another macro. */ +#define ESC(...) __VA_ARGS__ + +#endif /* COMMON_PREPROC */ diff --git a/gdb/common/traits.h b/gdb/common/traits.h new file mode 100644 index 0000000..4b7bac3 --- /dev/null +++ b/gdb/common/traits.h @@ -0,0 +1,34 @@ +/* Copyright (C) 2017 Free Software Foundation, Inc. + + 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 COMMON_TRAITS_H +#define COMMON_TRAITS_H + +namespace gdb { + +/* Pre C++14-safe (CWG 1558) version of C++17's std::void_t. See + <http://en.cppreference.com/w/cpp/types/void_t>. */ + +template<typename... Ts> +struct make_void { typedef void type; }; + +template<typename... Ts> +using void_t = typename make_void<Ts...>::type; + +} + +#endif /* COMMON_TRAITS_H */ diff --git a/gdb/common/valid-expr.h b/gdb/common/valid-expr.h new file mode 100644 index 0000000..80998917 --- /dev/null +++ b/gdb/common/valid-expr.h @@ -0,0 +1,108 @@ +/* Compile-time valid expression checker for GDB, the GNU debugger. + + Copyright (C) 2017 Free Software Foundation, Inc. + + 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/>. */ + +/* Helper macros used to build compile-time unit tests that make sure + that invalid expressions that should not compile would not compile, + and that expressions that should compile do compile, and have the + right type. This is mainly used to verify that some utility's API + is really as safe as intended. */ + +#ifndef COMMON_VALID_EXPR_H +#define COMMON_VALID_EXPR_H + +#include "common/preprocessor.h" +#include "common/traits.h" + +/* Macro that uses SFINAE magic to detect whether the EXPR expression + is either valid or ill-formed, at compile time, without actually + producing compile-time errors. I.e., check that bad uses of the + types (e.g., involving mismatching types) would be caught at + compile time. If the expression is valid, also check whether the + expression has the right type. + + EXPR must be defined in terms of some of the template parameters, + so that template substitution failure discards the overload instead + of causing a real compile error. TYPES is thus the list of types + involved in the expression, and TYPENAMES is the same list, but + with each element prefixed by "typename". These are passed as + template parameter types to the templates within the macro. + + VALID is a boolean that indicates whether the expression is + supposed to be valid or invalid. + + EXPR_TYPE is the expected type of EXPR. Only meaningful iff VALID + is true. If VALID is false, then you must pass "void" as expected + type. + + Each invocation of the macro is wrapped in its own namespace to + avoid ODR violations. The generated namespace only includes the + line number, so client code should wrap sets of calls in a + test-specific namespace too, to fully guarantee uniqueness between + the multiple clients in the codebase. */ +#define CHECK_VALID_EXPR_INT(TYPENAMES, TYPES, VALID, EXPR_TYPE, EXPR) \ + namespace CONCAT (check_valid_expr, __LINE__) { \ + \ + template<typename, typename, typename = void> \ + struct is_valid_expression \ + : std::false_type {}; \ + \ + template <TYPENAMES> \ + struct is_valid_expression<TYPES, gdb::void_t<decltype (EXPR)>> \ + : std::true_type {}; \ + \ + static_assert (is_valid_expression<TYPES>::value == VALID, \ + ""); \ + \ + template<TYPENAMES, typename = void> \ + struct is_same_type \ + : std::is_same<EXPR_TYPE, void> {}; \ + \ + template <TYPENAMES> \ + struct is_same_type<TYPES, gdb::void_t<decltype (EXPR)>> \ + : std::is_same<EXPR_TYPE, decltype (EXPR)> {}; \ + \ + static_assert (is_same_type<TYPES>::value, ""); \ + } /* namespace */ + +/* A few convenience macros that support expressions involving a + varying numbers of types. If you need more types, feel free to add + another variant. */ + +#define CHECK_VALID_EXPR_1(T1, VALID, EXPR_TYPE, EXPR) \ + CHECK_VALID_EXPR_INT (ESC (typename T1), \ + ESC (T1), \ + VALID, EXPR_TYPE, EXPR) + +#define CHECK_VALID_EXPR_2(T1, T2, VALID, EXPR_TYPE, EXPR) \ + CHECK_VALID_EXPR_INT (ESC (typename T1, typename T2), \ + ESC (T1, T2), \ + VALID, EXPR_TYPE, EXPR) + +#define CHECK_VALID_EXPR_3(T1, T2, T3, VALID, EXPR_TYPE, EXPR) \ + CHECK_VALID_EXPR_INT (ESC (typename T1, typename T2, typename T3), \ + ESC (T1, T2, T3), \ + VALID, EXPR_TYPE, EXPR) + +#define CHECK_VALID_EXPR_4(T1, T2, T3, T4, VALID, EXPR_TYPE, EXPR) \ + CHECK_VALID_EXPR_INT (ESC (typename T1, typename T2, \ + typename T3, typename T4), \ + ESC (T1, T2, T3, T4), \ + VALID, EXPR_TYPE, EXPR) + +#endif /* COMMON_VALID_EXPR_H */ diff --git a/gdb/dwarf2expr.c b/gdb/dwarf2expr.c index fbbb6c4..a693856 100644 --- a/gdb/dwarf2expr.c +++ b/gdb/dwarf2expr.c @@ -27,6 +27,7 @@ #include "dwarf2.h" #include "dwarf2expr.h" #include "dwarf2loc.h" +#include "common/underlying.h" /* Cookie for gdbarch data. */ @@ -317,7 +318,7 @@ dwarf_expr_context::add_piece (ULONGEST size, ULONGEST offset) } else if (p->location == DWARF_VALUE_IMPLICIT_POINTER) { - p->v.ptr.die.sect_off = this->len; + p->v.ptr.die_sect_off = (sect_offset) this->len; p->v.ptr.offset = value_as_long (fetch (0)); } else if (p->location == DWARF_VALUE_REGISTER) @@ -976,11 +977,9 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr, if (op == DW_OP_deref_type || op == DW_OP_GNU_deref_type) { - cu_offset type_die; - op_ptr = safe_read_uleb128 (op_ptr, op_end, &uoffset); - type_die.cu_off = uoffset; - type = get_base_type (type_die, 0); + cu_offset type_die_cu_off = (cu_offset) uoffset; + type = get_base_type (type_die_cu_off, 0); } else type = address_type; @@ -1283,21 +1282,19 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr, case DW_OP_call2: { - cu_offset offset; - - offset.cu_off = extract_unsigned_integer (op_ptr, 2, byte_order); + cu_offset cu_off + = (cu_offset) extract_unsigned_integer (op_ptr, 2, byte_order); op_ptr += 2; - this->dwarf_call (offset); + this->dwarf_call (cu_off); } goto no_push; case DW_OP_call4: { - cu_offset offset; - - offset.cu_off = extract_unsigned_integer (op_ptr, 4, byte_order); + cu_offset cu_off + = (cu_offset) extract_unsigned_integer (op_ptr, 4, byte_order); op_ptr += 4; - this->dwarf_call (offset); + this->dwarf_call (cu_off); } goto no_push; @@ -1344,8 +1341,8 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr, { union call_site_parameter_u kind_u; - kind_u.param_offset.cu_off = extract_unsigned_integer (op_ptr, 4, - byte_order); + kind_u.param_cu_off + = (cu_offset) extract_unsigned_integer (op_ptr, 4, byte_order); op_ptr += 4; this->push_dwarf_reg_entry_value (CALL_SITE_PARAMETER_PARAM_OFFSET, kind_u, @@ -1356,18 +1353,18 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr, case DW_OP_const_type: case DW_OP_GNU_const_type: { - cu_offset type_die; int n; const gdb_byte *data; struct type *type; op_ptr = safe_read_uleb128 (op_ptr, op_end, &uoffset); - type_die.cu_off = uoffset; + cu_offset type_die_cu_off = (cu_offset) uoffset; + n = *op_ptr++; data = op_ptr; op_ptr += n; - type = get_base_type (type_die, n); + type = get_base_type (type_die_cu_off, n); result_val = value_from_contents (type, data); } break; @@ -1375,14 +1372,13 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr, case DW_OP_regval_type: case DW_OP_GNU_regval_type: { - cu_offset type_die; struct type *type; op_ptr = safe_read_uleb128 (op_ptr, op_end, ®); op_ptr = safe_read_uleb128 (op_ptr, op_end, &uoffset); - type_die.cu_off = uoffset; + cu_offset type_die_cu_off = (cu_offset) uoffset; - type = get_base_type (type_die, 0); + type = get_base_type (type_die_cu_off, 0); result_val = this->get_reg_value (type, reg); } break; @@ -1392,16 +1388,15 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr, case DW_OP_reinterpret: case DW_OP_GNU_reinterpret: { - cu_offset type_die; struct type *type; op_ptr = safe_read_uleb128 (op_ptr, op_end, &uoffset); - type_die.cu_off = uoffset; + cu_offset type_die_cu_off = (cu_offset) uoffset; - if (type_die.cu_off == 0) + if (to_underlying (type_die_cu_off) == 0) type = address_type; else - type = get_base_type (type_die, 0); + type = get_base_type (type_die_cu_off, 0); result_val = fetch (0); pop (); diff --git a/gdb/dwarf2expr.h b/gdb/dwarf2expr.h index 2df310f..7df697d 100644 --- a/gdb/dwarf2expr.h +++ b/gdb/dwarf2expr.h @@ -172,16 +172,16 @@ struct dwarf_expr_context virtual CORE_ADDR get_tls_address (CORE_ADDR offset) = 0; /* Execute DW_AT_location expression for the DWARF expression - subroutine in the DIE at DIE_OFFSET in the CU. Do not touch + subroutine in the DIE at DIE_CU_OFF in the CU. Do not touch STACK while it being passed to and returned from the called DWARF subroutine. */ - virtual void dwarf_call (cu_offset die_offset) = 0; + virtual void dwarf_call (cu_offset die_cu_off) = 0; - /* Return the base type given by the indicated DIE. This can throw - an exception if the DIE is invalid or does not represent a base - type. SIZE is non-zero if this function should verify that the - resulting type has the correct size. */ - virtual struct type *get_base_type (cu_offset die, int size) + /* Return the base type given by the indicated DIE at DIE_CU_OFF. + This can throw an exception if the DIE is invalid or does not + represent a base type. SIZE is non-zero if this function should + verify that the resulting type has the correct size. */ + virtual struct type *get_base_type (cu_offset die_cu_off, int size) { /* Anything will do. */ return builtin_type (this->gdbarch)->builtin_int; @@ -249,7 +249,7 @@ struct dwarf_expr_piece struct { /* The referent DIE from DW_OP_implicit_pointer. */ - sect_offset die; + sect_offset die_sect_off; /* The byte offset into the resulting data. */ LONGEST offset; } ptr; diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c index 93c45a7..127167d 100644 --- a/gdb/dwarf2loc.c +++ b/gdb/dwarf2loc.c @@ -42,6 +42,7 @@ #include <algorithm> #include <vector> #include <unordered_set> +#include "common/underlying.h" extern int dwarf_always_disassemble; @@ -1191,7 +1192,7 @@ call_site_parameter_matches (struct call_site_parameter *parameter, case CALL_SITE_PARAMETER_FB_OFFSET: return kind_u.fb_offset == parameter->u.fb_offset; case CALL_SITE_PARAMETER_PARAM_OFFSET: - return kind_u.param_offset.cu_off == parameter->u.param_offset.cu_off; + return kind_u.param_cu_off == parameter->u.param_cu_off; } return 0; } @@ -2255,7 +2256,8 @@ indirect_pieced_value (struct value *value) TYPE_LENGTH (type), byte_order); byte_offset += piece->v.ptr.offset; - return indirect_synthetic_pointer (piece->v.ptr.die, byte_offset, c->per_cu, + return indirect_synthetic_pointer (piece->v.ptr.die_sect_off, + byte_offset, c->per_cu, frame, type); } @@ -2280,7 +2282,7 @@ coerce_pieced_ref (const struct value *value) gdb_assert (closure != NULL); gdb_assert (closure->n_pieces == 1); - return indirect_synthetic_pointer (closure->pieces->v.ptr.die, + return indirect_synthetic_pointer (closure->pieces->v.ptr.die_sect_off, closure->pieces->v.ptr.offset, closure->per_cu, frame, type); } @@ -3642,12 +3644,11 @@ dwarf2_compile_expr_to_ax (struct agent_expr *expr, struct axs_value *loc, { struct dwarf2_locexpr_baton block; int size = (op == DW_OP_call2 ? 2 : 4); - cu_offset offset; uoffset = extract_unsigned_integer (op_ptr, size, byte_order); op_ptr += size; - offset.cu_off = uoffset; + cu_offset offset = (cu_offset) uoffset; block = dwarf2_fetch_die_loc_cu_off (offset, per_cu, get_ax_pc, expr); @@ -4192,15 +4193,15 @@ disassemble_dwarf_expression (struct ui_file *stream, case DW_OP_GNU_deref_type: { int addr_size = *data++; - cu_offset offset; struct type *type; data = safe_read_uleb128 (data, end, &ul); - offset.cu_off = ul; + cu_offset offset = (cu_offset) ul; type = dwarf2_get_die_type (offset, per_cu); fprintf_filtered (stream, "<"); type_print (type, "", stream, -1); - fprintf_filtered (stream, " [0x%s]> %d", phex_nz (offset.cu_off, 0), + fprintf_filtered (stream, " [0x%s]> %d", + phex_nz (to_underlying (offset), 0), addr_size); } break; @@ -4208,15 +4209,15 @@ disassemble_dwarf_expression (struct ui_file *stream, case DW_OP_const_type: case DW_OP_GNU_const_type: { - cu_offset type_die; struct type *type; data = safe_read_uleb128 (data, end, &ul); - type_die.cu_off = ul; + cu_offset type_die = (cu_offset) ul; type = dwarf2_get_die_type (type_die, per_cu); fprintf_filtered (stream, "<"); type_print (type, "", stream, -1); - fprintf_filtered (stream, " [0x%s]>", phex_nz (type_die.cu_off, 0)); + fprintf_filtered (stream, " [0x%s]>", + phex_nz (to_underlying (type_die), 0)); } break; @@ -4224,18 +4225,17 @@ disassemble_dwarf_expression (struct ui_file *stream, case DW_OP_GNU_regval_type: { uint64_t reg; - cu_offset type_die; struct type *type; data = safe_read_uleb128 (data, end, ®); data = safe_read_uleb128 (data, end, &ul); - type_die.cu_off = ul; + cu_offset type_die = (cu_offset) ul; type = dwarf2_get_die_type (type_die, per_cu); fprintf_filtered (stream, "<"); type_print (type, "", stream, -1); fprintf_filtered (stream, " [0x%s]> [$%s]", - phex_nz (type_die.cu_off, 0), + phex_nz (to_underlying (type_die), 0), locexpr_regname (arch, reg)); } break; @@ -4245,12 +4245,10 @@ disassemble_dwarf_expression (struct ui_file *stream, case DW_OP_reinterpret: case DW_OP_GNU_reinterpret: { - cu_offset type_die; - data = safe_read_uleb128 (data, end, &ul); - type_die.cu_off = ul; + cu_offset type_die = (cu_offset) ul; - if (type_die.cu_off == 0) + if (to_underlying (type_die) == 0) fprintf_filtered (stream, "<0>"); else { @@ -4259,7 +4257,8 @@ disassemble_dwarf_expression (struct ui_file *stream, type = dwarf2_get_die_type (type_die, per_cu); fprintf_filtered (stream, "<"); type_print (type, "", stream, -1); - fprintf_filtered (stream, " [0x%s]>", phex_nz (type_die.cu_off, 0)); + fprintf_filtered (stream, " [0x%s]>", + phex_nz (to_underlying (type_die), 0)); } } break; diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index f18c072..a936381 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -397,7 +397,7 @@ struct comp_unit_head short version; unsigned char addr_size; unsigned char signed_addr_p; - sect_offset abbrev_offset; + sect_offset abbrev_sect_off; /* Size of file offsets; either 4 or 8. */ unsigned int offset_size; @@ -409,18 +409,18 @@ struct comp_unit_head /* Offset to the first byte of this compilation unit header in the .debug_info section, for resolving relative reference dies. */ - sect_offset offset; + sect_offset sect_off; /* Offset to first die in this cu from the start of the cu. This will be the first byte following the compilation unit header. */ - cu_offset first_die_offset; + cu_offset first_die_cu_offset; /* 64-bit signature of this type unit - it is valid only for UNIT_TYPE DW_UT_type. */ ULONGEST signature; /* For types, offset in the type's DIE of the type defined by this TU. */ - cu_offset type_offset_in_tu; + cu_offset type_cu_offset_in_tu; }; /* Type used for delaying computation of method physnames. @@ -589,7 +589,7 @@ struct dwarf2_per_cu_data initial_length_size. If the DIE refers to a DWO file, this is always of the original die, not the DWO file. */ - sect_offset offset; + sect_offset sect_off; unsigned int length; /* DWARF standard version this data has been read from (such as 4 or 5). */ @@ -728,7 +728,7 @@ struct stmt_list_hash struct dwo_unit *dwo_unit; /* Offset in .debug_line or .debug_line.dwo. */ - sect_offset line_offset; + sect_offset line_sect_off; }; /* Each element of dwarf2_per_objfile->type_unit_groups is a pointer to @@ -804,8 +804,8 @@ struct dwo_unit /* The section this CU/TU lives in, in the DWO file. */ struct dwarf2_section_info *section; - /* Same as dwarf2_per_cu_data:{offset,length} but in the DWO section. */ - sect_offset offset; + /* Same as dwarf2_per_cu_data:{sect_off,length} but in the DWO section. */ + sect_offset sect_off; unsigned int length; /* For types, offset in the type's DIE of the type defined by this TU. */ @@ -1147,7 +1147,7 @@ struct line_header } /* Offset of line number information in .debug_line section. */ - sect_offset offset {}; + sect_offset sect_off {}; /* OFFSET is for struct dwz_file associated with dwarf2_per_objfile. */ unsigned offset_in_dwz : 1; /* Can't initialize bitfields in-class. */ @@ -1193,7 +1193,7 @@ file_entry::include_dir (const line_header *lh) const struct partial_die_info { /* Offset of this DIE. */ - sect_offset offset; + sect_offset sect_off; /* DWARF-2 tag for this DIE. */ ENUM_BITFIELD(dwarf_tag) tag : 16; @@ -1251,7 +1251,7 @@ struct partial_die_info /* The location description associated with this DIE, if any. */ struct dwarf_block *locdesc; /* The offset of an import, for DW_TAG_imported_unit. */ - sect_offset offset; + sect_offset sect_off; } d; /* If HAS_PC_INFO, the PC range associated with this DIE. */ @@ -1303,7 +1303,7 @@ struct abbrev_table { /* Where the abbrev table came from. This is used as a sanity check when the table is used. */ - sect_offset offset; + sect_offset sect_off; /* Storage for the abbrev table. */ struct obstack abbrev_obstack; @@ -1358,7 +1358,7 @@ struct die_info unsigned int abbrev; /* Offset in .debug_info or .debug_types section. */ - sect_offset offset; + sect_offset sect_off; /* The dies in a compilation unit form an n-ary tree. PARENT points to this die's parent; CHILD points to the first child of @@ -1645,7 +1645,7 @@ static int die_is_declaration (struct die_info *, struct dwarf2_cu *cu); static struct die_info *die_specification (struct die_info *die, struct dwarf2_cu **); -static line_header_up dwarf_decode_line_header (unsigned int offset, +static line_header_up dwarf_decode_line_header (sect_offset sect_off, struct dwarf2_cu *cu); static void dwarf_decode_lines (struct line_header *, const char *, @@ -1910,7 +1910,7 @@ static hashval_t partial_die_hash (const void *item); static int partial_die_eq (const void *item_lhs, const void *item_rhs); static struct dwarf2_per_cu_data *dwarf2_find_containing_comp_unit - (sect_offset offset, unsigned int offset_in_dwz, struct objfile *objfile); + (sect_offset sect_off, unsigned int offset_in_dwz, struct objfile *objfile); static void init_one_comp_unit (struct dwarf2_cu *cu, struct dwarf2_per_cu_data *per_cu); @@ -2102,7 +2102,7 @@ dwarf2_invalid_attrib_class_complaint (const char *arg1, const char *arg2) static hashval_t line_header_hash (const struct line_header *ofs) { - return ofs->offset.sect_off ^ ofs->offset_in_dwz; + return to_underlying (ofs->sect_off) ^ ofs->offset_in_dwz; } /* Hash function for htab_create_alloc_ex for line_header_hash. */ @@ -2123,7 +2123,7 @@ line_header_eq_voidp (const void *item_lhs, const void *item_rhs) const struct line_header *ofs_lhs = (const struct line_header *) item_lhs; const struct line_header *ofs_rhs = (const struct line_header *) item_rhs; - return (ofs_lhs->offset.sect_off == ofs_rhs->offset.sect_off + return (ofs_lhs->sect_off == ofs_rhs->sect_off && ofs_lhs->offset_in_dwz == ofs_rhs->offset_in_dwz); } @@ -2743,7 +2743,7 @@ hash_stmt_list_entry (const struct stmt_list_hash *stmt_list_hash) if (stmt_list_hash->dwo_unit != NULL) v += (uintptr_t) stmt_list_hash->dwo_unit->dwo_file; - v += stmt_list_hash->line_offset.sect_off; + v += to_underlying (stmt_list_hash->line_sect_off); return v; } @@ -2759,7 +2759,7 @@ eq_stmt_list_entry (const struct stmt_list_hash *lhs, && lhs->dwo_unit->dwo_file != rhs->dwo_unit->dwo_file) return 0; - return lhs->line_offset.sect_off == rhs->line_offset.sect_off; + return lhs->line_sect_off == rhs->line_sect_off; } /* Hash function for a quick_file_names. */ @@ -2946,17 +2946,17 @@ create_cus_from_index_list (struct objfile *objfile, for (i = 0; i < n_elements; i += 2) { - struct dwarf2_per_cu_data *the_cu; - ULONGEST offset, length; - gdb_static_assert (sizeof (ULONGEST) >= 8); - offset = extract_unsigned_integer (cu_list, 8, BFD_ENDIAN_LITTLE); - length = extract_unsigned_integer (cu_list + 8, 8, BFD_ENDIAN_LITTLE); + + sect_offset sect_off + = (sect_offset) extract_unsigned_integer (cu_list, 8, BFD_ENDIAN_LITTLE); + ULONGEST length = extract_unsigned_integer (cu_list + 8, 8, BFD_ENDIAN_LITTLE); cu_list += 2 * 8; - the_cu = OBSTACK_ZALLOC (&objfile->objfile_obstack, - struct dwarf2_per_cu_data); - the_cu->offset.sect_off = offset; + dwarf2_per_cu_data *the_cu + = OBSTACK_ZALLOC (&objfile->objfile_obstack, + struct dwarf2_per_cu_data); + the_cu->sect_off = sect_off; the_cu->length = length; the_cu->objfile = objfile; the_cu->section = section; @@ -3015,23 +3015,26 @@ create_signatured_type_table_from_index (struct objfile *objfile, for (i = 0; i < elements; i += 3) { struct signatured_type *sig_type; - ULONGEST offset, type_offset_in_tu, signature; + ULONGEST signature; void **slot; + cu_offset type_offset_in_tu; gdb_static_assert (sizeof (ULONGEST) >= 8); - offset = extract_unsigned_integer (bytes, 8, BFD_ENDIAN_LITTLE); - type_offset_in_tu = extract_unsigned_integer (bytes + 8, 8, - BFD_ENDIAN_LITTLE); + sect_offset sect_off + = (sect_offset) extract_unsigned_integer (bytes, 8, BFD_ENDIAN_LITTLE); + type_offset_in_tu + = (cu_offset) extract_unsigned_integer (bytes + 8, 8, + BFD_ENDIAN_LITTLE); signature = extract_unsigned_integer (bytes + 16, 8, BFD_ENDIAN_LITTLE); bytes += 3 * 8; sig_type = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct signatured_type); sig_type->signature = signature; - sig_type->type_offset_in_tu.cu_off = type_offset_in_tu; + sig_type->type_offset_in_tu = type_offset_in_tu; sig_type->per_cu.is_debug_types = 1; sig_type->per_cu.section = section; - sig_type->per_cu.offset.sect_off = offset; + sig_type->per_cu.sect_off = sect_off; sig_type->per_cu.objfile = objfile; sig_type->per_cu.v.quick = OBSTACK_ZALLOC (&objfile->objfile_obstack, @@ -3425,7 +3428,6 @@ dw2_get_file_names_reader (const struct die_reader_specs *reader, int i; void **slot; struct quick_file_names *qfn; - unsigned int line_offset; gdb_assert (! this_cu->is_debug_types); @@ -3439,21 +3441,21 @@ dw2_get_file_names_reader (const struct die_reader_specs *reader, lh_cu = this_cu; slot = NULL; - line_offset = 0; line_header_up lh; + sect_offset line_offset {}; attr = dwarf2_attr (comp_unit_die, DW_AT_stmt_list, cu); if (attr) { struct quick_file_names find_entry; - line_offset = DW_UNSND (attr); + line_offset = (sect_offset) DW_UNSND (attr); /* We may have already read in this line header (TU line header sharing). If we have we're done. */ find_entry.hash.dwo_unit = cu->dwo_unit; - find_entry.hash.line_offset.sect_off = line_offset; + find_entry.hash.line_sect_off = line_offset; slot = htab_find_slot (dwarf2_per_objfile->quick_file_names_table, &find_entry, INSERT); if (*slot != NULL) @@ -3472,7 +3474,7 @@ dw2_get_file_names_reader (const struct die_reader_specs *reader, qfn = XOBNEW (&objfile->objfile_obstack, struct quick_file_names); qfn->hash.dwo_unit = cu->dwo_unit; - qfn->hash.line_offset.sect_off = line_offset; + qfn->hash.line_sect_off = line_offset; gdb_assert (slot != NULL); *slot = qfn; @@ -4420,15 +4422,15 @@ get_cu_length (const struct comp_unit_head *header) return header->initial_length_size + header->length; } -/* Return TRUE if OFFSET is within CU_HEADER. */ +/* Return TRUE if SECT_OFF is within CU_HEADER. */ -static inline int -offset_in_cu_p (const struct comp_unit_head *cu_header, sect_offset offset) +static inline bool +offset_in_cu_p (const comp_unit_head *cu_header, sect_offset sect_off) { - sect_offset bottom = { cu_header->offset.sect_off }; - sect_offset top = { cu_header->offset.sect_off + get_cu_length (cu_header) }; + sect_offset bottom = cu_header->sect_off; + sect_offset top = cu_header->sect_off + get_cu_length (cu_header); - return (offset.sect_off >= bottom.sect_off && offset.sect_off < top.sect_off); + return sect_off >= bottom && sect_off < top; } /* Find the base address of the compilation unit for range lists and @@ -4522,8 +4524,9 @@ read_comp_unit_head (struct comp_unit_head *cu_header, cu_header->addr_size = read_1_byte (abfd, info_ptr); info_ptr += 1; } - cu_header->abbrev_offset.sect_off = read_offset (abfd, info_ptr, cu_header, - &bytes_read); + cu_header->abbrev_sect_off = (sect_offset) read_offset (abfd, info_ptr, + cu_header, + &bytes_read); info_ptr += bytes_read; if (cu_header->version < 5) { @@ -4545,8 +4548,8 @@ read_comp_unit_head (struct comp_unit_head *cu_header, type_offset = read_offset (abfd, info_ptr, cu_header, &bytes_read); info_ptr += bytes_read; - cu_header->type_offset_in_tu.cu_off = type_offset; - if (cu_header->type_offset_in_tu.cu_off != type_offset) + cu_header->type_cu_offset_in_tu = (cu_offset) type_offset; + if (to_underlying (cu_header->type_cu_offset_in_tu) != type_offset) error (_("Dwarf Error: Too big type_offset in compilation unit " "header (is %s) [in module %s]"), plongest (type_offset), filename); @@ -4587,20 +4590,21 @@ error_check_comp_unit_head (struct comp_unit_head *header, "(is %d, should be 2, 3, 4 or 5) [in module %s]"), header->version, filename); - if (header->abbrev_offset.sect_off + if (to_underlying (header->abbrev_sect_off) >= dwarf2_section_size (dwarf2_per_objfile->objfile, abbrev_section)) - error (_("Dwarf Error: bad offset (0x%lx) in compilation unit header " - "(offset 0x%lx + 6) [in module %s]"), - (long) header->abbrev_offset.sect_off, (long) header->offset.sect_off, + error (_("Dwarf Error: bad offset (0x%x) in compilation unit header " + "(offset 0x%x + 6) [in module %s]"), + to_underlying (header->abbrev_sect_off), + to_underlying (header->sect_off), filename); - /* Cast to unsigned long to use 64-bit arithmetic when possible to + /* Cast to ULONGEST to use 64-bit arithmetic when possible to avoid potential 32-bit overflow. */ - if (((unsigned long) header->offset.sect_off + get_cu_length (header)) + if (((ULONGEST) header->sect_off + get_cu_length (header)) > section->size) - error (_("Dwarf Error: bad length (0x%lx) in compilation unit header " - "(offset 0x%lx + 0) [in module %s]"), - (long) header->length, (long) header->offset.sect_off, + error (_("Dwarf Error: bad length (0x%x) in compilation unit header " + "(offset 0x%x + 0) [in module %s]"), + header->length, to_underlying (header->sect_off), filename); } @@ -4618,11 +4622,11 @@ read_and_check_comp_unit_head (struct comp_unit_head *header, const gdb_byte *beg_of_comp_unit = info_ptr; bfd *abfd = get_section_bfd_owner (section); - header->offset.sect_off = beg_of_comp_unit - section->buffer; + header->sect_off = (sect_offset) (beg_of_comp_unit - section->buffer); info_ptr = read_comp_unit_head (header, info_ptr, section, section_kind); - header->first_die_offset.cu_off = info_ptr - beg_of_comp_unit; + header->first_die_cu_offset = (cu_offset) (info_ptr - beg_of_comp_unit); error_check_comp_unit_head (header, section, abbrev_section); @@ -4633,16 +4637,15 @@ read_and_check_comp_unit_head (struct comp_unit_head *header, static sect_offset read_abbrev_offset (struct dwarf2_section_info *section, - sect_offset offset) + sect_offset sect_off) { bfd *abfd = get_section_bfd_owner (section); const gdb_byte *info_ptr; unsigned int initial_length_size, offset_size; - sect_offset abbrev_offset; uint16_t version; dwarf2_read_section (dwarf2_per_objfile->objfile, section); - info_ptr = section->buffer + offset.sect_off; + info_ptr = section->buffer + to_underlying (sect_off); read_initial_length (abfd, info_ptr, &initial_length_size); offset_size = initial_length_size == 4 ? 4 : 8; info_ptr += initial_length_size; @@ -4655,8 +4658,7 @@ read_abbrev_offset (struct dwarf2_section_info *section, info_ptr += 2; } - abbrev_offset.sect_off = read_offset_1 (abfd, info_ptr, offset_size); - return abbrev_offset; + return (sect_offset) read_offset_1 (abfd, info_ptr, offset_size); } /* Allocate a new partial symtab for file named NAME and mark this new @@ -4710,7 +4712,7 @@ dwarf2_build_include_psymtabs (struct dwarf2_cu *cu, attr = dwarf2_attr (die, DW_AT_stmt_list, cu); if (attr) - lh = dwarf_decode_line_header (DW_UNSND (attr), cu); + lh = dwarf_decode_line_header ((sect_offset) DW_UNSND (attr), cu); if (lh == NULL) return; /* No linetable, so no includes. */ @@ -4805,7 +4807,6 @@ create_debug_type_hash_table (struct dwo_file *dwo_file, end_ptr = info_ptr + section->size; while (info_ptr < end_ptr) { - sect_offset offset; struct signatured_type *sig_type; struct dwo_unit *dwo_tu; void **slot; @@ -4813,11 +4814,11 @@ create_debug_type_hash_table (struct dwo_file *dwo_file, struct comp_unit_head header; unsigned int length; - offset.sect_off = ptr - section->buffer; + sect_offset sect_off = (sect_offset) (ptr - section->buffer); /* Initialize it due to a false compiler warning. */ header.signature = -1; - header.type_offset_in_tu.cu_off = -1; + header.type_cu_offset_in_tu = (cu_offset) -1; /* We need to read the type's signature in order to build the hash table, but we don't need anything else just yet. */ @@ -4851,9 +4852,9 @@ create_debug_type_hash_table (struct dwo_file *dwo_file, struct dwo_unit); dwo_tu->dwo_file = dwo_file; dwo_tu->signature = header.signature; - dwo_tu->type_offset_in_tu = header.type_offset_in_tu; + dwo_tu->type_offset_in_tu = header.type_cu_offset_in_tu; dwo_tu->section = section; - dwo_tu->offset = offset; + dwo_tu->sect_off = sect_off; dwo_tu->length = length; } else @@ -4864,11 +4865,11 @@ create_debug_type_hash_table (struct dwo_file *dwo_file, sig_type = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct signatured_type); sig_type->signature = header.signature; - sig_type->type_offset_in_tu = header.type_offset_in_tu; + sig_type->type_offset_in_tu = header.type_cu_offset_in_tu; sig_type->per_cu.objfile = objfile; sig_type->per_cu.is_debug_types = 1; sig_type->per_cu.section = section; - sig_type->per_cu.offset = offset; + sig_type->per_cu.sect_off = sect_off; sig_type->per_cu.length = length; } @@ -4878,34 +4879,34 @@ create_debug_type_hash_table (struct dwo_file *dwo_file, gdb_assert (slot != NULL); if (*slot != NULL) { - sect_offset dup_offset; + sect_offset dup_sect_off; if (dwo_file) { const struct dwo_unit *dup_tu = (const struct dwo_unit *) *slot; - dup_offset = dup_tu->offset; + dup_sect_off = dup_tu->sect_off; } else { const struct signatured_type *dup_tu = (const struct signatured_type *) *slot; - dup_offset = dup_tu->per_cu.offset; + dup_sect_off = dup_tu->per_cu.sect_off; } complaint (&symfile_complaints, _("debug type entry at offset 0x%x is duplicate to" " the entry at offset 0x%x, signature %s"), - offset.sect_off, dup_offset.sect_off, + to_underlying (sect_off), to_underlying (dup_sect_off), hex_string (header.signature)); } *slot = dwo_file ? (void *) dwo_tu : (void *) sig_type; if (dwarf_read_debug > 1) fprintf_unfiltered (gdb_stdlog, " offset 0x%x, signature %s\n", - offset.sect_off, + to_underlying (sect_off), hex_string (header.signature)); info_ptr += length; @@ -5042,12 +5043,12 @@ fill_in_sig_entry_from_dwo_entry (struct objfile *objfile, else gdb_assert (sig_entry->per_cu.v.psymtab == NULL); gdb_assert (sig_entry->signature == dwo_entry->signature); - gdb_assert (sig_entry->type_offset_in_section.sect_off == 0); + gdb_assert (to_underlying (sig_entry->type_offset_in_section) == 0); gdb_assert (sig_entry->type_unit_group == NULL); gdb_assert (sig_entry->dwo_unit == NULL); sig_entry->per_cu.section = dwo_entry->section; - sig_entry->per_cu.offset = dwo_entry->offset; + sig_entry->per_cu.sect_off = dwo_entry->sect_off; sig_entry->per_cu.length = dwo_entry->length; sig_entry->per_cu.reading_dwo_directly = 1; sig_entry->per_cu.objfile = objfile; @@ -5326,7 +5327,8 @@ read_cutu_die_from_dwo (struct dwarf2_per_cu_data *this_cu, section = dwo_unit->section; dwarf2_read_section (objfile, section); abfd = get_section_bfd_owner (section); - begin_info_ptr = info_ptr = section->buffer + dwo_unit->offset.sect_off; + begin_info_ptr = info_ptr = (section->buffer + + to_underlying (dwo_unit->sect_off)); dwo_abbrev_section = &dwo_unit->dwo_file->sections.abbrev; init_cu_die_reader (result_reader, cu, section, dwo_unit->dwo_file); @@ -5344,26 +5346,26 @@ read_cutu_die_from_dwo (struct dwarf2_per_cu_data *this_cu, " TU at offset 0x%x [in module %s]"), hex_string (sig_type->signature), hex_string (cu->header.signature), - dwo_unit->offset.sect_off, + to_underlying (dwo_unit->sect_off), bfd_get_filename (abfd)); } - gdb_assert (dwo_unit->offset.sect_off == cu->header.offset.sect_off); + gdb_assert (dwo_unit->sect_off == cu->header.sect_off); /* For DWOs coming from DWP files, we don't know the CU length nor the type's offset in the TU until now. */ dwo_unit->length = get_cu_length (&cu->header); - dwo_unit->type_offset_in_tu = cu->header.type_offset_in_tu; + dwo_unit->type_offset_in_tu = cu->header.type_cu_offset_in_tu; /* Establish the type offset that can be used to lookup the type. For DWO files, we don't know it until now. */ - sig_type->type_offset_in_section.sect_off = - dwo_unit->offset.sect_off + dwo_unit->type_offset_in_tu.cu_off; + sig_type->type_offset_in_section + = dwo_unit->sect_off + to_underlying (dwo_unit->type_offset_in_tu); } else { info_ptr = read_and_check_comp_unit_head (&cu->header, section, dwo_abbrev_section, info_ptr, rcuh_kind::COMPILE); - gdb_assert (dwo_unit->offset.sect_off == cu->header.offset.sect_off); + gdb_assert (dwo_unit->sect_off == cu->header.sect_off); /* For DWOs coming from DWP files, we don't know the CU length until now. */ dwo_unit->length = get_cu_length (&cu->header); @@ -5623,7 +5625,7 @@ init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu, if (dwarf_die_debug) fprintf_unfiltered (gdb_stdlog, "Reading %s unit at offset 0x%x\n", this_cu->is_debug_types ? "type" : "comp", - this_cu->offset.sect_off); + to_underlying (this_cu->sect_off)); if (use_existing_cu) gdb_assert (keep); @@ -5645,7 +5647,7 @@ init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu, /* This is cheap if the section is already read in. */ dwarf2_read_section (objfile, section); - begin_info_ptr = info_ptr = section->buffer + this_cu->offset.sect_off; + begin_info_ptr = info_ptr = section->buffer + to_underlying (this_cu->sect_off); abbrev_section = get_abbrev_section_for_cu (this_cu); @@ -5672,10 +5674,10 @@ init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu, } /* Get the header. */ - if (cu->header.first_die_offset.cu_off != 0 && ! rereading_dwo_cu) + if (to_underlying (cu->header.first_die_cu_offset) != 0 && !rereading_dwo_cu) { /* We already have the header, there's no need to read it in again. */ - info_ptr += cu->header.first_die_offset.cu_off; + info_ptr += to_underlying (cu->header.first_die_cu_offset); } else { @@ -5689,17 +5691,17 @@ init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu, we can go from a pointer to one to a pointer to the other. */ sig_type = (struct signatured_type *) this_cu; gdb_assert (sig_type->signature == cu->header.signature); - gdb_assert (sig_type->type_offset_in_tu.cu_off - == cu->header.type_offset_in_tu.cu_off); - gdb_assert (this_cu->offset.sect_off == cu->header.offset.sect_off); + gdb_assert (sig_type->type_offset_in_tu + == cu->header.type_cu_offset_in_tu); + gdb_assert (this_cu->sect_off == cu->header.sect_off); /* LENGTH has not been set yet for type units if we're using .gdb_index. */ this_cu->length = get_cu_length (&cu->header); /* Establish the type offset that can be used to lookup the type. */ - sig_type->type_offset_in_section.sect_off = - this_cu->offset.sect_off + sig_type->type_offset_in_tu.cu_off; + sig_type->type_offset_in_section = + this_cu->sect_off + to_underlying (sig_type->type_offset_in_tu); this_cu->dwarf_version = cu->header.version; } @@ -5710,7 +5712,7 @@ init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu, info_ptr, rcuh_kind::COMPILE); - gdb_assert (this_cu->offset.sect_off == cu->header.offset.sect_off); + gdb_assert (this_cu->sect_off == cu->header.sect_off); gdb_assert (this_cu->length == get_cu_length (&cu->header)); this_cu->dwarf_version = cu->header.version; } @@ -5732,8 +5734,7 @@ init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu, if (abbrev_table != NULL) { gdb_assert (cu->abbrev_table == NULL); - gdb_assert (cu->header.abbrev_offset.sect_off - == abbrev_table->offset.sect_off); + gdb_assert (cu->header.abbrev_sect_off == abbrev_table->sect_off); cu->abbrev_table = abbrev_table; } else if (cu->abbrev_table == NULL) @@ -5766,7 +5767,7 @@ init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu, complaint (&symfile_complaints, _("compilation unit with DW_AT_GNU_dwo_name" " has children (offset 0x%x) [in module %s]"), - this_cu->offset.sect_off, bfd_get_filename (abfd)); + to_underlying (this_cu->sect_off), bfd_get_filename (abfd)); } dwo_unit = lookup_dwo_unit (this_cu, comp_unit_die); if (dwo_unit != NULL) @@ -5856,7 +5857,7 @@ init_cutu_and_read_dies_no_follow (struct dwarf2_per_cu_data *this_cu, if (dwarf_die_debug) fprintf_unfiltered (gdb_stdlog, "Reading %s unit at offset 0x%x\n", this_cu->is_debug_types ? "type" : "comp", - this_cu->offset.sect_off); + to_underlying (this_cu->sect_off)); gdb_assert (this_cu->cu == NULL); @@ -5871,7 +5872,7 @@ init_cutu_and_read_dies_no_follow (struct dwarf2_per_cu_data *this_cu, cleanups = make_cleanup (free_stack_comp_unit, &cu); - begin_info_ptr = info_ptr = section->buffer + this_cu->offset.sect_off; + begin_info_ptr = info_ptr = section->buffer + to_underlying (this_cu->sect_off); info_ptr = read_and_check_comp_unit_head (&cu.header, section, abbrev_section, info_ptr, (this_cu->is_debug_types @@ -5984,7 +5985,7 @@ create_type_unit_group (struct dwarf2_cu *cu, sect_offset line_offset_struct) } else { - unsigned int line_offset = line_offset_struct.sect_off; + unsigned int line_offset = to_underlying (line_offset_struct); struct partial_symtab *pst; char *name; @@ -6002,7 +6003,7 @@ create_type_unit_group (struct dwarf2_cu *cu, sect_offset line_offset_struct) } tu_group->hash.dwo_unit = cu->dwo_unit; - tu_group->hash.line_offset = line_offset_struct; + tu_group->hash.line_sect_off = line_offset_struct; return tu_group; } @@ -6046,7 +6047,7 @@ get_type_unit_group (struct dwarf2_cu *cu, const struct attribute *stmt_list) } type_unit_group_for_lookup.hash.dwo_unit = cu->dwo_unit; - type_unit_group_for_lookup.hash.line_offset.sect_off = line_offset; + type_unit_group_for_lookup.hash.line_sect_off = (sect_offset) line_offset; slot = htab_find_slot (dwarf2_per_objfile->type_unit_groups, &type_unit_group_for_lookup, INSERT); if (*slot != NULL) @@ -6056,9 +6057,7 @@ get_type_unit_group (struct dwarf2_cu *cu, const struct attribute *stmt_list) } else { - sect_offset line_offset_struct; - - line_offset_struct.sect_off = line_offset; + sect_offset line_offset_struct = (sect_offset) line_offset; tu_group = create_type_unit_group (cu, line_offset_struct); *slot = tu_group; ++tu_stats->nr_symtabs; @@ -6233,7 +6232,7 @@ process_psymtab_comp_unit_reader (const struct die_reader_specs *reader, "Psymtab for %s unit @0x%x: %s - %s" ", %d global, %d static syms\n", per_cu->is_debug_types ? "type" : "comp", - per_cu->offset.sect_off, + to_underlying (per_cu->sect_off), paddress (gdbarch, pst->textlow), paddress (gdbarch, pst->texthigh), pst->n_global_syms, pst->n_static_syms); @@ -6331,8 +6330,8 @@ sort_tu_by_abbrev_offset (const void *ap, const void *bp) = (const struct tu_abbrev_offset * const*) ap; const struct tu_abbrev_offset * const *b = (const struct tu_abbrev_offset * const*) bp; - unsigned int aoff = (*a)->abbrev_offset.sect_off; - unsigned int boff = (*b)->abbrev_offset.sect_off; + sect_offset aoff = (*a)->abbrev_offset; + sect_offset boff = (*b)->abbrev_offset; return (aoff > boff) - (aoff < boff); } @@ -6404,13 +6403,13 @@ build_type_psymtabs_1 (void) sorted_by_abbrev[i].sig_type = sig_type; sorted_by_abbrev[i].abbrev_offset = read_abbrev_offset (sig_type->per_cu.section, - sig_type->per_cu.offset); + sig_type->per_cu.sect_off); } cleanups = make_cleanup (xfree, sorted_by_abbrev); qsort (sorted_by_abbrev, dwarf2_per_objfile->n_type_units, sizeof (struct tu_abbrev_offset), sort_tu_by_abbrev_offset); - abbrev_offset.sect_off = ~(unsigned) 0; + abbrev_offset = (sect_offset) ~(unsigned) 0; abbrev_table = NULL; make_cleanup (abbrev_table_free_cleanup, &abbrev_table); @@ -6420,7 +6419,7 @@ build_type_psymtabs_1 (void) /* Switch to the next abbrev table if necessary. */ if (abbrev_table == NULL - || tu->abbrev_offset.sect_off != abbrev_offset.sect_off) + || tu->abbrev_offset != abbrev_offset) { if (abbrev_table != NULL) { @@ -6739,9 +6738,8 @@ read_comp_units_from_section (struct objfile *objfile, { unsigned int length, initial_length_size; struct dwarf2_per_cu_data *this_cu; - sect_offset offset; - offset.sect_off = info_ptr - section->buffer; + sect_offset sect_off = (sect_offset) (info_ptr - section->buffer); /* Read just enough information to find out where the next compilation unit is. */ @@ -6750,7 +6748,7 @@ read_comp_units_from_section (struct objfile *objfile, /* Save the compilation unit for later lookup. */ this_cu = XOBNEW (&objfile->objfile_obstack, struct dwarf2_per_cu_data); memset (this_cu, 0, sizeof (*this_cu)); - this_cu->offset = offset; + this_cu->sect_off = sect_off; this_cu->length = length + initial_length_size; this_cu->is_dwz = is_dwz; this_cu->objfile = objfile; @@ -6886,7 +6884,7 @@ scan_partial_symbols (struct partial_die_info *first_die, CORE_ADDR *lowpc, objfile_name (cu->objfile)); } - per_cu = dwarf2_find_containing_comp_unit (pdi->d.offset, + per_cu = dwarf2_find_containing_comp_unit (pdi->d.sect_off, pdi->is_dwz, cu->objfile); @@ -6999,7 +6997,7 @@ partial_die_parent_scope (struct partial_die_info *pdi, ignoring them. */ complaint (&symfile_complaints, _("unhandled containing DIE tag %d for DIE at %d"), - parent->tag, pdi->offset.sect_off); + parent->tag, to_underlying (pdi->sect_off)); parent->scope = grandparent_scope; } @@ -7033,7 +7031,7 @@ partial_die_full_name (struct partial_die_info *pdi, /* DW_FORM_ref_addr is using section offset. */ attr.name = (enum dwarf_attribute) 0; attr.form = DW_FORM_ref_addr; - attr.u.unsnd = pdi->offset.sect_off; + attr.u.unsnd = to_underlying (pdi->sect_off); die = follow_die_ref (NULL, &attr, &ref_cu); return xstrdup (dwarf2_full_name (NULL, die, ref_cu)); @@ -7393,7 +7391,7 @@ peek_die_abbrev (const gdb_byte *info_ptr, unsigned int *bytes_read, error (_("Dwarf Error: Could not find abbrev number %d in %s" " at offset 0x%x [in module %s]"), abbrev_number, cu->per_cu->is_debug_types ? "TU" : "CU", - cu->header.offset.sect_off, bfd_get_filename (abfd)); + to_underlying (cu->header.sect_off), bfd_get_filename (abfd)); } return abbrev; @@ -7449,8 +7447,8 @@ skip_one_die (const struct die_reader_specs *reader, const gdb_byte *info_ptr, _("ignoring absolute DW_AT_sibling")); else { - unsigned int off = dwarf2_get_ref_die_offset (&attr).sect_off; - const gdb_byte *sibling_ptr = buffer + off; + sect_offset off = dwarf2_get_ref_die_offset (&attr); + const gdb_byte *sibling_ptr = buffer + to_underlying (off); if (sibling_ptr < info_ptr) complaint (&symfile_complaints, @@ -7738,14 +7736,15 @@ process_queue (void) sprintf (buf, "TU %s at offset 0x%x", hex_string (sig_type->signature), - per_cu->offset.sect_off); + to_underlying (per_cu->sect_off)); /* There can be 100s of TUs. Only print them in verbose mode. */ debug_print_threshold = 2; } else { - sprintf (buf, "CU at offset 0x%x", per_cu->offset.sect_off); + sprintf (buf, "CU at offset 0x%x", + to_underlying (per_cu->sect_off)); debug_print_threshold = 1; } @@ -7855,7 +7854,7 @@ die_hash (const void *item) { const struct die_info *die = (const struct die_info *) item; - return die->offset.sect_off; + return to_underlying (die->sect_off); } /* Trivial comparison function for die_info structures: two DIEs @@ -7867,7 +7866,7 @@ die_eq (const void *item_lhs, const void *item_rhs) const struct die_info *die_lhs = (const struct die_info *) item_lhs; const struct die_info *die_rhs = (const struct die_info *) item_rhs; - return die_lhs->offset.sect_off == die_rhs->offset.sect_off; + return die_lhs->sect_off == die_rhs->sect_off; } /* die_reader_func for load_full_comp_unit. @@ -8392,13 +8391,10 @@ process_imported_unit_die (struct die_info *die, struct dwarf2_cu *cu) attr = dwarf2_attr (die, DW_AT_import, cu); if (attr != NULL) { - struct dwarf2_per_cu_data *per_cu; - sect_offset offset; - int is_dwz; - - offset = dwarf2_get_ref_die_offset (attr); - is_dwz = (attr->form == DW_FORM_GNU_ref_alt || cu->per_cu->is_dwz); - per_cu = dwarf2_find_containing_comp_unit (offset, is_dwz, cu->objfile); + sect_offset sect_off = dwarf2_get_ref_die_offset (attr); + bool is_dwz = (attr->form == DW_FORM_GNU_ref_alt || cu->per_cu->is_dwz); + dwarf2_per_cu_data *per_cu + = dwarf2_find_containing_comp_unit (sect_off, is_dwz, cu->objfile); /* If necessary, add it to the queue and load its DIEs. */ if (maybe_queue_comp_unit (cu, per_cu, cu->language)) @@ -8932,7 +8928,7 @@ dwarf2_physname (const char *name, struct die_info *die, struct dwarf2_cu *cu) complaint (&symfile_complaints, _("Computed physname <%s> does not match demangled <%s> " "(from linkage <%s>) - DIE at 0x%x [in module %s]"), - physname, canon, mangled, die->offset.sect_off, + physname, canon, mangled, to_underlying (die->sect_off), objfile_name (objfile)); /* Prefer DW_AT_linkage_name (in the CANON form) - when it @@ -8996,16 +8992,16 @@ read_namespace_alias (struct die_info *die, struct dwarf2_cu *cu) { complaint (&symfile_complaints, _("DIE at 0x%x has too many recursively imported " - "declarations"), d->offset.sect_off); + "declarations"), to_underlying (d->sect_off)); return 0; } if (attr != NULL) { struct type *type; - sect_offset offset = dwarf2_get_ref_die_offset (attr); + sect_offset sect_off = dwarf2_get_ref_die_offset (attr); - type = get_die_type_at_offset (offset, cu->per_cu); + type = get_die_type_at_offset (sect_off, cu->per_cu); if (type != NULL && TYPE_CODE (type) == TYPE_CODE_NAMESPACE) { /* This declaration is a global namespace alias. Add @@ -9143,7 +9139,7 @@ read_import_statement (struct die_info *die, struct dwarf2_cu *cu) complaint (&symfile_complaints, _("child DW_TAG_imported_declaration expected " "- DIE at 0x%x [in module %s]"), - child_die->offset.sect_off, objfile_name (objfile)); + to_underlying (child_die->sect_off), objfile_name (objfile)); continue; } @@ -9164,7 +9160,7 @@ read_import_statement (struct die_info *die, struct dwarf2_cu *cu) complaint (&symfile_complaints, _("child DW_TAG_imported_declaration has unknown " "imported name - DIE at 0x%x [in module %s]"), - child_die->offset.sect_off, objfile_name (objfile)); + to_underlying (child_die->sect_off), objfile_name (objfile)); continue; } @@ -9243,7 +9239,6 @@ handle_DW_AT_stmt_list (struct die_info *die, struct dwarf2_cu *cu, { struct objfile *objfile = dwarf2_per_objfile->objfile; struct attribute *attr; - unsigned int line_offset; struct line_header line_header_local; hashval_t line_header_local_hash; unsigned u; @@ -9256,7 +9251,7 @@ handle_DW_AT_stmt_list (struct die_info *die, struct dwarf2_cu *cu, if (attr == NULL) return; - line_offset = DW_UNSND (attr); + sect_offset line_offset = (sect_offset) DW_UNSND (attr); /* The line header hash table is only created if needed (it exists to prevent redundant reading of the line table for partial_units). @@ -9276,7 +9271,7 @@ handle_DW_AT_stmt_list (struct die_info *die, struct dwarf2_cu *cu, dummy_obstack_deallocate); } - line_header_local.offset.sect_off = line_offset; + line_header_local.sect_off = line_offset; line_header_local.offset_in_dwz = cu->per_cu->is_dwz; line_header_local_hash = line_header_hash (&line_header_local); if (dwarf2_per_objfile->line_header_hash != NULL) @@ -9429,7 +9424,7 @@ setup_type_unit_groups (struct die_info *die, struct dwarf2_cu *cu) struct type_unit_group *tu_group; int first_time; struct attribute *attr; - unsigned int i, line_offset; + unsigned int i; struct signatured_type *sig_type; gdb_assert (per_cu->is_debug_types); @@ -9454,7 +9449,7 @@ setup_type_unit_groups (struct die_info *die, struct dwarf2_cu *cu) line_header_up lh; if (attr != NULL) { - line_offset = DW_UNSND (attr); + sect_offset line_offset = (sect_offset) DW_UNSND (attr); lh = dwarf_decode_line_header (line_offset, cu); } if (lh == NULL) @@ -9678,7 +9673,7 @@ create_dwo_cu_reader (const struct die_reader_specs *reader, void *datap) { struct dwarf2_cu *cu = reader->cu; - sect_offset offset = cu->per_cu->offset; + sect_offset sect_off = cu->per_cu->sect_off; struct dwarf2_section_info *section = cu->per_cu->section; struct create_dwo_cu_data *data = (struct create_dwo_cu_data *) datap; struct dwo_file *dwo_file = data->dwo_file; @@ -9691,19 +9686,20 @@ create_dwo_cu_reader (const struct die_reader_specs *reader, complaint (&symfile_complaints, _("Dwarf Error: debug entry at offset 0x%x is missing" " its dwo_id [in module %s]"), - offset.sect_off, dwo_file->dwo_name); + to_underlying (sect_off), dwo_file->dwo_name); return; } dwo_unit->dwo_file = dwo_file; dwo_unit->signature = DW_UNSND (attr); dwo_unit->section = section; - dwo_unit->offset = offset; + dwo_unit->sect_off = sect_off; dwo_unit->length = cu->per_cu->length; if (dwarf_read_debug) fprintf_unfiltered (gdb_stdlog, " offset 0x%x, dwo_id %s\n", - offset.sect_off, hex_string (dwo_unit->signature)); + to_underlying (sect_off), + hex_string (dwo_unit->signature)); } /* Create the dwo_unit for the lone CU in DWO_FILE. @@ -9744,7 +9740,7 @@ create_dwo_cu (struct dwo_file *dwo_file) memset (&per_cu, 0, sizeof (per_cu)); per_cu.objfile = objfile; per_cu.is_debug_types = 0; - per_cu.offset.sect_off = info_ptr - section->buffer; + per_cu.sect_off = sect_offset (info_ptr - section->buffer); per_cu.section = section; init_cutu_and_read_dies_no_follow (&per_cu, dwo_file, @@ -11189,7 +11185,7 @@ lookup_dwo_cutu (struct dwarf2_per_cu_data *this_unit, kind, dwo_name, hex_string (signature), dwp_text != NULL ? dwp_text : "", this_unit->is_debug_types ? "TU" : "CU", - this_unit->offset.sect_off, objfile_name (objfile)); + to_underlying (this_unit->sect_off), objfile_name (objfile)); do_cleanups (cleanups); } @@ -11367,7 +11363,8 @@ inherit_abstract_dies (struct die_info *die, struct dwarf2_cu *cu) && origin_die->tag == DW_TAG_subprogram)) complaint (&symfile_complaints, _("DIE 0x%x and its abstract origin 0x%x have different tags"), - die->offset.sect_off, origin_die->offset.sect_off); + to_underlying (die->sect_off), + to_underlying (origin_die->sect_off)); child_die = die->child; die_children_count = 0; @@ -11422,25 +11419,27 @@ inherit_abstract_dies (struct die_info *die, struct dwarf2_cu *cu) && child_origin_die->tag == DW_TAG_subprogram)) complaint (&symfile_complaints, _("Child DIE 0x%x and its abstract origin 0x%x have " - "different tags"), child_die->offset.sect_off, - child_origin_die->offset.sect_off); + "different tags"), + to_underlying (child_die->sect_off), + to_underlying (child_origin_die->sect_off)); if (child_origin_die->parent != origin_die) complaint (&symfile_complaints, _("Child DIE 0x%x and its abstract origin 0x%x have " - "different parents"), child_die->offset.sect_off, - child_origin_die->offset.sect_off); + "different parents"), + to_underlying (child_die->sect_off), + to_underlying (child_origin_die->sect_off)); else - *offsets_end++ = child_origin_die->offset; + *offsets_end++ = child_origin_die->sect_off; } } qsort (offsets, offsets_end - offsets, sizeof (*offsets), unsigned_int_compar); for (offsetp = offsets + 1; offsetp < offsets_end; offsetp++) - if (offsetp[-1].sect_off == offsetp->sect_off) + if (offsetp[-1] == *offsetp) complaint (&symfile_complaints, _("Multiple children of DIE 0x%x refer " "to DIE 0x%x as their abstract origin"), - die->offset.sect_off, offsetp->sect_off); + to_underlying (die->sect_off), to_underlying (*offsetp)); offsetp = offsets; origin_child_die = origin_die->child; @@ -11448,10 +11447,10 @@ inherit_abstract_dies (struct die_info *die, struct dwarf2_cu *cu) { /* Is ORIGIN_CHILD_DIE referenced by any of the DIE children? */ while (offsetp < offsets_end - && offsetp->sect_off < origin_child_die->offset.sect_off) + && *offsetp < origin_child_die->sect_off) offsetp++; if (offsetp >= offsets_end - || offsetp->sect_off > origin_child_die->offset.sect_off) + || *offsetp > origin_child_die->sect_off) { /* Found that ORIGIN_CHILD_DIE is really not referenced. Check whether we're already processing ORIGIN_CHILD_DIE. @@ -11508,7 +11507,7 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu) { complaint (&symfile_complaints, _("missing name for subprogram DIE at %d"), - die->offset.sect_off); + to_underlying (die->sect_off)); return; } @@ -11521,7 +11520,7 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu) complaint (&symfile_complaints, _("cannot get low and high bounds " "for subprogram DIE at %d"), - die->offset.sect_off); + to_underlying (die->sect_off)); return; } @@ -11756,7 +11755,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu) complaint (&symfile_complaints, _("missing DW_AT_call_return_pc for DW_TAG_call_site " "DIE 0x%x [in module %s]"), - die->offset.sect_off, objfile_name (objfile)); + to_underlying (die->sect_off), objfile_name (objfile)); return; } pc = attr_value_as_address (attr) + baseaddr; @@ -11773,7 +11772,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu) complaint (&symfile_complaints, _("Duplicate PC %s for DW_TAG_call_site " "DIE 0x%x [in module %s]"), - paddress (gdbarch, pc), die->offset.sect_off, + paddress (gdbarch, pc), to_underlying (die->sect_off), objfile_name (objfile)); return; } @@ -11790,7 +11789,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu) complaint (&symfile_complaints, _("Tag %d is not DW_TAG_call_site_parameter in " "DW_TAG_call_site child DIE 0x%x [in module %s]"), - child_die->tag, child_die->offset.sect_off, + child_die->tag, to_underlying (child_die->sect_off), objfile_name (objfile)); continue; } @@ -11853,7 +11852,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu) complaint (&symfile_complaints, _("Cannot find function owning DW_TAG_call_site " "DIE 0x%x [in module %s]"), - die->offset.sect_off, objfile_name (objfile)); + to_underlying (die->sect_off), objfile_name (objfile)); } } @@ -11906,7 +11905,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu) complaint (&symfile_complaints, _("DW_AT_call_target target DIE has invalid " "physname, for referencing DIE 0x%x [in module %s]"), - die->offset.sect_off, objfile_name (objfile)); + to_underlying (die->sect_off), objfile_name (objfile)); else SET_FIELD_PHYSNAME (call_site->target, target_physname); } @@ -11920,7 +11919,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu) complaint (&symfile_complaints, _("DW_AT_call_target target DIE has invalid " "low pc, for referencing DIE 0x%x [in module %s]"), - die->offset.sect_off, objfile_name (objfile)); + to_underlying (die->sect_off), objfile_name (objfile)); else { lowpc = gdbarch_adjust_dwarf2_addr (gdbarch, lowpc + baseaddr); @@ -11932,7 +11931,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu) complaint (&symfile_complaints, _("DW_TAG_call_site DW_AT_call_target is neither " "block nor reference, for DIE 0x%x [in module %s]"), - die->offset.sect_off, objfile_name (objfile)); + to_underlying (die->sect_off), objfile_name (objfile)); call_site->per_cu = cu->per_cu; @@ -11967,11 +11966,11 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu) } if (loc == NULL && origin != NULL && attr_form_is_ref (origin)) { - sect_offset offset; - parameter->kind = CALL_SITE_PARAMETER_PARAM_OFFSET; - offset = dwarf2_get_ref_die_offset (origin); - if (!offset_in_cu_p (&cu->header, offset)) + + sect_offset sect_off + = (sect_offset) dwarf2_get_ref_die_offset (origin); + if (!offset_in_cu_p (&cu->header, sect_off)) { /* As DW_OP_GNU_parameter_ref uses CU-relative offset this binding can be done only inside one CU. Such referenced DIE @@ -11979,18 +11978,19 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu) complaint (&symfile_complaints, _("DW_AT_call_parameter offset is not in CU for " "DW_TAG_call_site child DIE 0x%x [in module %s]"), - child_die->offset.sect_off, objfile_name (objfile)); + to_underlying (child_die->sect_off), + objfile_name (objfile)); continue; } - parameter->u.param_offset.cu_off = (offset.sect_off - - cu->header.offset.sect_off); + parameter->u.param_cu_off + = (cu_offset) (sect_off - cu->header.sect_off); } else if (loc == NULL || origin != NULL || !attr_form_is_block (loc)) { complaint (&symfile_complaints, _("No DW_FORM_block* DW_AT_location for " "DW_TAG_call_site child DIE 0x%x [in module %s]"), - child_die->offset.sect_off, objfile_name (objfile)); + to_underlying (child_die->sect_off), objfile_name (objfile)); continue; } else @@ -12010,7 +12010,8 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu) "for DW_FORM_block* DW_AT_location is supported for " "DW_TAG_call_site child DIE 0x%x " "[in module %s]"), - child_die->offset.sect_off, objfile_name (objfile)); + to_underlying (child_die->sect_off), + objfile_name (objfile)); continue; } } @@ -12023,7 +12024,8 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu) complaint (&symfile_complaints, _("No DW_FORM_block* DW_AT_call_value for " "DW_TAG_call_site child DIE 0x%x [in module %s]"), - child_die->offset.sect_off, objfile_name (objfile)); + to_underlying (child_die->sect_off), + objfile_name (objfile)); continue; } parameter->value = DW_BLOCK (attr)->data; @@ -12043,7 +12045,8 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu) complaint (&symfile_complaints, _("No DW_FORM_block* DW_AT_call_data_value for " "DW_TAG_call_site child DIE 0x%x [in module %s]"), - child_die->offset.sect_off, objfile_name (objfile)); + to_underlying (child_die->sect_off), + objfile_name (objfile)); else { parameter->data_value = DW_BLOCK (attr)->data; @@ -13292,7 +13295,7 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die, complaint (&symfile_complaints, _("cannot determine context for virtual member " "function \"%s\" (offset %d)"), - fieldname, die->offset.sect_off); + fieldname, to_underlying (die->sect_off)); } else { @@ -13320,7 +13323,7 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die, complaint (&symfile_complaints, _("Member function \"%s\" (offset %d) is virtual " "but the vtable offset is not specified"), - fieldname, die->offset.sect_off); + fieldname, to_underlying (die->sect_off)); ALLOCATE_CPLUS_STRUCT_TYPE (type); TYPE_CPLUS_DYNAMIC (type) = 1; } @@ -14010,8 +14013,8 @@ process_enumeration_scope (struct die_info *die, struct dwarf2_cu *cu) struct signatured_type *sig_type; sig_type = (struct signatured_type *) cu->per_cu; - gdb_assert (sig_type->type_offset_in_section.sect_off != 0); - if (sig_type->type_offset_in_section.sect_off != die->offset.sect_off) + gdb_assert (to_underlying (sig_type->type_offset_in_section) != 0); + if (sig_type->type_offset_in_section != die->sect_off) return; } @@ -14251,7 +14254,7 @@ mark_common_block_symbol_computed (struct symbol *sym, baton->data = ptr; *ptr++ = DW_OP_call4; - cu_off = common_die->offset.sect_off - cu->per_cu->offset.sect_off; + cu_off = common_die->sect_off - cu->per_cu->sect_off; store_unsigned_integer (ptr, 4, byte_order, cu_off); ptr += 4; @@ -14354,7 +14357,7 @@ read_common_block (struct die_info *die, struct dwarf2_cu *cu) _("Variable in common block has " "DW_AT_data_member_location " "- DIE at 0x%x [in module %s]"), - child_die->offset.sect_off, + to_underlying (child_die->sect_off), objfile_name (cu->objfile)); if (attr_form_is_section_offset (member_loc)) @@ -14474,7 +14477,7 @@ read_module_type (struct die_info *die, struct dwarf2_cu *cu) if (!module_name) complaint (&symfile_complaints, _("DW_TAG_module has no name, offset 0x%x"), - die->offset.sect_off); + to_underlying (die->sect_off)); type = init_type (objfile, TYPE_CODE_MODULE, 0, module_name); /* determine_prefix uses TYPE_TAG_NAME. */ @@ -15017,7 +15020,7 @@ read_typedef (struct die_info *die, struct dwarf2_cu *cu) complaint (&symfile_complaints, _("Self-referential DW_TAG_typedef " "- DIE at 0x%x [in module %s]"), - die->offset.sect_off, objfile_name (objfile)); + to_underlying (die->sect_off), objfile_name (objfile)); TYPE_TARGET_TYPE (this_type) = NULL; } return this_type; @@ -15311,7 +15314,7 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu) else if (!low_default_is_valid) complaint (&symfile_complaints, _("Missing DW_AT_lower_bound " "- DIE at 0x%x [in module %s]"), - die->offset.sect_off, objfile_name (cu->objfile)); + to_underlying (die->sect_off), objfile_name (cu->objfile)); attr = dwarf2_attr (die, DW_AT_upper_bound, cu); if (!attr_to_dynamic_prop (attr, die, cu, &high)) @@ -15533,13 +15536,12 @@ read_full_die_1 (const struct die_reader_specs *reader, int *has_children, int num_extra_attrs) { unsigned int abbrev_number, bytes_read, i; - sect_offset offset; struct abbrev_info *abbrev; struct die_info *die; struct dwarf2_cu *cu = reader->cu; bfd *abfd = reader->abfd; - offset.sect_off = info_ptr - reader->buffer; + sect_offset sect_off = (sect_offset) (info_ptr - reader->buffer); abbrev_number = read_unsigned_leb128 (abfd, info_ptr, &bytes_read); info_ptr += bytes_read; if (!abbrev_number) @@ -15556,7 +15558,7 @@ read_full_die_1 (const struct die_reader_specs *reader, bfd_get_filename (abfd)); die = dwarf_alloc_die (cu, abbrev->num_attrs + num_extra_attrs); - die->offset = offset; + die->sect_off = sect_off; die->tag = abbrev->tag; die->abbrev = abbrev_number; @@ -15661,7 +15663,7 @@ abbrev_table_lookup_abbrev (const struct abbrev_table *abbrev_table, static struct abbrev_table * abbrev_table_read_table (struct dwarf2_section_info *section, - sect_offset offset) + sect_offset sect_off) { struct objfile *objfile = dwarf2_per_objfile->objfile; bfd *abfd = get_section_bfd_owner (section); @@ -15674,7 +15676,7 @@ abbrev_table_read_table (struct dwarf2_section_info *section, unsigned int allocated_attrs; abbrev_table = XNEW (struct abbrev_table); - abbrev_table->offset = offset; + abbrev_table->sect_off = sect_off; obstack_init (&abbrev_table->abbrev_obstack); abbrev_table->abbrevs = XOBNEWVEC (&abbrev_table->abbrev_obstack, struct abbrev_info *, @@ -15683,7 +15685,7 @@ abbrev_table_read_table (struct dwarf2_section_info *section, ABBREV_HASH_SIZE * sizeof (struct abbrev_info *)); dwarf2_read_section (objfile, section); - abbrev_ptr = section->buffer + offset.sect_off; + abbrev_ptr = section->buffer + to_underlying (sect_off); abbrev_number = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read); abbrev_ptr += bytes_read; @@ -15800,7 +15802,7 @@ dwarf2_read_abbrevs (struct dwarf2_cu *cu, struct dwarf2_section_info *abbrev_section) { cu->abbrev_table = - abbrev_table_read_table (abbrev_section, cu->header.abbrev_offset); + abbrev_table_read_table (abbrev_section, cu->header.abbrev_sect_off); } /* Release the memory used by the abbrev table for a compilation unit. */ @@ -16002,7 +16004,7 @@ load_partial_dies (const struct die_reader_specs *reader, complaint (&symfile_complaints, _("DW_TAG_typedef has childen - GCC PR debug/47510 bug " "- DIE at 0x%x [in module %s]"), - part_die->offset.sect_off, objfile_name (objfile)); + to_underlying (part_die->sect_off), objfile_name (objfile)); /* If we're at the second level, and we're an enumerator, and our parent has no specification (meaning possibly lives in a @@ -16075,7 +16077,8 @@ load_partial_dies (const struct die_reader_specs *reader, void **slot; slot = htab_find_slot_with_hash (cu->partial_dies, part_die, - part_die->offset.sect_off, INSERT); + to_underlying (part_die->sect_off), + INSERT); *slot = part_die; } @@ -16142,7 +16145,7 @@ read_partial_die (const struct die_reader_specs *reader, memset (part_die, 0, sizeof (struct partial_die_info)); - part_die->offset.sect_off = info_ptr - buffer; + part_die->sect_off = (sect_offset) (info_ptr - buffer); info_ptr += abbrev_len; @@ -16241,8 +16244,8 @@ read_partial_die (const struct die_reader_specs *reader, _("ignoring absolute DW_AT_sibling")); else { - unsigned int off = dwarf2_get_ref_die_offset (&attr).sect_off; - const gdb_byte *sibling_ptr = buffer + off; + sect_offset off = dwarf2_get_ref_die_offset (&attr); + const gdb_byte *sibling_ptr = buffer + to_underlying (off); if (sibling_ptr < info_ptr) complaint (&symfile_complaints, @@ -16287,7 +16290,7 @@ read_partial_die (const struct die_reader_specs *reader, case DW_AT_import: if (part_die->tag == DW_TAG_imported_unit) { - part_die->d.offset = dwarf2_get_ref_die_offset (&attr); + part_die->d.sect_off = dwarf2_get_ref_die_offset (&attr); part_die->is_dwz = (attr.form == DW_FORM_GNU_ref_alt || cu->per_cu->is_dwz); } @@ -16323,7 +16326,7 @@ read_partial_die (const struct die_reader_specs *reader, _("DW_AT_low_pc %s is zero " "for DIE at 0x%x [in module %s]"), paddress (gdbarch, part_die->lowpc), - part_die->offset.sect_off, objfile_name (objfile)); + to_underlying (part_die->sect_off), objfile_name (objfile)); } /* dwarf2_get_pc_bounds has also the strict low < high requirement. */ else if (part_die->lowpc >= part_die->highpc) @@ -16335,7 +16338,8 @@ read_partial_die (const struct die_reader_specs *reader, "for DIE at 0x%x [in module %s]"), paddress (gdbarch, part_die->lowpc), paddress (gdbarch, part_die->highpc), - part_die->offset.sect_off, objfile_name (objfile)); + to_underlying (part_die->sect_off), + objfile_name (objfile)); } else part_die->has_pc_info = 1; @@ -16347,15 +16351,15 @@ read_partial_die (const struct die_reader_specs *reader, /* Find a cached partial DIE at OFFSET in CU. */ static struct partial_die_info * -find_partial_die_in_comp_unit (sect_offset offset, struct dwarf2_cu *cu) +find_partial_die_in_comp_unit (sect_offset sect_off, struct dwarf2_cu *cu) { struct partial_die_info *lookup_die = NULL; struct partial_die_info part_die; - part_die.offset = offset; + part_die.sect_off = sect_off; lookup_die = ((struct partial_die_info *) htab_find_with_hash (cu->partial_dies, &part_die, - offset.sect_off)); + to_underlying (sect_off))); return lookup_die; } @@ -16366,16 +16370,16 @@ find_partial_die_in_comp_unit (sect_offset offset, struct dwarf2_cu *cu) DW_FORM_ref_sig8). */ static struct partial_die_info * -find_partial_die (sect_offset offset, int offset_in_dwz, struct dwarf2_cu *cu) +find_partial_die (sect_offset sect_off, int offset_in_dwz, struct dwarf2_cu *cu) { struct objfile *objfile = cu->objfile; struct dwarf2_per_cu_data *per_cu = NULL; struct partial_die_info *pd = NULL; if (offset_in_dwz == cu->per_cu->is_dwz - && offset_in_cu_p (&cu->header, offset)) + && offset_in_cu_p (&cu->header, sect_off)) { - pd = find_partial_die_in_comp_unit (offset, cu); + pd = find_partial_die_in_comp_unit (sect_off, cu); if (pd != NULL) return pd; /* We missed recording what we needed. @@ -16387,19 +16391,19 @@ find_partial_die (sect_offset offset, int offset_in_dwz, struct dwarf2_cu *cu) /* TUs don't reference other CUs/TUs (except via type signatures). */ if (cu->per_cu->is_debug_types) { - error (_("Dwarf Error: Type Unit at offset 0x%lx contains" - " external reference to offset 0x%lx [in module %s].\n"), - (long) cu->header.offset.sect_off, (long) offset.sect_off, + error (_("Dwarf Error: Type Unit at offset 0x%x contains" + " external reference to offset 0x%x [in module %s].\n"), + to_underlying (cu->header.sect_off), to_underlying (sect_off), bfd_get_filename (objfile->obfd)); } - per_cu = dwarf2_find_containing_comp_unit (offset, offset_in_dwz, + per_cu = dwarf2_find_containing_comp_unit (sect_off, offset_in_dwz, objfile); if (per_cu->cu == NULL || per_cu->cu->partial_dies == NULL) load_partial_comp_unit (per_cu); per_cu->cu->last_used = 0; - pd = find_partial_die_in_comp_unit (offset, per_cu->cu); + pd = find_partial_die_in_comp_unit (sect_off, per_cu->cu); } /* If we didn't find it, and not all dies have been loaded, @@ -16417,14 +16421,14 @@ find_partial_die (sect_offset offset, int offset_in_dwz, struct dwarf2_cu *cu) set. */ load_partial_comp_unit (per_cu); - pd = find_partial_die_in_comp_unit (offset, per_cu->cu); + pd = find_partial_die_in_comp_unit (sect_off, per_cu->cu); } if (pd == NULL) internal_error (__FILE__, __LINE__, _("could not find partial DIE 0x%x " "in cache [from module %s]\n"), - offset.sect_off, bfd_get_filename (objfile->obfd)); + to_underlying (sect_off), bfd_get_filename (objfile->obfd)); return pd; } @@ -16715,22 +16719,22 @@ read_attribute_value (const struct die_reader_specs *reader, info_ptr += bytes_read; break; case DW_FORM_ref1: - DW_UNSND (attr) = (cu->header.offset.sect_off + DW_UNSND (attr) = (to_underlying (cu->header.sect_off) + read_1_byte (abfd, info_ptr)); info_ptr += 1; break; case DW_FORM_ref2: - DW_UNSND (attr) = (cu->header.offset.sect_off + DW_UNSND (attr) = (to_underlying (cu->header.sect_off) + read_2_bytes (abfd, info_ptr)); info_ptr += 2; break; case DW_FORM_ref4: - DW_UNSND (attr) = (cu->header.offset.sect_off + DW_UNSND (attr) = (to_underlying (cu->header.sect_off) + read_4_bytes (abfd, info_ptr)); info_ptr += 4; break; case DW_FORM_ref8: - DW_UNSND (attr) = (cu->header.offset.sect_off + DW_UNSND (attr) = (to_underlying (cu->header.sect_off) + read_8_bytes (abfd, info_ptr)); info_ptr += 8; break; @@ -16739,7 +16743,7 @@ read_attribute_value (const struct die_reader_specs *reader, info_ptr += 8; break; case DW_FORM_ref_udata: - DW_UNSND (attr) = (cu->header.offset.sect_off + DW_UNSND (attr) = (to_underlying (cu->header.sect_off) + read_unsigned_leb128 (abfd, info_ptr, &bytes_read)); info_ptr += bytes_read; break; @@ -17378,16 +17382,16 @@ read_str_index (const struct die_reader_specs *reader, ULONGEST str_index) dwarf2_read_section (objfile, str_offsets_section); if (str_section->buffer == NULL) error (_("%s used without .debug_str.dwo section" - " in CU at offset 0x%lx [in module %s]"), - form_name, (long) cu->header.offset.sect_off, objf_name); + " in CU at offset 0x%x [in module %s]"), + form_name, to_underlying (cu->header.sect_off), objf_name); if (str_offsets_section->buffer == NULL) error (_("%s used without .debug_str_offsets.dwo section" - " in CU at offset 0x%lx [in module %s]"), - form_name, (long) cu->header.offset.sect_off, objf_name); + " in CU at offset 0x%x [in module %s]"), + form_name, to_underlying (cu->header.sect_off), objf_name); if (str_index * cu->header.offset_size >= str_offsets_section->size) error (_("%s pointing outside of .debug_str_offsets.dwo" - " section in CU at offset 0x%lx [in module %s]"), - form_name, (long) cu->header.offset.sect_off, objf_name); + " section in CU at offset 0x%x [in module %s]"), + form_name, to_underlying (cu->header.sect_off), objf_name); info_ptr = (str_offsets_section->buffer + str_index * cu->header.offset_size); if (cu->header.offset_size == 4) @@ -17396,8 +17400,8 @@ read_str_index (const struct die_reader_specs *reader, ULONGEST str_index) str_offset = bfd_get_64 (abfd, info_ptr); if (str_offset >= str_section->size) error (_("Offset from %s pointing outside of" - " .debug_str.dwo section in CU at offset 0x%lx [in module %s]"), - form_name, (long) cu->header.offset.sect_off, objf_name); + " .debug_str.dwo section in CU at offset 0x%x [in module %s]"), + form_name, to_underlying (cu->header.sect_off), objf_name); return (const char *) (str_section->buffer + str_offset); } @@ -17543,7 +17547,7 @@ dwarf2_string_attr (struct die_info *die, unsigned int name, struct dwarf2_cu *c complaint (&symfile_complaints, _("string type expected for attribute %s for " "DIE at 0x%x in module %s"), - dwarf_attr_name (name), die->offset.sect_off, + dwarf_attr_name (name), to_underlying (die->sect_off), objfile_name (cu->objfile)); } @@ -17793,7 +17797,7 @@ read_formatted_entries (bfd *abfd, const gdb_byte **bufp, and must not be freed. */ static line_header_up -dwarf_decode_line_header (unsigned int offset, struct dwarf2_cu *cu) +dwarf_decode_line_header (sect_offset sect_off, struct dwarf2_cu *cu) { const gdb_byte *line_ptr; unsigned int bytes_read, offset_size; @@ -17819,7 +17823,7 @@ dwarf_decode_line_header (unsigned int offset, struct dwarf2_cu *cu) /* Make sure that at least there's room for the total_length field. That could be 12 bytes long, but we're just going to fudge that. */ - if (offset + 4 >= section->size) + if (to_underlying (sect_off) + 4 >= section->size) { dwarf2_statement_list_fits_in_line_number_section_complaint (); return 0; @@ -17827,10 +17831,10 @@ dwarf_decode_line_header (unsigned int offset, struct dwarf2_cu *cu) line_header_up lh (new line_header ()); - lh->offset.sect_off = offset; + lh->sect_off = sect_off; lh->offset_in_dwz = cu->per_cu->is_dwz; - line_ptr = section->buffer + offset; + line_ptr = section->buffer + to_underlying (sect_off); /* Read in the header. */ lh->total_length = @@ -19487,8 +19491,8 @@ build_error_marker_type (struct dwarf2_cu *cu, struct die_info *die) message = xstrprintf (_("<unknown type in %s, CU 0x%x, DIE 0x%x>"), objfile_name (objfile), - cu->header.offset.sect_off, - die->offset.sect_off); + to_underlying (cu->header.sect_off), + to_underlying (die->sect_off)); saved = (char *) obstack_copy0 (&objfile->objfile_obstack, message, strlen (message)); xfree (message); @@ -19517,16 +19521,16 @@ lookup_die_type (struct die_info *die, const struct attribute *attr, if (attr->form == DW_FORM_GNU_ref_alt) { struct dwarf2_per_cu_data *per_cu; - sect_offset offset = dwarf2_get_ref_die_offset (attr); + sect_offset sect_off = dwarf2_get_ref_die_offset (attr); - per_cu = dwarf2_find_containing_comp_unit (offset, 1, cu->objfile); - this_type = get_die_type_at_offset (offset, per_cu); + per_cu = dwarf2_find_containing_comp_unit (sect_off, 1, cu->objfile); + this_type = get_die_type_at_offset (sect_off, per_cu); } else if (attr_form_is_ref (attr)) { - sect_offset offset = dwarf2_get_ref_die_offset (attr); + sect_offset sect_off = dwarf2_get_ref_die_offset (attr); - this_type = get_die_type_at_offset (offset, cu->per_cu); + this_type = get_die_type_at_offset (sect_off, cu->per_cu); } else if (attr->form == DW_FORM_ref_sig8) { @@ -19539,7 +19543,7 @@ lookup_die_type (struct die_info *die, const struct attribute *attr, complaint (&symfile_complaints, _("Dwarf Error: Bad type attribute %s in DIE" " at 0x%x [in module %s]"), - dwarf_attr_name (attr->name), die->offset.sect_off, + dwarf_attr_name (attr->name), to_underlying (die->sect_off), objfile_name (objfile)); return build_error_marker_type (cu, die); } @@ -20234,13 +20238,14 @@ dump_die_shallow (struct ui_file *f, int indent, struct die_info *die) print_spaces (indent, f); fprintf_unfiltered (f, "Die: %s (abbrev %d, offset 0x%x)\n", - dwarf_tag_name (die->tag), die->abbrev, die->offset.sect_off); + dwarf_tag_name (die->tag), die->abbrev, + to_underlying (die->sect_off)); if (die->parent != NULL) { print_spaces (indent, f); fprintf_unfiltered (f, " parent at offset: 0x%x\n", - die->parent->offset.sect_off); + to_underlying (die->parent->sect_off)); } print_spaces (indent, f); @@ -20399,7 +20404,8 @@ store_in_ref_table (struct die_info *die, struct dwarf2_cu *cu) { void **slot; - slot = htab_find_slot_with_hash (cu->die_hash, die, die->offset.sect_off, + slot = htab_find_slot_with_hash (cu->die_hash, die, + to_underlying (die->sect_off), INSERT); *slot = die; @@ -20411,16 +20417,13 @@ store_in_ref_table (struct die_info *die, struct dwarf2_cu *cu) static sect_offset dwarf2_get_ref_die_offset (const struct attribute *attr) { - sect_offset retval = { DW_UNSND (attr) }; - if (attr_form_is_ref (attr)) - return retval; + return (sect_offset) DW_UNSND (attr); - retval.sect_off = 0; complaint (&symfile_complaints, _("unsupported die ref attribute form: '%s'"), dwarf_form_name (attr->form)); - return retval; + return {}; } /* Return the constant value held by ATTR. Return DEFAULT_VALUE if @@ -20477,7 +20480,7 @@ follow_die_ref_or_sig (struct die_info *src_die, const struct attribute *attr, Returns NULL if OFFSET is invalid. */ static struct die_info * -follow_die_offset (sect_offset offset, int offset_in_dwz, +follow_die_offset (sect_offset sect_off, int offset_in_dwz, struct dwarf2_cu **ref_cu) { struct die_info temp_die; @@ -20492,15 +20495,15 @@ follow_die_offset (sect_offset offset, int offset_in_dwz, /* .debug_types CUs cannot reference anything outside their CU. If they need to, they have to reference a signatured type via DW_FORM_ref_sig8. */ - if (! offset_in_cu_p (&cu->header, offset)) + if (!offset_in_cu_p (&cu->header, sect_off)) return NULL; } else if (offset_in_dwz != cu->per_cu->is_dwz - || ! offset_in_cu_p (&cu->header, offset)) + || !offset_in_cu_p (&cu->header, sect_off)) { struct dwarf2_per_cu_data *per_cu; - per_cu = dwarf2_find_containing_comp_unit (offset, offset_in_dwz, + per_cu = dwarf2_find_containing_comp_unit (sect_off, offset_in_dwz, cu->objfile); /* If necessary, add it to the queue and load its DIEs. */ @@ -20517,9 +20520,10 @@ follow_die_offset (sect_offset offset, int offset_in_dwz, } *ref_cu = target_cu; - temp_die.offset = offset; + temp_die.sect_off = sect_off; return (struct die_info *) htab_find_with_hash (target_cu->die_hash, - &temp_die, offset.sect_off); + &temp_die, + to_underlying (sect_off)); } /* Follow reference attribute ATTR of SRC_DIE. @@ -20530,29 +20534,29 @@ static struct die_info * follow_die_ref (struct die_info *src_die, const struct attribute *attr, struct dwarf2_cu **ref_cu) { - sect_offset offset = dwarf2_get_ref_die_offset (attr); + sect_offset sect_off = dwarf2_get_ref_die_offset (attr); struct dwarf2_cu *cu = *ref_cu; struct die_info *die; - die = follow_die_offset (offset, + die = follow_die_offset (sect_off, (attr->form == DW_FORM_GNU_ref_alt || cu->per_cu->is_dwz), ref_cu); if (!die) error (_("Dwarf Error: Cannot find DIE at 0x%x referenced from DIE " "at 0x%x [in module %s]"), - offset.sect_off, src_die->offset.sect_off, + to_underlying (sect_off), to_underlying (src_die->sect_off), objfile_name (cu->objfile)); return die; } -/* Return DWARF block referenced by DW_AT_location of DIE at OFFSET at PER_CU. +/* Return DWARF block referenced by DW_AT_location of DIE at SECT_OFF at PER_CU. Returned value is intended for DW_OP_call*. Returned dwarf2_locexpr_baton->data has lifetime of PER_CU->OBJFILE. */ struct dwarf2_locexpr_baton -dwarf2_fetch_die_loc_sect_off (sect_offset offset, +dwarf2_fetch_die_loc_sect_off (sect_offset sect_off, struct dwarf2_per_cu_data *per_cu, CORE_ADDR (*get_frame_pc) (void *baton), void *baton) @@ -20572,13 +20576,13 @@ dwarf2_fetch_die_loc_sect_off (sect_offset offset, /* We shouldn't get here for a dummy CU, but don't crash on the user. Instead just throw an error, not much else we can do. */ error (_("Dwarf Error: Dummy CU at 0x%x referenced in module %s"), - offset.sect_off, objfile_name (per_cu->objfile)); + to_underlying (sect_off), objfile_name (per_cu->objfile)); } - die = follow_die_offset (offset, per_cu->is_dwz, &cu); + die = follow_die_offset (sect_off, per_cu->is_dwz, &cu); if (!die) error (_("Dwarf Error: Cannot find DIE at 0x%x referenced in module %s"), - offset.sect_off, objfile_name (per_cu->objfile)); + to_underlying (sect_off), objfile_name (per_cu->objfile)); attr = dwarf2_attr (die, DW_AT_location, cu); if (!attr) @@ -20606,7 +20610,7 @@ dwarf2_fetch_die_loc_sect_off (sect_offset offset, if (!attr_form_is_block (attr)) error (_("Dwarf Error: DIE at 0x%x referenced in module %s " "is neither DW_FORM_block* nor DW_FORM_exprloc"), - offset.sect_off, objfile_name (per_cu->objfile)); + to_underlying (sect_off), objfile_name (per_cu->objfile)); retval.data = DW_BLOCK (attr)->data; retval.size = DW_BLOCK (attr)->size; @@ -20627,9 +20631,9 @@ dwarf2_fetch_die_loc_cu_off (cu_offset offset_in_cu, CORE_ADDR (*get_frame_pc) (void *baton), void *baton) { - sect_offset offset = { per_cu->offset.sect_off + offset_in_cu.cu_off }; + sect_offset sect_off = per_cu->sect_off + to_underlying (offset_in_cu); - return dwarf2_fetch_die_loc_sect_off (offset, per_cu, get_frame_pc, baton); + return dwarf2_fetch_die_loc_sect_off (sect_off, per_cu, get_frame_pc, baton); } /* Write a constant of a given type as target-ordered bytes into @@ -20657,7 +20661,7 @@ write_constant_as_bytes (struct obstack *obstack, does not have a DW_AT_const_value, return NULL. */ const gdb_byte * -dwarf2_fetch_constant_bytes (sect_offset offset, +dwarf2_fetch_constant_bytes (sect_offset sect_off, struct dwarf2_per_cu_data *per_cu, struct obstack *obstack, LONGEST *len) @@ -20680,13 +20684,13 @@ dwarf2_fetch_constant_bytes (sect_offset offset, /* We shouldn't get here for a dummy CU, but don't crash on the user. Instead just throw an error, not much else we can do. */ error (_("Dwarf Error: Dummy CU at 0x%x referenced in module %s"), - offset.sect_off, objfile_name (per_cu->objfile)); + to_underlying (sect_off), objfile_name (per_cu->objfile)); } - die = follow_die_offset (offset, per_cu->is_dwz, &cu); + die = follow_die_offset (sect_off, per_cu->is_dwz, &cu); if (!die) error (_("Dwarf Error: Cannot find DIE at 0x%x referenced in module %s"), - offset.sect_off, objfile_name (per_cu->objfile)); + to_underlying (sect_off), objfile_name (per_cu->objfile)); attr = dwarf2_attr (die, DW_AT_const_value, cu); @@ -20788,7 +20792,7 @@ dwarf2_fetch_constant_bytes (sect_offset offset, valid type for this die is found. */ struct type * -dwarf2_fetch_die_type_sect_off (sect_offset offset, +dwarf2_fetch_die_type_sect_off (sect_offset sect_off, struct dwarf2_per_cu_data *per_cu) { struct dwarf2_cu *cu; @@ -20802,7 +20806,7 @@ dwarf2_fetch_die_type_sect_off (sect_offset offset, if (!cu) return NULL; - die = follow_die_offset (offset, per_cu->is_dwz, &cu); + die = follow_die_offset (sect_off, per_cu->is_dwz, &cu); if (!die) return NULL; @@ -20816,11 +20820,9 @@ struct type * dwarf2_get_die_type (cu_offset die_offset, struct dwarf2_per_cu_data *per_cu) { - sect_offset die_offset_sect; - dw2_setup (per_cu->objfile); - die_offset_sect.sect_off = per_cu->offset.sect_off + die_offset.cu_off; + sect_offset die_offset_sect = per_cu->sect_off + to_underlying (die_offset); return get_die_type_at_offset (die_offset_sect, per_cu); } @@ -20848,10 +20850,10 @@ follow_die_sig_1 (struct die_info *src_die, struct signatured_type *sig_type, sig_cu = sig_type->per_cu.cu; gdb_assert (sig_cu != NULL); - gdb_assert (sig_type->type_offset_in_section.sect_off != 0); - temp_die.offset = sig_type->type_offset_in_section; + gdb_assert (to_underlying (sig_type->type_offset_in_section) != 0); + temp_die.sect_off = sig_type->type_offset_in_section; die = (struct die_info *) htab_find_with_hash (sig_cu->die_hash, &temp_die, - temp_die.offset.sect_off); + to_underlying (temp_die.sect_off)); if (die) { /* For .gdb_index version 7 keep track of included TUs. @@ -20894,7 +20896,7 @@ follow_die_sig (struct die_info *src_die, const struct attribute *attr, { error (_("Dwarf Error: Cannot find signatured DIE %s referenced" " from DIE at 0x%x [in module %s]"), - hex_string (signature), src_die->offset.sect_off, + hex_string (signature), to_underlying (src_die->sect_off), objfile_name ((*ref_cu)->objfile)); } @@ -20904,7 +20906,7 @@ follow_die_sig (struct die_info *src_die, const struct attribute *attr, dump_die_for_error (src_die); error (_("Dwarf Error: Problem reading signatured DIE %s referenced" " from DIE at 0x%x [in module %s]"), - hex_string (signature), src_die->offset.sect_off, + hex_string (signature), to_underlying (src_die->sect_off), objfile_name ((*ref_cu)->objfile)); } @@ -20931,7 +20933,7 @@ get_signatured_type (struct die_info *die, ULONGEST signature, complaint (&symfile_complaints, _("Dwarf Error: Cannot find signatured DIE %s referenced" " from DIE at 0x%x [in module %s]"), - hex_string (signature), die->offset.sect_off, + hex_string (signature), to_underlying (die->sect_off), objfile_name (dwarf2_per_objfile->objfile)); return build_error_marker_type (cu, die); } @@ -20953,7 +20955,7 @@ get_signatured_type (struct die_info *die, ULONGEST signature, complaint (&symfile_complaints, _("Dwarf Error: Cannot build signatured type %s" " referenced from DIE at 0x%x [in module %s]"), - hex_string (signature), die->offset.sect_off, + hex_string (signature), to_underlying (die->sect_off), objfile_name (dwarf2_per_objfile->objfile)); type = build_error_marker_type (cu, die); } @@ -20963,7 +20965,7 @@ get_signatured_type (struct die_info *die, ULONGEST signature, complaint (&symfile_complaints, _("Dwarf Error: Problem reading signatured DIE %s referenced" " from DIE at 0x%x [in module %s]"), - hex_string (signature), die->offset.sect_off, + hex_string (signature), to_underlying (die->sect_off), objfile_name (dwarf2_per_objfile->objfile)); type = build_error_marker_type (cu, die); } @@ -20996,7 +20998,7 @@ get_DW_AT_signature_type (struct die_info *die, const struct attribute *attr, complaint (&symfile_complaints, _("Dwarf Error: DW_AT_signature has bad form %s in DIE" " at 0x%x [in module %s]"), - dwarf_form_name (attr->form), die->offset.sect_off, + dwarf_form_name (attr->form), to_underlying (die->sect_off), objfile_name (dwarf2_per_objfile->objfile)); return build_error_marker_type (cu, die); } @@ -22498,7 +22500,7 @@ per_cu_header_read_in (struct comp_unit_head *cu_headerp, if (per_cu->cu) return &per_cu->cu->header; - info_ptr = per_cu->section->buffer + per_cu->offset.sect_off; + info_ptr = per_cu->section->buffer + to_underlying (per_cu->sect_off); memset (cu_headerp, 0, sizeof (*cu_headerp)); read_comp_unit_head (cu_headerp, info_ptr, per_cu->section, @@ -22574,7 +22576,7 @@ dwarf2_version (struct dwarf2_per_cu_data *per_cu) the DIE at OFFSET. Raises an error on failure. */ static struct dwarf2_per_cu_data * -dwarf2_find_containing_comp_unit (sect_offset offset, +dwarf2_find_containing_comp_unit (sect_offset sect_off, unsigned int offset_in_dwz, struct objfile *objfile) { @@ -22590,35 +22592,34 @@ dwarf2_find_containing_comp_unit (sect_offset offset, int mid = low + (high - low) / 2; mid_cu = dwarf2_per_objfile->all_comp_units[mid]; - cu_off = &mid_cu->offset; + cu_off = &mid_cu->sect_off; if (mid_cu->is_dwz > offset_in_dwz - || (mid_cu->is_dwz == offset_in_dwz - && cu_off->sect_off >= offset.sect_off)) + || (mid_cu->is_dwz == offset_in_dwz && *cu_off >= sect_off)) high = mid; else low = mid + 1; } gdb_assert (low == high); this_cu = dwarf2_per_objfile->all_comp_units[low]; - cu_off = &this_cu->offset; - if (this_cu->is_dwz != offset_in_dwz || cu_off->sect_off > offset.sect_off) + cu_off = &this_cu->sect_off; + if (this_cu->is_dwz != offset_in_dwz || *cu_off > sect_off) { if (low == 0 || this_cu->is_dwz != offset_in_dwz) error (_("Dwarf Error: could not find partial DIE containing " - "offset 0x%lx [in module %s]"), - (long) offset.sect_off, bfd_get_filename (objfile->obfd)); + "offset 0x%x [in module %s]"), + to_underlying (sect_off), bfd_get_filename (objfile->obfd)); - gdb_assert (dwarf2_per_objfile->all_comp_units[low-1]->offset.sect_off - <= offset.sect_off); + gdb_assert (dwarf2_per_objfile->all_comp_units[low-1]->sect_off + <= sect_off); return dwarf2_per_objfile->all_comp_units[low-1]; } else { this_cu = dwarf2_per_objfile->all_comp_units[low]; if (low == dwarf2_per_objfile->n_comp_units - 1 - && offset.sect_off >= this_cu->offset.sect_off + this_cu->length) - error (_("invalid dwarf2 offset %u"), offset.sect_off); - gdb_assert (offset.sect_off < this_cu->offset.sect_off + this_cu->length); + && sect_off >= this_cu->sect_off + this_cu->length) + error (_("invalid dwarf2 offset %u"), to_underlying (sect_off)); + gdb_assert (sect_off < this_cu->sect_off + this_cu->length); return this_cu; } } @@ -22823,7 +22824,7 @@ dwarf2_free_objfile (struct objfile *objfile) struct dwarf2_per_cu_offset_and_type { const struct dwarf2_per_cu_data *per_cu; - sect_offset offset; + sect_offset sect_off; struct type *type; }; @@ -22835,7 +22836,7 @@ per_cu_offset_and_type_hash (const void *item) const struct dwarf2_per_cu_offset_and_type *ofs = (const struct dwarf2_per_cu_offset_and_type *) item; - return (uintptr_t) ofs->per_cu + ofs->offset.sect_off; + return (uintptr_t) ofs->per_cu + to_underlying (ofs->sect_off); } /* Equality function for a dwarf2_per_cu_offset_and_type. */ @@ -22849,7 +22850,7 @@ per_cu_offset_and_type_eq (const void *item_lhs, const void *item_rhs) = (const struct dwarf2_per_cu_offset_and_type *) item_rhs; return (ofs_lhs->per_cu == ofs_rhs->per_cu - && ofs_lhs->offset.sect_off == ofs_rhs->offset.sect_off); + && ofs_lhs->sect_off == ofs_rhs->sect_off); } /* Set the type associated with DIE to TYPE. Save it in CU's hash @@ -22904,9 +22905,9 @@ set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu) else if (attr != NULL) { complaint (&symfile_complaints, - _("DW_AT_allocated has the wrong form (%s) at DIE 0x%x"), - (attr != NULL ? dwarf_form_name (attr->form) : "n/a"), - die->offset.sect_off); + _("DW_AT_allocated has the wrong form (%s) at DIE 0x%x"), + (attr != NULL ? dwarf_form_name (attr->form) : "n/a"), + to_underlying (die->sect_off)); } /* Read DW_AT_associated and set in type. */ @@ -22919,9 +22920,9 @@ set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu) else if (attr != NULL) { complaint (&symfile_complaints, - _("DW_AT_associated has the wrong form (%s) at DIE 0x%x"), - (attr != NULL ? dwarf_form_name (attr->form) : "n/a"), - die->offset.sect_off); + _("DW_AT_associated has the wrong form (%s) at DIE 0x%x"), + (attr != NULL ? dwarf_form_name (attr->form) : "n/a"), + to_underlying (die->sect_off)); } /* Read DW_AT_data_location and set in type. */ @@ -22942,25 +22943,25 @@ set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu) } ofs.per_cu = cu->per_cu; - ofs.offset = die->offset; + ofs.sect_off = die->sect_off; ofs.type = type; slot = (struct dwarf2_per_cu_offset_and_type **) htab_find_slot (dwarf2_per_objfile->die_type_hash, &ofs, INSERT); if (*slot) complaint (&symfile_complaints, _("A problem internal to GDB: DIE 0x%x has type already set"), - die->offset.sect_off); + to_underlying (die->sect_off)); *slot = XOBNEW (&objfile->objfile_obstack, struct dwarf2_per_cu_offset_and_type); **slot = ofs; return type; } -/* Look up the type for the die at OFFSET in PER_CU in die_type_hash, +/* Look up the type for the die at SECT_OFF in PER_CU in die_type_hash, or return NULL if the die does not have a saved type. */ static struct type * -get_die_type_at_offset (sect_offset offset, +get_die_type_at_offset (sect_offset sect_off, struct dwarf2_per_cu_data *per_cu) { struct dwarf2_per_cu_offset_and_type *slot, ofs; @@ -22969,7 +22970,7 @@ get_die_type_at_offset (sect_offset offset, return NULL; ofs.per_cu = per_cu; - ofs.offset = offset; + ofs.sect_off = sect_off; slot = ((struct dwarf2_per_cu_offset_and_type *) htab_find (dwarf2_per_objfile->die_type_hash, &ofs)); if (slot) @@ -22984,7 +22985,7 @@ get_die_type_at_offset (sect_offset offset, static struct type * get_die_type (struct die_info *die, struct dwarf2_cu *cu) { - return get_die_type_at_offset (die->offset, cu->per_cu); + return get_die_type_at_offset (die->sect_off, cu->per_cu); } /* Add a dependence relationship from CU to REF_PER_CU. */ @@ -23066,7 +23067,7 @@ partial_die_hash (const void *item) const struct partial_die_info *part_die = (const struct partial_die_info *) item; - return part_die->offset.sect_off; + return to_underlying (part_die->sect_off); } /* Trivial comparison function for partial_die_info structures: two DIEs @@ -23080,7 +23081,7 @@ partial_die_eq (const void *item_lhs, const void *item_rhs) const struct partial_die_info *part_die_rhs = (const struct partial_die_info *) item_rhs; - return part_die_lhs->offset.sect_off == part_die_rhs->offset.sect_off; + return part_die_lhs->sect_off == part_die_rhs->sect_off; } static struct cmd_list_element *set_dwarf_cmdlist; @@ -23761,10 +23762,10 @@ write_one_signatured_type (void **slot, void *d) 1); store_unsigned_integer (val, 8, BFD_ENDIAN_LITTLE, - entry->per_cu.offset.sect_off); + to_underlying (entry->per_cu.sect_off)); obstack_grow (info->types_list, val, 8); store_unsigned_integer (val, 8, BFD_ENDIAN_LITTLE, - entry->type_offset_in_tu.cu_off); + to_underlying (entry->type_offset_in_tu)); obstack_grow (info->types_list, val, 8); store_unsigned_integer (val, 8, BFD_ENDIAN_LITTLE, entry->signature); obstack_grow (info->types_list, val, 8); @@ -23900,7 +23901,7 @@ write_psymtabs_to_index (struct objfile *objfile, const char *dir) *slot = map; store_unsigned_integer (val, 8, BFD_ENDIAN_LITTLE, - per_cu->offset.sect_off); + to_underlying (per_cu->sect_off)); obstack_grow (&cu_list, val, 8); store_unsigned_integer (val, 8, BFD_ENDIAN_LITTLE, per_cu->length); obstack_grow (&cu_list, val, 8); diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h index 4abeaf3..3c57970 100644 --- a/gdb/gdbtypes.h +++ b/gdb/gdbtypes.h @@ -45,6 +45,7 @@ */ #include "hashtab.h" +#include "common/offset-type.h" /* Forward declarations for prototypes. */ struct field; @@ -57,18 +58,11 @@ struct language_defn; /* * Offset relative to the start of its containing CU (compilation unit). */ -typedef struct -{ - unsigned int cu_off; -} cu_offset; +DEFINE_OFFSET_TYPE (cu_offset, unsigned int); /* * Offset relative to the start of its .debug_info or .debug_types section. */ - -typedef struct -{ - unsigned int sect_off; -} sect_offset; +DEFINE_OFFSET_TYPE (sect_offset, unsigned int); /* Some macros for char-based bitfields. */ @@ -1108,7 +1102,7 @@ union call_site_parameter_u DW_TAG_formal_parameter which is referenced by both caller and the callee. */ - cu_offset param_offset; + cu_offset param_cu_off; }; struct call_site_parameter diff --git a/gdb/unittests/offset-type-selftests.c b/gdb/unittests/offset-type-selftests.c new file mode 100644 index 0000000..a11e908 --- /dev/null +++ b/gdb/unittests/offset-type-selftests.c @@ -0,0 +1,178 @@ +/* Self tests for offset types for GDB, the GNU debugger. + + Copyright (C) 2017 Free Software Foundation, Inc. + + 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 "selftest.h" +#include "common/offset-type.h" +#include "common/underlying.h" +#include "common/valid-expr.h" + +namespace selftests { +namespace offset_type { + +DEFINE_OFFSET_TYPE (off_A, unsigned int); +DEFINE_OFFSET_TYPE (off_B, unsigned int); + +/* First, compile-time tests that: + + - make sure that incorrect operations with mismatching types are + caught at compile time. + + - make sure that the same operations but involving the right types + do compile and that they return the correct type. +*/ + +#define CHECK_VALID(VALID, EXPR_TYPE, EXPR) \ + CHECK_VALID_EXPR_2 (off_A, off_B, VALID, EXPR_TYPE, EXPR) + +off_A lval_a {}; +off_B lval_b {}; + +using undrl = std::underlying_type<off_A>::type; + +/* Offset +/- underlying. */ + +CHECK_VALID (true, off_A, off_A {} + undrl {}); +CHECK_VALID (true, off_A, off_A {} - undrl {}); +CHECK_VALID (true, off_A, undrl {} + off_A {}); +CHECK_VALID (true, off_A, undrl {} - off_A {}); + +/* Add offset types. Both same and different. */ + +CHECK_VALID (false, void, off_A {} + off_A {}); +CHECK_VALID (false, void, off_A {} + off_B {}); + +/* Subtract offset types. Both same and different. */ + +CHECK_VALID (false, void, off_B {} - off_A {}); +CHECK_VALID (true, undrl, off_A {} - off_A {}); + +/* Add/assign offset types. Both same and different. */ + +CHECK_VALID (false, void, lval_a += off_A {}); +CHECK_VALID (false, void, lval_a += off_B {}); +CHECK_VALID (false, void, lval_a -= off_A {}); +CHECK_VALID (false, void, lval_a -= off_B {}); + +/* operator OP+= (offset, underlying), lvalue ref on the lhs. */ + +CHECK_VALID (true, off_A&, lval_a += undrl {}); +CHECK_VALID (true, off_A&, lval_a -= undrl {}); + +/* operator OP+= (offset, underlying), rvalue ref on the lhs. */ + +CHECK_VALID (false, void, off_A {} += undrl {}); +CHECK_VALID (false, void, off_A {} -= undrl {}); + +/* Rel ops, with same type. */ + +CHECK_VALID (true, bool, off_A {} < off_A {}); +CHECK_VALID (true, bool, off_A {} > off_A {}); +CHECK_VALID (true, bool, off_A {} <= off_A {}); +CHECK_VALID (true, bool, off_A {} >= off_A {}); + +/* Rel ops, with unrelated offset types. */ + +CHECK_VALID (false, void, off_A {} < off_B {}); +CHECK_VALID (false, void, off_A {} > off_B {}); +CHECK_VALID (false, void, off_A {} <= off_B {}); +CHECK_VALID (false, void, off_A {} >= off_B {}); + +/* Rel ops, with unrelated types. */ + +CHECK_VALID (false, void, off_A {} < undrl {}); +CHECK_VALID (false, void, off_A {} > undrl {}); +CHECK_VALID (false, void, off_A {} <= undrl {}); +CHECK_VALID (false, void, off_A {} >= undrl {}); + +static void +run_tests () +{ + /* Test op+ and op-. */ + { + constexpr off_A a {}; + static_assert (to_underlying (a) == 0, ""); + + { + constexpr off_A res1 = a + 2; + static_assert (to_underlying (res1) == 2, ""); + + constexpr off_A res2 = res1 - 1; + static_assert (to_underlying (res2) == 1, ""); + } + + { + constexpr off_A res1 = 2 + a; + static_assert (to_underlying (res1) == 2, ""); + + constexpr off_A res2 = 3 - res1; + static_assert (to_underlying (res2) == 1, ""); + } + } + + /* Test op+= and op-=. */ + { + off_A o {}; + + o += 10; + SELF_CHECK (to_underlying (o) == 10); + o -= 5; + SELF_CHECK (to_underlying (o) == 5); + } + + /* Test op-. */ + { + constexpr off_A o1 = (off_A) 10; + constexpr off_A o2 = (off_A) 20; + + constexpr unsigned int delta = o2 - o1; + + static_assert (delta == 10, ""); + } + + /* Test <, <=, >, >=. */ + { + constexpr off_A o1 = (off_A) 10; + constexpr off_A o2 = (off_A) 20; + + static_assert (o1 < o2, ""); + static_assert (!(o2 < o1), ""); + + static_assert (o2 > o1, ""); + static_assert (!(o1 > o2), ""); + + static_assert (o1 <= o2, ""); + static_assert (!(o2 <= o1), ""); + + static_assert (o2 >= o1, ""); + static_assert (!(o1 >= o2), ""); + + static_assert (o1 <= o1, ""); + static_assert (o1 >= o1, ""); + } +} + +} /* namespace offset_type */ +} /* namespace selftests */ + +void +_initialize_offset_type_selftests () +{ + register_self_test (selftests::offset_type::run_tests); +} |