Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
please sonar
[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,
43       "Missing frame context for register operation DW_OP_reg%i",
44       dwarf_register);
45     return Location(dwarf_register_to_libunwind(dwarf_register));
46   }
47
48   simgrid::dwarf::ExpressionStack stack;
49   simgrid::dwarf::execute(expression, context, stack);
50   return Location((void*) stack.top());
51 }
52
53 // TODO, move this in a method of LocationList
54 static simgrid::dwarf::DwarfExpression const* find_expression(
55     simgrid::dwarf::LocationList const& locations, unw_word_t ip)
56 {
57   for (simgrid::dwarf::LocationListEntry const& entry : locations)
58     if (entry.valid_for_ip(ip))
59       return &entry.expression();
60   return nullptr;
61 }
62
63 Location resolve(
64   simgrid::dwarf::LocationList const& locations,
65   simgrid::mc::ObjectInformation* object_info,
66   unw_cursor_t * c,
67   void *frame_pointer_address,
68   simgrid::mc::AddressSpace* address_space,
69   int process_index)
70 {
71   unw_word_t ip = 0;
72   if (c && unw_get_reg(c, UNW_REG_IP, &ip))
73     xbt_die("Could not resolve IP");
74   simgrid::dwarf::DwarfExpression const* expression =
75     find_expression(locations, ip);
76   if (!expression)
77     xbt_die("Could not resolve location");
78   return simgrid::dwarf::resolve(
79           *expression, object_info, c,
80           frame_pointer_address, address_space, process_index);
81 }
82
83 LocationList location_list(
84   simgrid::mc::ObjectInformation& info,
85   Dwarf_Attribute& attr)
86 {
87   LocationList locations;
88   std::ptrdiff_t offset = 0;
89   while (1) {
90
91     Dwarf_Addr base, start, end;
92     Dwarf_Op *ops;
93     std::size_t len;
94
95     offset = dwarf_getlocations(
96       &attr, offset, &base, &start, &end, &ops, &len);
97
98     if (offset == 0)
99       break;
100     else if (offset == -1)
101       xbt_die("Error while loading location list");
102
103     std::uint64_t base_address = (std::uint64_t) info.base_address();
104
105     LocationListEntry::range_type range;
106     if (start == 0)
107       // If start == 0, this is not a location list:
108       range = { 0, UINT64_MAX };
109     else
110       range =  { base_address + start, base_address + end };
111
112     locations.push_back({ DwarfExpression(ops, ops+len), range });
113   }
114
115   return locations;
116 }
117
118
119 }
120 }