1 /* Copyright (c) 2004-2019. The SimGrid Team. All rights reserved. */
3 /* This program is free software; you can redistribute it and/or modify it
4 * under the terms of the license (GNU LGPL) which comes with this package. */
10 #include "xbt/asserts.h"
11 #include "xbt/sysdep.h"
13 #include <libunwind.h>
15 #include "src/mc/mc_dwarf.hpp"
16 #include "src/mc/ObjectInformation.hpp"
17 #include "src/mc/LocationList.hpp"
22 /** Resolve a location expression */
24 simgrid::dwarf::DwarfExpression const& expression,
25 simgrid::mc::ObjectInformation* object_info,
27 void *frame_pointer_address,
28 simgrid::mc::AddressSpace* address_space, int process_index)
30 simgrid::dwarf::ExpressionContext context;
31 context.frame_base = frame_pointer_address;
33 context.address_space = address_space;
34 context.object_info = object_info;
35 context.process_index = process_index;
37 if (not expression.empty() && expression[0].atom >= DW_OP_reg0 && expression[0].atom <= DW_OP_reg31) {
38 int dwarf_register = expression[0].atom - DW_OP_reg0;
39 xbt_assert(c, "Missing frame context for register operation DW_OP_reg%i", dwarf_register);
40 return Location(dwarf_register_to_libunwind(dwarf_register));
43 simgrid::dwarf::ExpressionStack stack;
44 simgrid::dwarf::execute(expression, context, stack);
45 return Location((void*) stack.top());
48 // TODO, move this in a method of LocationList
49 static simgrid::dwarf::DwarfExpression const* find_expression(
50 simgrid::dwarf::LocationList const& locations, unw_word_t ip)
52 for (simgrid::dwarf::LocationListEntry const& entry : locations)
53 if (entry.valid_for_ip(ip))
54 return &entry.expression();
59 simgrid::dwarf::LocationList const& locations,
60 simgrid::mc::ObjectInformation* object_info,
62 void *frame_pointer_address,
63 simgrid::mc::AddressSpace* address_space,
67 if (c && unw_get_reg(c, UNW_REG_IP, &ip))
68 xbt_die("Could not resolve IP");
69 simgrid::dwarf::DwarfExpression const* expression =
70 find_expression(locations, ip);
72 xbt_die("Could not resolve location");
73 return simgrid::dwarf::resolve(
74 *expression, object_info, c,
75 frame_pointer_address, address_space, process_index);
78 LocationList location_list(
79 simgrid::mc::ObjectInformation& info,
80 Dwarf_Attribute& attr)
82 LocationList locations;
83 std::ptrdiff_t offset = 0;
91 offset = dwarf_getlocations(&attr, offset, &base, &start, &end, &ops, &len);
95 else if (offset == -1)
96 xbt_die("Error while loading location list");
98 std::uint64_t base_address = (std::uint64_t) info.base_address();
100 LocationListEntry::range_type range;
102 // If start == 0, this is not a location list:
103 range = { 0, UINT64_MAX };
105 range = { base_address + start, base_address + end };
107 locations.push_back({ DwarfExpression(ops, ops+len), range });