aboutsummaryrefslogtreecommitdiff
AgeCommit message (Collapse)AuthorFilesLines
2022-10-26Add support for new DWARF overlay operationsusers/zaric/location_on_dwarf_stackZoran Zaric6-0/+333
Another complex DWARF expression operations, that are usefull for SIMD/SIMT like architectures are: DW_OP_LLVM_overlay and DW_OP_LLVM_bit_overlay. These operations pop four stack entries, where the first must be an integral that represents an overlay size, the second must be an integral that represents a starting point of the overlay from the base location, the third must be a location description that represents the overlay location description and the forth must be a location description that represents the base location description. Resulting composite location description contains parts from base location description, overlayed by the overlay location description, starting from the overlay offset, ending at a sum of the overlay offset and overlay size. A new test in gdb.dwarf2 called dw2-llvm-overlay has been also added to test the support for both operations.
2022-10-25Add support for DWARF location offset type that is larger than 64-bitZoran Zaric1-466/+685
To support new DWARF extension restrictions for location handling a new data type for representing an offset within a location has been added. The new loc_offset type defines a separate handling of the byte and sub_bit parts of the offset while enabling the byte part of the information to utilize a full 64-bit range of values.
2021-11-05Add DW_OP_LLVM_select_bit_piece DWARF operationZoran Zaric6-0/+320
Second more complex DWARF expression operation, that is usefull for SIMD/SIMT like architectures is DW_OP_LLVM_select_bit_piece. This operation pops three stack entries, where the first must be an integral type value that represents a bit mask, the second must be a location description that represents the one-location description and the third must be a location description that represents the zero-location description. Resulting composite location description contains a given number of pieces of a given bit size, created with parts from either of the two location description, based on the bit mask. gdb/ChangeLog: * compile/compile-loc2c.c (compute_stack_depth_worker): Add new DW_OP_LLVM_select_bit_piece operation support. * dwarf2/expr.c (dwarf_expr_context::create_select_composite): New method that creates the select bit piece composite. (dwarf_location::slice): New method. (dwarf_composite::slice): New method. (dwarf_expr_context::execute_stack_op): Add new DW_OP_LLVM_select_bit_piece operation support. * dwarf2/loc.c (dwarf2_get_symbol_read_needs): Add new DW_OP_LLVM_select_bit_piece operation support. (disassemble_dwarf_expression): Add new DW_OP_LLVM_select_bit_piece operation support. include/ChangeLog: * dwarf2.def: Add new DW_OP_LLVM_select_bit_piece enumeration. gdb/testsuite/ChangeLog: * gdb.dwarf2/dw2-llvm-select-bit-piece.exp: New test. * lib/dwarf.exp: Add new DW_OP_LLVM_select_bit_piece operation support.
2021-11-05Add DW_OP_LLVM_extend DWARF operationZoran Zaric6-0/+210
Previous changes allow a new set of more complex DWARF expression operations to be added which are very usefull for SIMD/SIMT like architectures. First of which is the DW_OP_LLVM_extend operation that pops one stack element (which must be a location description) and treat it as a number of pieces of a new composite location description. This means that a resulting composite location contains a given number of pieces of a given bit size, where all the pieces are described by the same location description found on top of the stack. gdb/ChangeLog: * compile/compile-loc2c.c (compute_stack_depth_worker): Add new DW_OP_LLVM_extend operation support. * dwarf2/expr.c (dwarf_expr_context::create_extend_composite): New method that creates the extend composite. (dwarf_expr_context::execute_stack_op): Add new DW_OP_LLVM_extend operation support. * dwarf2/loc.c (dwarf2_get_symbol_read_needs): Add new DW_OP_LLVM_extend operation support. (disassemble_dwarf_expression): Add new DW_OP_LLVM_extend operation support. include/ChangeLog: * dwarf2.def: Add new DW_OP_LLVM_extend enumeration. gdb/testsuite/ChangeLog: * gdb.dwarf2/dw2-llvm-extend.exp: New test. * lib/dwarf.exp: Add new DW_OP_LLVM_extend operation support.
2021-11-05Add support for nested composite locationsZoran Zaric5-14/+270
After allowing a location description to be placed on a DWARF stack, in an effort to achieve a full composability of the DWARF expression, it is necessary to enable forming of a nested composite location descriptions. To be able do this, a new operation DW_OP_LLVM_piece_end needs to be introduced, along with some additional rules on the way how the composite location description is formed using the existing DW_OP_piece and DW_OP_bit_piece operations. These new rules are fully compatible with the composite forming rules from the DWARF 5 standard. More details on the new operation and added rules can be found here: https://llvm.org/docs/AMDGPUDwarfExtensionsForHeterogeneousDebugging.html The dwarf_composite also needed to be modified to make a distinction between completed composite locationd description and not completed one. This also mean that some DWARF expression operations can duplicate a composite location description that is not completed and end up with more then one different composite location description on the stack. To be able to do this, classes that derive from a DWARF entry class need to have a clone method. gdb/ChangeLog: * compile/compile-loc2c.c (compute_stack_depth_worker): Add new DW_OP_LLVM_piece_end operation support. * dwarf2/expr.c (dwarf_composite::m_completed): New data member. (dwarf_entry::dwarf_entry): New copy constructor. (dwarf_location::dwarf_location): New copy constructor. (dwarf_value::dwarf_value): New copy constructor. (dwarf_undefined::dwarf_undefined): New copy constructor. (dwarf_memory::dwarf_memory): New copy constructor. (dwarf_register::dwarf_register): New copy constructor. (dwarf_implicit::dwarf_implicit): New method. (dwarf_implicit_pointer::dwarf_implicit_pointer): New copy constructor. (dwarf_composite::dwarf_composite): New copy constructor. (dwarf_entry::clone): New method. (dwarf_location::clone): New method. (dwarf_value::clone): New method. (dwarf_undefined::clone): New method. (dwarf_memory::clone): New method. (dwarf_register::clone): New method. (dwarf_implicit::clone): New method. (dwarf_implicit_pointer::clone): New method. (dwarf_composite::clone): New method. (dwarf_composite::is_completed): New method. (dwarf_composite::set_completed): New method. (dwarf_expr_context::add_piece): Use new composite forming rules. (dwarf_expr_context::execute_stack_op): Add new DW_OP_LLVM_piece_end operation support. * dwarf2/loc.c (dwarf2_get_symbol_read_needs): Add new DW_OP_LLVM_piece_end operation support. include/ChangeLog: * dwarf2.def (DW_OP_DUP): Add new DW_OP_LLVM_piece_end enumeration. gdb/testsuite/ChangeLog: * gdb.dwarf2/dw2-llvm-piece-end.exp: New test.
2021-11-05Add support for DW_OP_LLVM_undefined operationZoran Zaric5-0/+154
For the DW_OP_piece and DW_OP_bit_piece operations, in the DWARF 5 standard, it is stated that if the location description (of that piece) is empty, then the piece is describing an undefined location description. The act of allowing any location description to be placed on a DWARF stack means that now a new operations can be defined which could pop more then one location description from a DWARF stack. This means that the old rule is not really applicable any more and a new operation that explicitly pushes an undefined location description on the DWARF stack is needed. This new rule however is fully backward compatibility as described in the document found on: https://llvm.org/docs/AMDGPUDwarfExtensionsForHeterogeneousDebugging.html Under the new definitions for the DW_OP_piece and DW_OP_bit_piece operations. gdb/ChangeLog: * compile/compile-loc2c.c (compute_stack_depth_worker): Add support for new DW_OP_LLVM_undefined operations. * dwarf2/expr.c (dwarf_expr_context::execute_stack_op): Add support for new DW_OP_LLVM_undefined operations. * dwarf2/loc.c (dwarf2_get_symbol_read_needs): Add new DW_OP_LLVM_undefined operation support. include/ChangeLog: * dwarf2.def (DW_OP): New DW_OP_LLVM_undefined operations enumeration. gdb/testsuite/ChangeLog: * gdb.dwarf2/dw2-llvm-undefined.exp: New test.
2021-11-05Add DWARF operations for byte and bit offsetZoran Zaric13-82/+541
Currently in DWARF, there are only two ways to specify an offset for a location description. For a memory location description, the location description can be first converted to a DWARF value, after which an arithmetic operation can be applied to it. This however, only works while there are no address spaces involved, that are not mapped to a general address space (CORE_ADDR). Another limitation is that there is no way to specify a bit offset to that location description. Second way of specifying an offset to a location description is more universal and involves wrapping that location description in a composite piece, where piece itself has a bit/byte offset defined. The problem with this approach is that both DW_OP_piece and DW_OP_bit_piece define an offset as a DWARF operation operand, which means that an offset needs to be a constant value encoded into the DWARF expression. By adding three new operations (DW_OP_LLVM_offset, DW_OP_LLVM_offset_constu and DW_OP_LLVM_bit_offset) these restrictions are now lifted. Detailed descriptions of these new operations can be found here: https://llvm.org/docs/AMDGPUDwarfExtensionsForHeterogeneousDebugging.html The same document also explores an idea of extending the DW_OP_push_object_address operation to allow pushing any location description on the DWARF stack. This together with the new bit/byte offset operations, generalizes DWARF to work with bit fields and could replace the odd passed-in buffer mechanics in a more elegant way. There seem to be a difference in views on what the big endian machine register byte ordering should be. On one hand, some would expect for a register to behave in the same way as memory, but on another, there seems to be an existing implementation for (IBM big endian based machines) which seems to be viewing registers differently, depending if the register location description is part of a composite piece or not. More on this topic can be found here: https://sourceware.org/legacy-ml/gdb-patches/2017-04/msg00177.html Unfortunately, the gdb current implementation favors the second option, which feels like a target specific implementation. Because of this, I've decided to not favor a specific implementation in the added test for new DWARF operations (dw2-llvm-offset.exp), so the test is restricted to only run on little endian platforms. gdb/ChangeLog: * ada-lang.c (coerce_unspec_val_to_type): Add source bit offset argument to the value_contents_copy call. * compile/compile-loc2c.c (compute_stack_depth_worker): Add new DWARF operations support. * dwarf2/expr.c (dwarf_register::to_gdb_value): Add bit offset support. (dwarf_register::to_gdb_value): Add bit offset support. (dwarf_register::to_gdb_value): Add source bit offset argument to the value_contents_copy call. (dwarf_expr_context::execute_stack_op): Add new DWARF operations support. * dwarf2/loc.c (dwarf2_get_symbol_read_needs): Add new DWARF operation support. (disassemble_dwarf_expression): Add support for new DW_OP_LLVM_offset_constu operation. * findvar.c (read_frame_register_value): Add source bit offset argument to the value_contents_copy call. * frame.c (get_frame_register_bytes): Takes into account a potential unwound register struct value offset. (get_frame_register_bytes): Takes into account a potential unwound register struct value offset. * valops.c (read_value_memory): Add bit offset support. (value_assign): Add bit offset support. (value_repeat): Add bit offset support. (value_array): Add source bit offset argument to the value_contents_copy call. (value_slice): Add source bit offset argument to the value_contents_copy call. * value.c (value_contents_copy_raw): Add source bit offset support. (value_contents_copy): Add source bit offset argument to value_contents_copy_raw call. (value_primitive_field): Add source bit offset argument to the value_contents_copy call. (value_from_component): Add source bit offset argument to the value_contents_copy call. (value_fetch_lazy_memory): Add bit offset argument to the read_value_memory call. (value_fetch_lazy_register): Add source bit offset argument to the value_contents_copy call. * value.h (value_contents_copy): Add source bit offset argument. include/ChangeLog: * dwarf2.def (DW_OP_DUP): New DWARF operations enumeration. gdb/testsuite/ChangeLog: * lib/dwarf.exp: Add support for new DW_OP_LLVM_offset_constu DWARF operation. * gdb.dwarf2/dw2-llvm-offset.exp: New test.
2021-11-05Add support for any location description in CFIZoran Zaric2-27/+58
One of the main benefits of allowing location description to be on the DWARF stack is that now CFI expression based register rules can be defined using a location description operations. This allows a register of one frame to be saved in any location, including any composite location. To fully support this feature, the execute_stack_op function in dwarf2/frame.c needs to return a single struct value object instead of just an address. Function put_frame_register_bytes also needs to change to support any location description. This support is a one of the key features to truly support optimized code. gdb/ChangeLog: * dwarf2/frame.c (execute_stack_op): Change to return a struct value object. (dwarf2_frame_cache): Change to call new execute_stack_op definition. (dwarf2_frame_prev_register): Change to call new execute_stack_op definition. * frame.c (put_frame_register_bytes): Add support for writing to composite location description.
2021-11-05Remove DWARF expression composition checkZoran Zaric1-8/+0
The dwarf_expr_require_composition function reports an error if the last operation is not a leaf node of the DWARF expression. This was previously used to prevent location description operations to be used freely in the DWARF expression. With the new approach, all operations are treated the same and everything is composable, so there is no need for the previous restrictions in the expression evaluator. gdb/ChangeLog: * dwarf2/expr.c (dwarf_expr_context::execute_stack_op): Remove the use of dwarf_expr_require_composition.
2021-11-05Add frame info check to DW_OP_reg operationsZoran Zaric1-0/+1
After enabling location description to be on a DWARF stack, it is now needed to check the frame context information validity when creating a register location description. gdb/ChangeLog: * dwarf2/expr.c (dwarf_expr_context::execute_stack_op): Add check_frame_info call for DW_OP_reg operations.
2021-11-05Move read_addr_from_reg function to frame.cZoran Zaric3-15/+12
read_addr_from_reg function is now only called from frame.c file, this means that the function can safely be moved there. gdb/ChangeLog: * dwarf2/expr.c (read_addr_from_reg): Move function to frame.c. * dwarf2/expr.h (read_addr_from_reg): Remove function. * dwarf2/frame.c (read_addr_from_reg): Add function from expr.c.
2021-11-05Remove dwarf_expr_context from expr.h interfaceZoran Zaric4-202/+214
After the switch to the new evaluator implementation, it is now possible to completely remove the dwarf_expr_context class from the expr.h interface and encapsulate it inside the expr.c file. The new interface consists of a new function called dwarf2_evaluate that takes a DWARF expression stream, initial DWARF stack elements (in a form of a vector of a struct value objects), evaluation context and expected result type information. Function returns an evaluation result in a form of a struct value object. Currently, there is ever only one initial stack element provided to the evaluator and that element is always a memory address, so having a vector of struct value object might seems like an overkill. In reality this new flexibility allows implementation of a new DWARF attribute extensions that could provide any number of initial stack elements to describe any location description or value. gdb/ChangeLog: * dwarf2/expr.c (dwarf2_evaluate): New function. (struct dwarf_expr_context): Move from expr.h. (class dwarf_entry): Move from expr.h (dwarf_expr_context::push_address): Remove function. * dwarf2/expr.h (struct dwarf_expr_context): Move to expr.c. (class dwarf_entry): Move to expr.c. (address_type): Expose function. * dwarf2/frame.c (execute_stack_op): Now calls dwarf2_evaluate. * dwarf2/loc.c (dwarf2_evaluate_loc_desc_full): Now calls dwarf2_evaluate. (dwarf2_locexpr_baton_eval): Now calls dwarf2_evaluate.
2021-11-05Comments cleanup between expr.h and expr.cZoran Zaric2-28/+69
This is just a cosmetic cleanup of the expr.h and expr.c documentation. gdb/ChangeLog: * dwarf2/expr.c: Comments cleanup. * dwarf2/expr.h: Comments cleanup.
2021-11-05Remove old computed struct value callbacksZoran Zaric2-614/+0
After changing the DWARF stack to use the new DWARF entry based classes, the previous computed struct value callback infrastructure is not used anymore and can be removed. gdb/ChangeLog: * dwarf2/expr.c (struct piece_closure): Remove structure. (rw_pieced_value): Remove unused function. (read_pieced_value): Remove unused function. (write_pieced_value): Remove unused function. (check_pieced_synthetic_pointer): Remove unused function. (indirect_pieced_value): Remove unused function. (coerce_pieced_ref): Remove unused function. (copy_pieced_value_closure): Remove unused function. (free_pieced_value_closure): Remove unused function. * dwarf2/expr.h (class dwarf_entry): New declaration. (struct dwarf_expr_piece): Remove structure. (enum dwarf_value_location): Remove enumeration.
2021-11-05Change DWARF stack to use new dwarf_entry classesZoran Zaric5-761/+711
To replace existing DWARF stack element (dwarf_stack_value) with dwarf_entry class based objects, a support for conversion between struct value and the new classes is needed. The reason for this is that dwarf_entry based classes are not designed to be visible outside the expr.c file. This makes the DWARF expression evaluator more self contained. This can be beneficial if there is ever a need to have a DWARF support in gdbserver. In the previous patch the conversion between the DWARF entry classes to the struct value has been already added in a form of a to_gdb_value method. The interface that is still missing is to convert from struct value to the DWARF entry classes. New static function gdb_value_to_dwarf_entry has been added for this purpose. We also need a way to perform DWARF arithmetic and logical operations on DWARF values and for this a new set of static functions (dwarf_value_X) has been provided. Currently the existing struct value operations are used under the hood of these functions to avoid the code duplication. Vector types are planned to be promoted to base types in the future anyway which means that the operations subset needed is just going to grow. Also, dwarf_entry class declaration had to be temporarily moved to the expr.h file so that unique_ptr wrapper type could be used in some dwarf_expr_context method declaration and will be moved back to the expr.c file in one of the next patches. Now, everything is ready so that the DWARF stack element can easily be swapped out. It is worth mentioning that a few tests under gdb/testsuite/gdb.dwarf2/ folder, also had to be changed to reflect the design change which effected an edge case error message text. Tests that had to be changed slightly are: dw2-param-error.exp, dw2-stack-boundary.exp and dw2_op_call.exp. The reason for this is that they all contained a DWARF expression that once evaluated resulted in a stack underflow error reported by a fetch method, but with the switch to the new stack element type and a bit different stack algorithm, the message can no longer be reported by that method, but by a stack pop method instead. gdb/ChangeLog: * dwarf2/expr.c (gdb_value_to_dwarf_entry): New function. (to_location): New function. (to_value): New function. (dwarf_value_cast_op): New function. (dwarf_value_complement_op): New function. (dwarf_value_negation_op): New function. (dwarf_value_binary_op): New function. (dwarf_value_less_op): New function. (dwarf_value_equal_op): New function. (allocate_piece_closure): Remove unused function. (dwarf_expr_context::push): Change to use dwarf_entry based classes. (dwarf_expr_context::push_address): Change to use dwarf_entry based classes. (dwarf_expr_context::fetch): Change to use dwarf_entry based classes. (dwarf_expr_context::read_mem): Remove method. (dwarf_expr_context::fetch_result): Change to use dwarf_entry based classes. (dwarf_expr_context::fetch_address): Change to use dwarf_entry based classes. (dwarf_expr_context::fetch_in_stack_memory): Remove method. (dwarf_expr_context::add_piece): Change to use dwarf_entry based classes. (dwarf_expr_context::execute_stack_op): Change to use dwarf_entry based classes. (dwarf_location::clone): New method. (dwarf_value::clone): New method. * dwarf2/expr.h (class dwarf_entry): New declaration. (struct dwarf_stack_value): Remove structure. (struct dwarf_expr_context): Change to use dwarf_entry based. (dwarf_entry::clone): New method. gdb/testsuite/ChangeLog: * gdb.dwarf2/dw2-param-error.exp: Error message text change. * gdb.dwarf2/dw2-stack-boundry.exp: Error message text change. * gdb.dwarf2/dw2-op-call.exp Error message text change.
2021-11-05Add to_gdb_value method to DWARF entry classZoran Zaric1-0/+283
The result of the DWARF expression evaluation is expected to be in a format of a struct value object. This means that a new to_gdb_value method is needed for both dwarf_location and dwarf_value classes. In the case of the dwarf_value class, the conversion between that class and struct value can happen often, this is why it is usefull to cache once created struct value object in a dwarf_value m_gdb_value member to reduce the number of conversions needed. However, this also means that the to_gdb_value method cant be declared as a constant method. In the case of classes that derive from dwarf_location class, there is now a need for a cloning method because the encapsulating computed_closure class has a life span separated from the expression evaluator. gdb/ChangeLog: * dwarf2/expr.c (dwarf_entry::to_gdb_value): New method. (dwarf_location::to_gdb_value): New method. (dwarf_location::clone_location): New method. (dwarf_value::m_gdb_value): New member. (dwarf_value::to_gdb_value): New method. (dwarf_undefined::to_gdb_value): New method. (dwarf_undefined::clone_location): New method. (dwarf_memory::to_gdb_value): New method. (dwarf_memory::clone_location): New method. (dwarf_register::to_gdb_value): New method. (dwarf_register::clone_location): New method. (dwarf_implicit::to_gdb_value): New method. (dwarf_implicit::clone_location): New method. (dwarf_implicit_pointer::to_gdb_value): New method. (dwarf_implicit_pointer::clone_location): New method. (dwarf_composite::to_gdb_value): New method. (dwarf_composite::clone_location): New method.
2021-11-05Add new computed struct value callback interfaceZoran Zaric1-0/+324
At this point all support is there to add a new callback interface for the computed struct value infrastructure. Original callback interface (piece closure) is going to be removed as soon as the switch to the new DWARF entry classes is done in the next few patches. gdb/ChangeLog: * dwarf2/expr.c (class computed_closure): New class. (closure_value_funcs): New closure callback structure. (copy_value_closure): New function. (free_value_closure): New function. (rw_closure_value): New function. (check_synthetic_pointer): New function. (write_closure_value): New function. (read_closure_value): New function. (is_optimized_out_closure_value): New function. (indirect_closure_value): New function. (coerce_closure_ref): New function.
2021-11-05Add is_optimized_out to dwarf_location classZoran Zaric1-0/+97
Similarly to the is_implicit_ptr_at method, the existing function callback interface of the computed struct value, requiers a way to check if the underlying location description describes any part as optimized out. gdb/ChangeLog: * dwarf2/expr.c (dwarf_location::is_optimized_out): New method. (dwarf_implicit::is_optimized_out): New method. (dwarf_register::is_optimized_out): New method. (dwarf_composite::is_optimized_out): New method.
2021-11-05Add indirect_implicit_ptr to dwarf_location classZoran Zaric1-0/+73
Similarly to the is_implicit_ptr_at method, the existing function callback interface of the computed struct value, requiers a way to apply indirection to an implicit pointer on a given offset of a given length of an underlying location description. This is different than reading from a struct value object (previously described write_to_gdb_value method) in a way that the result of this operation is expected to be a struct value of a pointed source level variable instead of reading the value of that variable. In the same way this is also different operation than the deref method because the deref returns a read value of a given type from that location description. gdb/ChangeLog: * dwarf2/expr.c (dwarf_location::indirect_implicit_ptr): New method. (dwarf_implicit_pointer::indirect_implicit_ptr): New method. (dwarf_composite::indirect_implicit_ptr): New method.
2021-11-05Add is_implicit_ptr_at method to dwarf_locationZoran Zaric1-0/+52
Another expectation of the existing function callback interface of the computed struct value is to check if a specific part (on a given offset of a given length) of an underlying location description is an implicit pointer location description. To satisfy this expectation a new is_implicit_ptr_at has been added. gdb/ChangeLog: * dwarf2/expr.c (dwarf_location::is_implicit_ptr_at): New method. (dwarf_implicit_pointer::is_implicit_ptr_at): New method. (dwarf_composite::is_implicit_ptr_at): New method.
2021-11-05Add write_to_gdb_value method to dwarf_locationZoran Zaric1-0/+89
Similar story behind the previous read_from_gdb_value method applies to the new write_to_gdb_value. In the same way, reading the data from a location described and writing that data to a struct value object, can be different from just generic read the data from a buffer (location description read method). To make this distinction clear, a new write_to_gdb_value method is added to classes that derive from location description class. gdb/ChangeLog: * dwarf2/expr.c (dwarf_location::write_to_gdb_value): New method. (dwarf_composite::write_to_gdb_value): New method.
2021-11-05Add read_from_gdb_value method to dwarf_locationZoran Zaric1-0/+99
The few patches are addressing the expectations of the existing function calback interface of the computed struct value objects. As mentioned in the previous patches the location description and the interaction with that location are opaque to the struct value object, but currently that interaction is influenced by the data contained inside of that object and outside of the location description class. Also, the struct value evaluation involves more then just writing or reading the object contents buffer, in certain cases it is also expected to throw an exception or mark different parts of the object with additional information (optimized out bitmap for example). As a result, reading the data from a struct value object and writing that data into the location described, can be different then just generic writing the data from a buffer (dwarf_location write method). To make this distinction clear a new read_from_gdb_value method is added to classes that derive from location description class. gdb/ChangeLog: * dwarf2/expr.c (dwarf_location::read_from_gdb_value): New method. (dwarf_composite::read_from_gdb_value): New method.
2021-11-05Add deref method to location description classesZoran Zaric1-0/+123
Concept of reading from a location seems to be too low level for the DWARF standard. What the standard actually describes is a concept of dereferencing, where the type of the operation result can be specified in advance. This can be seen in the definition of the DW_OP_derefX family of expression operations, but it is also happening implicitly in the case of DW_OP_fbreg, DW_OP_regval_type and DW_OP_bregX family of operations. Currently, the DW_OP_derefX operations will take the value from the DWARF expression stack and implicitly convert it to a memory location description (in reality treat it as a memory address for a given target) and apply the dereference operation to it. When we allow any location description on a DWARF expression stack, these operations need to work in the same way. The conclusion here is that we need a universal method that models the dereference operation for any class derived from a location description class. It is worth mentioning that because of how the passed in buffers are currently being implemented, we needed a specialisation for the deref method of the dwarf_memory class to support them. gdb/ChangeLog: * dwarf2/expr.c (dwarf_location::deref): New method. (dwarf_memory::deref): New method.
2021-11-05Add write method to location description classesZoran Zaric1-0/+211
After adding the interface for reading from the location, it also makes sense to add the interface for writing. To be clear, DWARF standard doesn't have a concept of writting to a location, but because of the way how callback functions are used to interact with the opaque implementation of the computed struct value objects, the choice was to either use the existing DWARF entry classes or to invent another way of representing the complexity behind those computed objects. Adding a write method seems to be a simpler option of the two. gdb/ChangeLog: * dwarf2/expr.c (dwarf_location::write): New method. (dwarf_undefined::write): New method. (dwarf_memory::write): New method. (dwarf_register::write): New method. (dwarf_implicit::write): New method. (dwarf_implicit_pointer::write): New method. (dwarf_composite::write): New method.
2021-11-05Add read method to location description classesZoran Zaric1-21/+284
After adding the interface for register and memory location access, a new method for reading from any location derived from a dwarf_location class, can now be defined. In the case of implicit pointer location description the existing indirect_synthetic_pointer interface requiers a type of the pointer to be specified, so for a generic read interface the only type that makes sense is the DWARF generic type. This means that the existing address_type method of a dwarf_expr_context class needs to be exposed outside of that class. gdb/ChangeLog: * dwarf2/expr.c (dwarf_location::read): New method. (dwarf_undefined::read): New method. (dwarf_memory::read): New method. (dwarf_register::read): New method. (dwarf_implicit::read): New method. (dwarf_implicit_pointer::read): New method. (dwarf_composite::read): New method. (dwarf_expr_context::address_type): Change to use the new address_type function. (address_type): New function.
2021-11-05Add to_value method to dwarf_location classZoran Zaric1-0/+29
Following the idea from the last patch this patch is adding a conversion method from any dwarf_location derived object into a dwarf_value object. Currently, we only know how to convert from a memory location description into a value, but it is resonable to expect a set of target hooks that would let the target decide on how to do other conversions in the future. gdb/ChangeLog: * dwarf2/expr.c (dwarf_location::to_value): New method. (dwarf_memory::to_value): New method. (ill_formed_expression): New function.
2021-11-05Add to_location method to dwarf_value classZoran Zaric2-0/+43
DWARF standard already contains an implicit conversion between location description and a DWARF value. In the DWARF 5 version, one place where this can happen is at the very end of the evaluation where a client decides if the result is expected to be in a form of a value or a location description (as_lval argument of the new evaluation method). By allowing any location description to be on the DWARF stack, these implicit conversions are expected on per operation basis which means that the new dwarf_value class need to have a support for it. This patch adds a conversion method from a dwarf_value object into a location description object. To support the conversion method we also need an implementation of the C++14 standard library function make_unique which was copied from the standard library implementation. gdb/ChangeLog: * dwarf2/expr.c (class dwarf_value::to_location): New method. gdbsupport/ChangeLog: * common-utils.h (make_unique): New function.
2021-11-05Add new classes that model DWARF stack elementZoran Zaric3-1/+244
The rest of the patch series addresses the issues described in a "Motivation" section of the AMD's DWARF standard extensions that can be found at: https://llvm.org/docs/AMDGPUDwarfExtensionsForHeterogeneousDebugging.html The document describes a couple of main issues found when using the current DWARF 5 version to describe optimized code for SIMD and SIMT architectures. Without going much into details described in the document, the main point is that DWARF version 5 does not allow a proper support for address spaces and it does not allow a location description to be used anywhere in the DWARF expression, instead a location description can using a result left on the DWARF stack (after the evaluation of that expression) to describe the location. Both issues can be solved in a clean way by introducing a new set of classes that describe all entry types which can be placed on a DWARF stack, while keeping most of backward compatibility with the previous standard version. These entry types can now be either a typed value or any location description. Known edge case where placing a location description on the DWARF stack is not fully backward compatible with DWARF version 5 is in the case of DW_OP_call operations, where the current standard only defines that an expression stack is shared between the caller and the callee, but there it is unknown what happens with the resuling location description after the evaluation of the callee's location description expression. Considering that this edge case is not defined in the standard, it would be very unusual and dangerous for any compiler to use it in their own way and in the existing testsuite, there is no indication of that. Currently, the result of an expression evaluation is kept in a separate data structure, while with the new approach, it will be always found as a top element of the DWARF stack. Question here is, why do we need a new set of classes and why not just use the struct value instead? As it stands, there are couple of issues with using the struct value to describe a DWARF stack element: - It is not designed to represent a DWARF location description specifically, instead it behaves more like unified debug information format that represents an actual target resource. One example of this is accessing data of a struct value register location description, where if the amount of data accessed is larger then the register, results in accessing more then one register. In DWARF this is not a valid behavior and locations that span more then one register should be described as a composite location description. - There is a tight coupling between struct value and it's type information, regardless if the data represented is describing a value (not_lval) or a location description. While the type information dictates how the data is accessed for a struct value case, in DWARF, location description doesn't have a type so data access is not bound by it. - DWARF values only support much simpler base types, while struct value can be linked to any type. Admittedly, new classes are still using the same struct value infrastructure for a value based operations at the moment, but that is planned to change in the near future. - struct value register location description requires a frame id information which makes them unsuitable for CFA expression evaluation. So, there seems to be a lack of separation of concerns in the design of a struct value infrastructure, while the new classes are handling one specific purpose and are completely encapsulated in the expr.c. Additional benefit of this design is that it makes a step in a right direction for being able to evaluate DWARF expressions on a gdbserver side in the near future, which sounds like a desirable thing. It is also worth mentioning that this new location description representation is based on a bit granularity (the bit_suboffset class member) even though the DWARF standard has a very limited support for it (mostly used for DW_OP_bit_piece operation). By allowing any location description to define a bit sub-offset of the location, we are able to give more options for supporting of new concepts (like the existing packed arrays in Ada language). In this patch, a new set of classes that describe a DWARF stack element are added. The new classes are: - Value - describes a numerical value with a DWARF base type. - Location description - describes a DWARF location description. - Undefined location - describes a location that is not defined. - Memory location - describes a location in memory. - Register location - describes a register location in a frame context. - Implicit location - describes a location that implicitly holds a value that it describes. - Implicit pointer - describes a concept of an implicit pointer to a source variable. - Composite location - describes a location that is composed from pieces of other location descriptions. For now, these classes are just defined, and they are planned to be used by the following patches. gdb/ChangeLog: * dwarf2/expr.c (class dwarf_entry): New class. (class dwarf_value): New class. (class dwarf_location): New class. (class dwarf_undefined): New class. (class dwarf_memory): New class. (class dwarf_register): New class. (class dwarf_implicit): New class. (class dwarf_implicit_pointer): New class. (class dwarf_composite): New class. * value.c (pack_unsigned_long): Expose function. * value.h (pack_unsigned_long): Expose function.
2021-11-05Add new memory access interface to expr.cZoran Zaric1-44/+146
DWARF expression evaluator is currently using a few different interfaces for memory access: write_memory_with_notification, read_value_memory, read_memory. They all seem incosistent, while some of them even need a struct value typed argument to be present. This patch is simplifying that interface by replacing it with two new low level functions: read_from_memory and write_to_memory. The advantage of this new interface is that it behaves in the same way as the register access interface from the previous patch. Both of these have the same error returning policy, which will be usefull for the following patches. * dwarf2/expr.c (xfer_memory): New function. (read_from_memory): New function. (write_to_memory): New function. (rw_pieced_value): Now calls the read_from_memory and write_to_memory functions.
2021-11-05Add new register access interface to expr.cZoran Zaric1-22/+105
DWARF expression evaluator is currently using get_frame_register_bytes and put_frame_register_bytes interface for register access. The problem with evaluator using this interface is that it allows a bleed out register access. This means that if the caller specifies a larger amount of data then the size of a specified register, the operation will continue accessing the neighboring registers until a full amount of data has been reached. DWARF specification does not define this behavior, so a new simplified register access interface is needed instead. * dwarf2/expr.c (read_from_register): New function. (write_to_register): New function. (rw_pieced_value): Now calls the read_from_register and write_to_register functions.
2021-11-05PR28530, Hang in objdump on machine with 196GB RAMAlan Modra1-0/+15
Investigating the PR28530 testcase, which has a fuzzed compression header with an enormous size, I noticed that decompress_contents is broken when the size doesn't fit in strm.avail_out. It wouldn't be too hard to support larger sizes (patches welcome!) but for now just stop decompress_contents from returning rubbish. PR 28530 * compress.c (decompress_contents): Fail when uncompressed_size is too big. (bfd_init_section_decompress_status): Likewise.
2021-11-05asan: alpha-vms: objdump buffer overflowsAlan Modra1-175/+344
* vms-alpha.c (evax_bfd_print_desc): Sanity check buffer access. (evax_bfd_print_valspec, evax_bfd_print_typspec): Likewise. (evax_bfd_print_dst): Likewise.
2021-11-05Automatic date update in version.inGDB Administrator1-1/+1
2021-11-04gdb: introduce "set index-cache enabled", deprecate "set index-cache on/off"Simon Marchi5-27/+71
The "set index-cache" command is used at the same time as a prefix command (prefix for "set index-cache directory", for example), and a boolean setting for turning the index-cache on and off. Even though I did introduce that, I now don't think it's a good idea to do something non-standard like this. First, there's no dedicated CLI command to show whether the index-cache is enabled, so it has to be custom output in the "show index-cache handler". Also, it means there's no good way a MI frontend can find out if the index-cache is enabled. "-gdb-show index-cache" doesn't show it in the MI output record: (gdb) interpreter-exec mi "-gdb-show index-cache" ~"\n" ~"The index cache is currently disabled.\n" ^done,showlist={option={name="directory",value="/home/simark/.cache/gdb"}} Fix this by introducing "set/show index-cache enabled on/off", regular boolean setting commands. Keep commands "set index-cache on" and "set index-cache off" as deprecated aliases of "set index-cache enabled", with respectively the default arguments "on" and "off". Update tests using "set index-cache on/off" to use the new command. Update the regexps in gdb.base/maint.exp to figure out whether the index-cache is enabled or not. Update the doc to mention the new commands. Change-Id: I7d5aaaf7fd22bf47bd03e0023ef4fbb4023b37b3
2021-11-04gdb: pass/return setting setter/getter scalar values by valueSimon Marchi3-61/+81
The getter and setter in struct setting always receive and return values by const reference. This is not necessary for scalar values (like bool and int), but more importantly it makes it a bit annoying to write a getter, you have to use a scratch static variable or something similar that you can refer to: const bool & my_getter () { static bool value; value = function_returning_bool (); return value; } Change the getter and setter function signatures to receive and return value by value instead of by reference, when the underlying data type is scalar. This means that string-based settings will still use references, but all others will be by value. The getter above would then be re-written as: bool my_getter () { return function_returning_bool (); } This is useful for a patch later in this series that defines a boolean setting with a getter and a setter. Change-Id: Ieca3a2419fcdb75a6f75948b2c920b548a0af0fd
2021-11-04gdb: remove command_class enum class_deprecatedSimon Marchi2-6/+1
The class_deprecated enumerator isn't assigned anywhere, so remove it. Commands that are deprecated have cmd_list_element::cmd_deprecated set instead. Change-Id: Ib35e540915c52aa65f13bfe9b8e4e22e6007903c
2021-11-04gdb: remove unnecessary cmd_list_element::aliases nullptr checksSimon Marchi1-17/+11
Remove two unnecessary nullptr checks. If aliases is nullptr, then the for loops will simply be skipped. Change-Id: I9132063bb17798391f8d019af305383fa8e0229f
2021-11-04gdbserver: re-generate configureSimon Marchi2-0/+49
I get some diffs when running autoconf in gdbserver, probably leftovers from commit 5dfe4bfcb969 ("Fix format_pieces selftest on Windows"). Re-generate configure in that directory. Change-Id: Icdc9906af95fbaf1047a579914b2983f8ec5db08
2021-11-04Revert "bfd: Always check sections with the corrupt size"H.J. Lu1-27/+23
This reverts commit e0f7ea91436dd308a094c4c101fd4169e8245a91.
2021-11-04bfd: Always check sections with the corrupt sizeH.J. Lu1-23/+27
Always check sections with the corrupt size for non-MMO files. Skip MMO files for compress_status == COMPRESS_SECTION_NONE since MMO has special handling for COMPRESS_SECTION_NONE. PR binutils/28530 * compress.c (bfd_get_full_section_contents): Always check sections with the corrupt size.
2021-11-04RISC-V: Clarify the behavior of .option rvc or norvc.Nelson Chu3-21/+86
Add/Remove the rvc extension to/from the riscv_subsets once the .option rvc/norvc is set. So that we don't need to always check the riscv_opts.rvc in the riscv_subset_supports, just call the riscv_lookup_subset to search the subset list is enough. Besides, we will need to dump the instructions according to the elf architecture attributes. That means the dis-assembler needs to parse the architecture string from the elf attribute before dumping any instructions, and also needs to recognized the INSN_CLASS* classes from riscv_opcodes. Therefore, I suppose some functions will need to be moved from gas/config/tc-riscv.c to bfd/elfxx-riscv.c, including riscv_multi_subset_supports and riscv_subset_supports. This is one of the reasons why we need this patch. This patch passes the gcc/binutils regressions of rv32emc-elf, rv32i-elf, rv64gc-elf and rv64gc-linux toolchains. bfd/ * elfxx-riscv.c (riscv_remove_subset): Remove the extension from the subset list. (riscv_update_subset): Add/Remove an extension to/from the subset list. This is used for the .option rvc or norvc. * elfxx-riscv.h: Added the extern bool riscv_update_subset. gas/ * config/tc-riscv.c (riscv_set_options): Removed the unused rve flag. (riscv_opts): Likewise. (riscv_set_rve): Removed. (riscv_subset_supports): Removed the riscv_opts.rvc check. (riscv_set_arch): Don't need to call riscv_set_rve. (reg_lookup_internal): Call riscv_subset_supports to check whether the rve is supported. (s_riscv_option): Add/Remove the rvc extension to/from the subset list once the .option rvc/norvc is set.
2021-11-03sim: mips: fix missing prototype in multi-run generationMike Frysinger2-0/+4
The multi-run logic for mips involves a bit of codegen and rewriting of files to include per-architecture prefixes. That can result in files with missing prototypes which cause compiler errors. In the case of mips-sde-elf targets, we have: $srcdir/m16run.c -> $builddir/m16mips64r2_run.c sim_engine_run -> m16mips64r2_engine_run $srcdir/micromipsrun.c -> micromipsmicromips_run.c sim_engine_run -> micromips64micromips_engine_run micromipsmicromips_run.c:80:1: error: no previous prototype for 'micromips64micromips_engine_run' [-Werror=missing-prototypes] 80 | micromips64micromips_engine_run (SIM_DESC sd, int next_cpu_nr, int nr_cpus, We generate headers for those prototypes in the configure script, but only include them in the generated multi-run.c file. Update the rewrite logic to turn the sim-engine.h include into the relevant generated engine include so these files also have their prototypes. $srcdir/m16run.c -> $builddir/m16mips64r2_run.c sim-engine.h -> m16mips64r2_engine.h $srcdir/micromipsrun.c -> micromipsmicromips_run.c sim-engine.h -> micromips64micromips_engine.h
2021-11-04PR28540, segmentation fault on NULL byte_getAlan Modra1-1/+1
PR 28540 * objdump.c (dump_bfd): Don't attempt load_separate_debug_files when byte_get is NULL.
2021-11-04Automatic date update in version.inGDB Administrator1-1/+1
2021-11-03sim: ppc: inline common sim-fpu.c logicMike Frysinger3-33/+2
We will never bother building w/out a ../common/ sim directory, so drop ancient logic supporting that method.
2021-11-03sim: ppc: switch to common builds for callback objectsMike Frysinger3-37/+6
We don't need to build this anymore ourselves since the common build includes it and produces the same object code. We also need to pull in the split constant modules after the refactoring and pulling them out of nltvals.def & targ-map.o. This doesn't matter for the sim directly, but does for gdb and other users of libsim. We also delete some conditional source tree logic since we already require this be the "new" combined tree with a ../common/ dir. This has been the case for decades at this point.
2021-11-03gdb: fix gnu-nat buildSimon Marchi1-3/+3
When building gnu-nat.c, we get: CXX gnu-nat.o gnu-nat.c: In member function 'virtual void gnu_nat_target::create_inferior(const char*, const string&, char**, int)': gnu-nat.c:2117:13: error: 'struct inf' has no member named 'target_is_pushed' 2117 | if (!inf->target_is_pushed (this)) | ^~~~~~~~~~~~~~~~ gnu-nat.c:2118:10: error: 'struct inf' has no member named 'push_target' 2118 | inf->push_target (this); | ^~~~~~~~~~~ This is because of a confusion between the generic `struct inferior` variable and the gnu-nat-specific `struct inf` variable. Fix by referring to `inferior`, not `inf`. Adjust the comment on top of `struct inf` to clarify the purpose of that type. Co-Authored-By: Andrea Monaco <andrea.monaco@autistici.org> Change-Id: I2fe2f7f6ef61a38d79860fd262b08835c963fc77
2021-11-03gdb/testsuite: set ASAN_OPTIONS=detect_leaks=0 while running testsSimon Marchi1-0/+7
We see some additional failures when running the testsuite against a GDB compiled with ASan, compared to a GDB compiled without ASan. Some of them are caused by the memory leak report shown by the GDB process when it exits, and the fact that it makes it exit with a non-zero exit code. I generally try to remember to set ASAN_OPTIONS=detect_leaks=0 in my environment when running the tests, but I don't always do it. I think it would be nice if the testsuite did it. I don't see any use to have leak detection when running the tests. That is, unless we ever have a test that ensures GDB doesn't leak memory, which isn't going to happen any time soon. Here are some tests I found that were affected by this: gdb.base/batch-exit-status.exp gdb.base/many-headers.exp gdb.base/quit.exp gdb.base/with-mf.exp gdb.dwarf2/gdb-add-index.exp gdb.dwarf2/gdb-add-index-symlink.exp gdb.dwarf2/imported-unit-runto-main.exp Change-Id: I784c7df8a13979eb96587f735c1d33ba2cc6e0ca
2021-11-03Use section name in warnings in display_debug_locTom Tromey2-8/+16
While looking at an apparently malformed executable with "readelf --debug-dump=loc", I got this warning: readelf: ./main: Warning: There is a hole [0x89 - 0x95] in .debug_loc section. However, the executable only has a .debug_loclists section. This patch fixes the warning messages in display_debug_loc to use the name of the section that is being processed. binutils/ChangeLog 2021-11-03 Tom Tromey <tromey@adacore.com> * dwarf.c (display_debug_loc): Use section name in warnings.
2021-11-03[AArch64] Make gdbserver register set selection dynamicLuis Machado2-85/+110
The current register set selection mechanism for AArch64 is static, based on a pre-populated array of register sets. This means that we might potentially probe register sets that are not available. This is OK if the kernel errors out during ptrace, but probing the tag_ctl register, for example, does not result in a ptrace error if the kernel supports the tagged address ABI but not MTE (PR 28355). Making the register set selection dynamic, based on feature checks, solves this and simplifies the code a bit. It allows us to list all of the register sets only once, and pick and choose based on HWCAP/HWCAP2 or other properties. I plan to backport this fix to GDB 11 as well. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=28355