Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
eca864120c7dd02057d9b4a428911759b6853c9a
[simgrid.git] / src / mc / LocationList.cpp
1 /* Copyright (c) 2004-2015. The SimGrid Team.
2  * All rights reserved.                                                     */
3
4 /* This program is free software; you can redistribute it and/or modify it
5  * under the terms of the license (GNU LGPL) which comes with this package. */
6
7 #include <cstddef>
8 #include <cstdint>
9 #include <utility>
10
11 #include <xbt/asserts.h>
12 #include <xbt/sysdep.h>
13
14 #include <libunwind.h>
15
16 #include "src/mc/mc_dwarf.hpp"
17 #include "src/mc/ObjectInformation.hpp"
18 #include "src/mc/LocationList.hpp"
19
20 namespace simgrid {
21 namespace dwarf {
22
23 /** Resolve a location expression */
24 Location resolve(
25                       simgrid::dwarf::DwarfExpression const& expression,
26                       simgrid::mc::ObjectInformation* object_info,
27                       unw_cursor_t * c,
28                       void *frame_pointer_address,
29                       simgrid::mc::AddressSpace* address_space, int process_index)
30 {
31   simgrid::dwarf::ExpressionContext context;
32   context.frame_base = frame_pointer_address;
33   context.cursor = c;
34   context.address_space = address_space;
35   context.object_info = object_info;
36   context.process_index = process_index;
37
38   if (!expression.empty()
39       && expression[0].atom >= DW_OP_reg0
40       && expression[0].atom <= DW_OP_reg31) {
41     int dwarf_register = expression[0].atom - DW_OP_reg0;
42     xbt_assert(c, "Missing frame context for register operation DW_OP_reg%i", dwarf_register);
43     return Location(dwarf_register_to_libunwind(dwarf_register));
44   }
45
46   simgrid::dwarf::ExpressionStack stack;
47   simgrid::dwarf::execute(expression, context, stack);
48   return Location((void*) stack.top());
49 }
50
51 // TODO, move this in a method of LocationList
52 static simgrid::dwarf::DwarfExpression const* find_expression(
53     simgrid::dwarf::LocationList const& locations, unw_word_t ip)
54 {
55   for (simgrid::dwarf::LocationListEntry const& entry : locations)
56     if (entry.valid_for_ip(ip))
57       return &entry.expression();
58   return nullptr;
59 }
60
61 Location resolve(
62   simgrid::dwarf::LocationList const& locations,
63   simgrid::mc::ObjectInformation* object_info,
64   unw_cursor_t * c,
65   void *frame_pointer_address,
66   simgrid::mc::AddressSpace* address_space,
67   int process_index)
68 {
69   unw_word_t ip = 0;
70   if (c && unw_get_reg(c, UNW_REG_IP, &ip))
71     xbt_die("Could not resolve IP");
72   simgrid::dwarf::DwarfExpression const* expression =
73     find_expression(locations, ip);
74   if (!expression)
75     xbt_die("Could not resolve location");
76   return simgrid::dwarf::resolve(
77           *expression, object_info, c,
78           frame_pointer_address, address_space, process_index);
79 }
80
81 LocationList location_list(
82   simgrid::mc::ObjectInformation& info,
83   Dwarf_Attribute& attr)
84 {
85   LocationList locations;
86   std::ptrdiff_t offset = 0;
87   while (1) {
88     Dwarf_Addr base;
89     Dwarf_Addr start;
90     Dwarf_Addr end;
91     Dwarf_Op *ops;
92     std::size_t len;
93
94     offset = dwarf_getlocations(&attr, offset, &base, &start, &end, &ops, &len);
95
96     if (offset == 0)
97       break;
98     else if (offset == -1)
99       xbt_die("Error while loading location list");
100
101     std::uint64_t base_address = (std::uint64_t) info.base_address();
102
103     LocationListEntry::range_type range;
104     if (start == 0)
105       // If start == 0, this is not a location list:
106       range = { 0, UINT64_MAX };
107     else
108       range =  { base_address + start, base_address + end };
109
110     locations.push_back({ DwarfExpression(ops, ops+len), range });
111   }
112
113   return locations;
114 }
115 }
116 }