-static dw_location_t MC_dwarf_resolve_location_list(mc_object_info_t info, Dwarf_Word offset) {
- char *key = bprintf("%ld", (long) offset);
- dw_location_t loc = xbt_new0(s_dw_location_t, 1);
- loc->type = e_dw_loclist;
- loc->location.loclist = (xbt_dynar_t)xbt_dict_get_or_null(info->location_list, key);
- if (!loc->location.loclist)
- XBT_INFO("Key not found in loclist");
- xbt_free(key);
- return loc;
+/** \brief Create a location list from a given attribute
+ *
+ * \param die the DIE
+ * \param attr the attribute
+ * \return MC specific representation of the location list represented by the given attribute
+ * of the given die
+ */
+static dw_location_t MC_dwarf_get_location_list(mc_object_info_t info, Dwarf_Die* die, Dwarf_Attribute* attr) {
+
+ dw_location_t location = xbt_new0(s_dw_location_t, 1);
+ location->type = e_dw_loclist;
+ xbt_dynar_t loclist = xbt_dynar_new(sizeof(dw_location_entry_t), NULL);
+ location->location.loclist = loclist;
+
+ ptrdiff_t offset = 0;
+ Dwarf_Addr base, start, end;
+ Dwarf_Op *expr;
+ size_t len;
+
+ while (1) {
+
+ offset = dwarf_getlocations(attr, offset, &base, &start, &end, &expr, &len);
+ if (offset==0)
+ return location;
+ else if (offset==-1)
+ xbt_die("Error while loading location list");
+
+ dw_location_entry_t new_entry = xbt_new0(s_dw_location_entry_t, 1);
+
+ void* base = info->flags & MC_OBJECT_INFO_EXECUTABLE ? 0 : MC_object_base_address(info);
+
+ new_entry->lowpc = (char*) base + start;
+ new_entry->highpc = (char*) base + end;
+ new_entry->location = MC_dwarf_get_expression(expr, len);
+
+ xbt_dynar_push(loclist, &new_entry);
+
+ }
+}
+
+/** \brief Find the frame base of a given frame
+ *
+ * \param ip Instruction pointer
+ * \param frame
+ * \param unw_cursor
+ */
+void* mc_find_frame_base(void* ip, dw_frame_t frame, unw_cursor_t* unw_cursor) {
+ switch(frame->frame_base->type) {
+ case e_dw_loclist:
+ {
+ int loclist_cursor;
+ for(loclist_cursor=0; loclist_cursor < xbt_dynar_length(frame->frame_base->location.loclist); loclist_cursor++){
+ dw_location_entry_t entry = xbt_dynar_get_as(frame->frame_base->location.loclist, loclist_cursor, dw_location_entry_t);
+ if((ip >= entry->lowpc) && (ip < entry->highpc)){
+ return (void*) MC_dwarf_resolve_location(unw_cursor, entry->location, NULL);
+ }
+ }
+ return NULL;
+ }
+ // Not handled:
+ default:
+ return NULL;
+ }