Logo AND Algorithmique Numérique Distribuée

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