blob: a61f2cf7a94d2a43c6691e4c46a88d9ace3c016e [file] [log] [blame]
GDB currently does not handle all DW5 loclist options.
This patch adds code to handle DW_LLE_base_addressx,
DW_LLE_startx_length, and DW_LLE_start_length. This code was
backported (and updated sligntly) from upstream GDB.
Author: cmtice
Date: 05-Apr-2021
diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c
index 99cac03..7100241 100644
--- a/gdb/dwarf2loc.c
+++ b/gdb/dwarf2loc.c
@@ -173,9 +173,55 @@ decode_debug_loclists_addresses (struct dwarf2_per_cu_data *per_cu,
switch (*loc_ptr++)
{
+ case DW_LLE_base_addressx:
+ *low = 0;
+ loc_ptr = gdb_read_uleb128 (loc_ptr, buf_end, &u64);
+ if (loc_ptr == NULL)
+ return DEBUG_LOC_BUFFER_OVERFLOW;
+
+ *high = dwarf2_read_addr_index (per_cu, u64);
+ *new_ptr = loc_ptr;
+ return DEBUG_LOC_BASE_ADDRESS;
+
+ case DW_LLE_startx_length:
+ loc_ptr = gdb_read_uleb128 (loc_ptr, buf_end, &u64);
+ if (loc_ptr == NULL)
+ return DEBUG_LOC_BUFFER_OVERFLOW;
+
+ *low = dwarf2_read_addr_index (per_cu, u64);
+ *high = *low;
+ loc_ptr = gdb_read_uleb128 (loc_ptr, buf_end, &u64);
+ if (loc_ptr == NULL)
+ return DEBUG_LOC_BUFFER_OVERFLOW;
+
+ *high += u64;
+ *new_ptr = loc_ptr;
+ return DEBUG_LOC_START_LENGTH;
+
+ case DW_LLE_start_length:
+ if (buf_end - loc_ptr < addr_size)
+ return DEBUG_LOC_BUFFER_OVERFLOW;
+
+ if (signed_addr_p)
+ *low = extract_signed_integer (loc_ptr, addr_size, byte_order);
+ else
+ *low = extract_unsigned_integer (loc_ptr, addr_size, byte_order);
+
+ loc_ptr += addr_size;
+ *high = *low;
+
+ loc_ptr = gdb_read_uleb128 (loc_ptr, buf_end, &u64);
+ if (loc_ptr == NULL)
+ return DEBUG_LOC_BUFFER_OVERFLOW;
+
+ *high += u64;
+ *new_ptr = loc_ptr;
+ return DEBUG_LOC_START_LENGTH;
+
case DW_LLE_end_of_list:
*new_ptr = loc_ptr;
return DEBUG_LOC_END_OF_LIST;
+
case DW_LLE_base_address:
if (loc_ptr + addr_size > buf_end)
return DEBUG_LOC_BUFFER_OVERFLOW;
@@ -186,6 +232,7 @@ decode_debug_loclists_addresses (struct dwarf2_per_cu_data *per_cu,
loc_ptr += addr_size;
*new_ptr = loc_ptr;
return DEBUG_LOC_BASE_ADDRESS;
+
case DW_LLE_offset_pair:
loc_ptr = gdb_read_uleb128 (loc_ptr, buf_end, &u64);
if (loc_ptr == NULL)
@@ -197,6 +244,11 @@ decode_debug_loclists_addresses (struct dwarf2_per_cu_data *per_cu,
*high = u64;
*new_ptr = loc_ptr;
return DEBUG_LOC_START_END;
+
+ /* Following cases are not supported yet. */
+ case DW_LLE_startx_endx:
+ case DW_LLE_start_end:
+ case DW_LLE_default_location:
default:
return DEBUG_LOC_INVALID_ENTRY;
}