Files
clang-p2996/lldb/source/Plugins/SymbolFile/DWARF/DWARFLocationDescription.cpp
Greg Clayton c7bece56fa <rdar://problem/13069948>
Major fixed to allow reading files that are over 4GB. The main problems were that the DataExtractor was using 32 bit offsets as a data cursor, and since we mmap all of our object files we could run into cases where if we had a very large core file that was over 4GB, we were running into the 4GB boundary.

So I defined a new "lldb::offset_t" which should be used for all file offsets.

After making this change, I enabled warnings for data loss and for enexpected implicit conversions temporarily and found a ton of things that I fixed.

Any functions that take an index internally, should use "size_t" for any indexes and also should return "size_t" for any sizes of collections.

llvm-svn: 173463
2013-01-25 18:06:21 +00:00

173 lines
5.7 KiB
C++

//===-- DWARFLocationDescription.cpp ----------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "DWARFLocationDescription.h"
#include "DWARFDefines.h"
#include "lldb/lldb-private.h"
#include "lldb/Core/Stream.h"
using namespace lldb_private;
static int print_dwarf_exp_op (Stream &s, const DataExtractor& data, lldb::offset_t *offset_ptr, int address_size, int dwarf_ref_size);
int
print_dwarf_expression (Stream &s,
const DataExtractor& data,
int address_size,
int dwarf_ref_size,
bool location_expression)
{
int op_count = 0;
lldb::offset_t offset = 0;
while (data.ValidOffset(offset))
{
if (location_expression && op_count > 0)
{
// err (baton, "Dwarf location expressions may only have one operand!");
return 1;
}
if (op_count > 0)
{
s.PutCString(", ");
}
if (print_dwarf_exp_op (s, data, &offset, address_size, dwarf_ref_size) == 1)
return 1;
op_count++;
}
return 0;
}
static int
print_dwarf_exp_op (Stream &s,
const DataExtractor& data,
lldb::offset_t *offset_ptr,
int address_size,
int dwarf_ref_size)
{
uint8_t opcode = data.GetU8(offset_ptr);
DRC_class opcode_class;
uint64_t uint;
int64_t sint;
int size;
opcode_class = DW_OP_value_to_class (opcode) & (~DRC_DWARFv3);
s.Printf("%s ", DW_OP_value_to_name (opcode));
/* Does this take zero parameters? If so we can shortcut this function. */
if (opcode_class == DRC_ZEROOPERANDS)
return 0;
if (opcode_class == DRC_TWOOPERANDS && opcode == DW_OP_bregx)
{
uint = data.GetULEB128(offset_ptr);
sint = data.GetSLEB128(offset_ptr);
s.Printf("%" PRIu64 " %" PRIi64, uint, sint);
return 0;
}
if (opcode_class != DRC_ONEOPERAND)
{
s.Printf("UNKNOWN OP %u", opcode);
return 1;
}
switch (opcode)
{
case DW_OP_addr: size = address_size; break;
case DW_OP_const1u: size = 1; break;
case DW_OP_const1s: size = -1; break;
case DW_OP_const2u: size = 2; break;
case DW_OP_const2s: size = -2; break;
case DW_OP_const4u: size = 4; break;
case DW_OP_const4s: size = -4; break;
case DW_OP_const8u: size = 8; break;
case DW_OP_const8s: size = -8; break;
case DW_OP_constu: size = 128; break;
case DW_OP_consts: size = -128; break;
case DW_OP_fbreg: size = -128; break;
case DW_OP_breg0:
case DW_OP_breg1:
case DW_OP_breg2:
case DW_OP_breg3:
case DW_OP_breg4:
case DW_OP_breg5:
case DW_OP_breg6:
case DW_OP_breg7:
case DW_OP_breg8:
case DW_OP_breg9:
case DW_OP_breg10:
case DW_OP_breg11:
case DW_OP_breg12:
case DW_OP_breg13:
case DW_OP_breg14:
case DW_OP_breg15:
case DW_OP_breg16:
case DW_OP_breg17:
case DW_OP_breg18:
case DW_OP_breg19:
case DW_OP_breg20:
case DW_OP_breg21:
case DW_OP_breg22:
case DW_OP_breg23:
case DW_OP_breg24:
case DW_OP_breg25:
case DW_OP_breg26:
case DW_OP_breg27:
case DW_OP_breg28:
case DW_OP_breg29:
case DW_OP_breg30:
case DW_OP_breg31:
size = -128; break;
case DW_OP_pick:
size = 1; break;
case DW_OP_deref_size:
size = 1; break;
case DW_OP_xderef_size:
size = 1; break;
case DW_OP_plus_uconst:
size = 128; break;
case DW_OP_skip:
size = -2; break;
case DW_OP_bra:
size = -2; break;
case DW_OP_call2:
size = 2; break;
case DW_OP_call4:
size = 4; break;
case DW_OP_call_ref:
size = dwarf_ref_size; break;
case DW_OP_piece:
size = 128; break;
case DW_OP_regx:
size = 128; break;
default:
s.Printf("UNKNOWN ONE-OPERAND OPCODE, #%u", opcode);
return 1;
}
switch (size)
{
case -1: sint = (int8_t) data.GetU8(offset_ptr); s.Printf("%+" PRIi64, sint); break;
case -2: sint = (int16_t) data.GetU16(offset_ptr); s.Printf("%+" PRIi64, sint); break;
case -4: sint = (int32_t) data.GetU32(offset_ptr); s.Printf("%+" PRIi64, sint); break;
case -8: sint = (int64_t) data.GetU64(offset_ptr); s.Printf("%+" PRIi64, sint); break;
case -128: sint = data.GetSLEB128(offset_ptr); s.Printf("%+" PRIi64, sint); break;
case 1: uint = data.GetU8(offset_ptr); s.Printf("0x%2.2" PRIx64, uint); break;
case 2: uint = data.GetU16(offset_ptr); s.Printf("0x%4.4" PRIx64, uint); break;
case 4: uint = data.GetU32(offset_ptr); s.Printf("0x%8.8" PRIx64, uint); break;
case 8: uint = data.GetU64(offset_ptr); s.Printf("0x%16.16" PRIx64, uint); break;
case 128: uint = data.GetULEB128(offset_ptr); s.Printf("0x%" PRIx64, uint); break;
}
return 0;
}