124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===-- DWARFLocationDescription.cpp ----------------------------*- C++ -*-===//
224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//                     The LLVM Compiler Infrastructure
424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// This file is distributed under the University of Illinois Open Source
624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// License. See LICENSE.TXT for details.
724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===----------------------------------------------------------------------===//
924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "DWARFLocationDescription.h"
1124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "DWARFDefines.h"
1224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/lldb-private.h"
1324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/Stream.h"
1424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerusing namespace lldb_private;
1724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1836da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Claytonstatic int print_dwarf_exp_op (Stream &s, const DataExtractor& data, lldb::offset_t *offset_ptr, int address_size, int dwarf_ref_size);
1924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
2024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerint
21169c5fbc8cac8a0bd724bd18fd9d816ca3d6486aJim Inghamprint_dwarf_expression (Stream &s,
2224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        const DataExtractor& data,
2324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        int address_size,
2424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        int dwarf_ref_size,
2524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        bool location_expression)
2624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
2724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    int op_count = 0;
2836da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton    lldb::offset_t offset = 0;
2924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    while (data.ValidOffset(offset))
3024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
3124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (location_expression && op_count > 0)
3224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
3324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            //  err (baton, "Dwarf location expressions may only have one operand!");
3424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            return 1;
3524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
3624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (op_count > 0)
3724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
38169c5fbc8cac8a0bd724bd18fd9d816ca3d6486aJim Ingham            s.PutCString(", ");
3924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
4024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (print_dwarf_exp_op (s, data, &offset, address_size, dwarf_ref_size) == 1)
4124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            return 1;
4224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        op_count++;
4324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
4424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
4524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return 0;
4624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
4724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
4824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerstatic int
49169c5fbc8cac8a0bd724bd18fd9d816ca3d6486aJim Inghamprint_dwarf_exp_op (Stream &s,
5024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    const DataExtractor& data,
5136da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton                    lldb::offset_t *offset_ptr,
5224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    int address_size,
5324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    int dwarf_ref_size)
5424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
5524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    uint8_t opcode = data.GetU8(offset_ptr);
5624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    DRC_class opcode_class;
5724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    uint64_t  uint;
5824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    int64_t   sint;
5924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
6024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    int size;
6124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
6224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    opcode_class = DW_OP_value_to_class (opcode) & (~DRC_DWARFv3);
6324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
64169c5fbc8cac8a0bd724bd18fd9d816ca3d6486aJim Ingham    s.Printf("%s ", DW_OP_value_to_name (opcode));
6524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
6624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    /* Does this take zero parameters?  If so we can shortcut this function.  */
6724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (opcode_class == DRC_ZEROOPERANDS)
6824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return 0;
6924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
7024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (opcode_class == DRC_TWOOPERANDS && opcode == DW_OP_bregx)
7124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
7224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        uint = data.GetULEB128(offset_ptr);
7324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        sint = data.GetSLEB128(offset_ptr);
745f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea        s.Printf("%" PRIu64 " %" PRIi64, uint, sint);
7524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return 0;
7624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
7724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (opcode_class != DRC_ONEOPERAND)
7824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
79169c5fbc8cac8a0bd724bd18fd9d816ca3d6486aJim Ingham        s.Printf("UNKNOWN OP %u", opcode);
8024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return 1;
8124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
8224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
8324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    switch (opcode)
8424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
8524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case DW_OP_addr:    size = address_size;    break;
8624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case DW_OP_const1u: size = 1;               break;
8724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case DW_OP_const1s: size = -1;              break;
8824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case DW_OP_const2u: size = 2;               break;
8924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case DW_OP_const2s: size = -2;              break;
9024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case DW_OP_const4u: size = 4;               break;
9124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case DW_OP_const4s: size = -4;              break;
9224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case DW_OP_const8u: size = 8;               break;
9324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case DW_OP_const8s: size = -8;              break;
9424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case DW_OP_constu:  size = 128;             break;
9524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case DW_OP_consts:  size = -128;            break;
9624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case DW_OP_fbreg:   size = -128;            break;
9724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case DW_OP_breg0:
9824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case DW_OP_breg1:
9924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case DW_OP_breg2:
10024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case DW_OP_breg3:
10124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case DW_OP_breg4:
10224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case DW_OP_breg5:
10324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case DW_OP_breg6:
10424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case DW_OP_breg7:
10524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case DW_OP_breg8:
10624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case DW_OP_breg9:
10724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case DW_OP_breg10:
10824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case DW_OP_breg11:
10924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case DW_OP_breg12:
11024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case DW_OP_breg13:
11124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case DW_OP_breg14:
11224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case DW_OP_breg15:
11324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case DW_OP_breg16:
11424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case DW_OP_breg17:
11524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case DW_OP_breg18:
11624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case DW_OP_breg19:
11724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case DW_OP_breg20:
11824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case DW_OP_breg21:
11924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case DW_OP_breg22:
12024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case DW_OP_breg23:
12124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case DW_OP_breg24:
12224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case DW_OP_breg25:
12324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case DW_OP_breg26:
12424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case DW_OP_breg27:
12524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case DW_OP_breg28:
12624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case DW_OP_breg29:
12724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case DW_OP_breg30:
12824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case DW_OP_breg31:
12924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            size = -128; break;
13024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case DW_OP_pick:
13124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            size = 1;       break;
13224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case DW_OP_deref_size:
13324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            size = 1;       break;
13424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case DW_OP_xderef_size:
13524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            size = 1;       break;
13624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case DW_OP_plus_uconst:
13724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            size = 128;     break;
13824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case DW_OP_skip:
13924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            size = -2;      break;
14024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case DW_OP_bra:
14124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            size = -2;      break;
14224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case DW_OP_call2:
14324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            size = 2;       break;
14424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case DW_OP_call4:
14524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            size = 4;       break;
14624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case DW_OP_call_ref:
14724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            size = dwarf_ref_size;  break;
14824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case DW_OP_piece:
14924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            size = 128; break;
15024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case DW_OP_regx:
15124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            size = 128; break;
15224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        default:
153169c5fbc8cac8a0bd724bd18fd9d816ca3d6486aJim Ingham            s.Printf("UNKNOWN ONE-OPERAND OPCODE, #%u", opcode);
15424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            return 1;
15524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
15624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
15724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    switch (size)
15824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
1595f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea    case -1:    sint = (int8_t)     data.GetU8(offset_ptr);     s.Printf("%+" PRIi64, sint); break;
1605f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea    case -2:    sint = (int16_t)    data.GetU16(offset_ptr);    s.Printf("%+" PRIi64, sint); break;
1615f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea    case -4:    sint = (int32_t)    data.GetU32(offset_ptr);    s.Printf("%+" PRIi64, sint); break;
1625f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea    case -8:    sint = (int64_t)    data.GetU64(offset_ptr);    s.Printf("%+" PRIi64, sint); break;
1635f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea    case -128:  sint = data.GetSLEB128(offset_ptr);             s.Printf("%+" PRIi64, sint); break;
1645f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea    case 1:     uint = data.GetU8(offset_ptr);                  s.Printf("0x%2.2" PRIx64, uint); break;
1655f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea    case 2:     uint = data.GetU16(offset_ptr);                 s.Printf("0x%4.4" PRIx64, uint); break;
1665f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea    case 4:     uint = data.GetU32(offset_ptr);                 s.Printf("0x%8.8" PRIx64, uint); break;
1675f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea    case 8:     uint = data.GetU64(offset_ptr);                 s.Printf("0x%16.16" PRIx64, uint); break;
1685f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea    case 128:   uint = data.GetULEB128(offset_ptr);             s.Printf("0x%" PRIx64, uint); break;
16924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
17024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
17124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return 0;
17224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
173