124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===-- DNBDataRef.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//  Created by Greg Clayton on 1/11/06.
1124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
1224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===----------------------------------------------------------------------===//
1324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "DNBDataRef.h"
1524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "DNBLog.h"
1624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include <assert.h>
1724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include <ctype.h>
1824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include <libkern/OSByteOrder.h>
1924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
2024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
2124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Constructor
2224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
2324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
2424943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDNBDataRef::DNBDataRef() :
2524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_start(NULL),
2624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_end(NULL),
2724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_swap(false),
2824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_ptrSize(0),
2924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_addrPCRelative(INVALID_NUB_ADDRESS),
3024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_addrTEXT(INVALID_NUB_ADDRESS),
3124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_addrDATA(INVALID_NUB_ADDRESS)
3224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
3324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
3424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
3524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
3624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
3724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Constructor
3824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
3924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
4024943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDNBDataRef::DNBDataRef(const uint8_t *start, size_t size, bool swap) :
4124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_start(start),
4224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_end(start+size),
4324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_swap(swap),
4424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_ptrSize(0),
4524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_addrPCRelative(INVALID_NUB_ADDRESS),
4624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_addrTEXT(INVALID_NUB_ADDRESS),
4724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_addrDATA(INVALID_NUB_ADDRESS)
4824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
4924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
5024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
5124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
5224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
5324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Destructor
5424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
5524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
5624943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDNBDataRef::~DNBDataRef()
5724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
5824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
5924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
6024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
6124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
6224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Get8
6324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
6424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattneruint8_t
6524943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDNBDataRef::Get8(offset_t *offset_ptr) const
6624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
6724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    uint8_t val = 0;
6824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if ( ValidOffsetForDataOfSize(*offset_ptr, sizeof(val)) )
6924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
7024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        val = *(m_start + *offset_ptr);
7124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        *offset_ptr += sizeof(val);
7224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
7324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return val;
7424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
7524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
7624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
7724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
7824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Get16
7924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
8024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattneruint16_t
8124943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDNBDataRef::Get16(offset_t *offset_ptr) const
8224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
8324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    uint16_t val = 0;
8424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if ( ValidOffsetForDataOfSize(*offset_ptr, sizeof(val)) )
8524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
8624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        const uint8_t *p = m_start + *offset_ptr;
8724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        val = *(uint16_t*)p;
8824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
8924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (m_swap)
9024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            val = OSSwapInt16(val);
9124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
9224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // Advance the offset
9324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        *offset_ptr += sizeof(val);
9424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
9524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return val;
9624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
9724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
9824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
9924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
10024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Get32
10124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
10224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattneruint32_t
10324943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDNBDataRef::Get32(offset_t *offset_ptr) const
10424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
10524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    uint32_t val = 0;
10624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if ( ValidOffsetForDataOfSize(*offset_ptr, sizeof(val)) )
10724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
10824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        const uint8_t *p = m_start + *offset_ptr;
10924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        val = *(uint32_t*)p;
11024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (m_swap)
11124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            val = OSSwapInt32(val);
11224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
11324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // Advance the offset
11424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        *offset_ptr += sizeof(val);
11524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
11624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return val;
11724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
11824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
11924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
12024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
12124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Get64
12224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
12324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattneruint64_t
12424943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDNBDataRef::Get64(offset_t *offset_ptr) const
12524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
12624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    uint64_t val = 0;
12724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if ( ValidOffsetForDataOfSize(*offset_ptr, sizeof(val)) )
12824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
12924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        const uint8_t *p = m_start + *offset_ptr;
13024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        val = *(uint64_t*)p;
13124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (m_swap)
13224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            val = OSSwapInt64(val);
13324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
13424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // Advance the offset
13524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        *offset_ptr += sizeof(val);
13624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
13724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return val;
13824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
13924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
14024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
14124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
14224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// GetMax32
14324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
14424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Used for calls when the size can vary. Fill in extra cases if they
14524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// are ever needed.
14624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
14724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattneruint32_t
14824943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDNBDataRef::GetMax32(offset_t *offset_ptr, uint32_t byte_size) const
14924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
15024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    switch (byte_size)
15124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
15224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case 1: return Get8 (offset_ptr); break;
15324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case 2: return Get16(offset_ptr); break;
15424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case 4:    return Get32(offset_ptr); break;
15524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        default:
15624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        assert(!"GetMax32 unhandled case!");
15724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            break;
15824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
15924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return 0;
16024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
16124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
16224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
16324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
16424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// GetMax64
16524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
16624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Used for calls when the size can vary. Fill in extra cases if they
16724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// are ever needed.
16824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
16924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattneruint64_t
17024943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDNBDataRef::GetMax64(offset_t *offset_ptr, uint32_t size) const
17124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
17224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    switch (size)
17324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
17424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case 1: return Get8 (offset_ptr); break;
17524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case 2: return Get16(offset_ptr); break;
17624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case 4: return Get32(offset_ptr); break;
17724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case 8: return Get64(offset_ptr); break;
17824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        default:
17924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        assert(!"GetMax64 unhandled case!");
18024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            break;
18124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
18224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return 0;
18324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
18424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
18524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
18624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// GetPointer
18724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
18824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Extract a pointer value from the buffer. The pointer size must be
18924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// set prior to using this using one of the SetPointerSize functions.
19024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
19124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattneruint64_t
19224943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDNBDataRef::GetPointer(offset_t *offset_ptr) const
19324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
19424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // Must set pointer size prior to using this call
19524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    assert(m_ptrSize != 0);
19624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return GetMax64(offset_ptr, m_ptrSize);
19724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
19824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
19924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// GetCStr
20024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
20124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerconst char *
20224943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDNBDataRef::GetCStr(offset_t *offset_ptr, uint32_t fixed_length) const
20324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
20424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const char *s = NULL;
20524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if ( m_start < m_end )
20624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
20724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        s = (char*)m_start + *offset_ptr;
20824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
20924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // Advance the offset
21024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (fixed_length)
21124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            *offset_ptr += fixed_length;
21224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        else
21324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            *offset_ptr += strlen(s) + 1;
21424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
21524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return s;
21624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
21724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
21824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
21924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
22024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// GetData
22124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
22224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerconst uint8_t *
22324943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDNBDataRef::GetData(offset_t *offset_ptr, uint32_t length) const
22424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
22524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const uint8_t *data = NULL;
22624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if ( length > 0 && ValidOffsetForDataOfSize(*offset_ptr, length) )
22724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
22824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        data = m_start + *offset_ptr;
22924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        *offset_ptr += length;
23024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
23124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return data;
23224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
23324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
23424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
23524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
23624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Get_ULEB128
23724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
23824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattneruint64_t
23924943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDNBDataRef::Get_ULEB128 (offset_t *offset_ptr) const
24024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
24124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    uint64_t result = 0;
24224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if ( m_start < m_end )
24324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
24424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        int shift = 0;
24524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        const uint8_t *src = m_start + *offset_ptr;
24624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        uint8_t byte;
24724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        int bytecount = 0;
24824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
24924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        while (src < m_end)
25024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
25124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            bytecount++;
25224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            byte = *src++;
25324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            result |= (byte & 0x7f) << shift;
25424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            shift += 7;
25524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            if ((byte & 0x80) == 0)
25624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                break;
25724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
25824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
25924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        *offset_ptr += bytecount;
26024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
26124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return result;
26224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
26324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
26424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
26524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
26624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Get_SLEB128
26724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
26824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerint64_t
26924943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDNBDataRef::Get_SLEB128 (offset_t *offset_ptr) const
27024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
27124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    int64_t result = 0;
27224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
27324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if ( m_start < m_end )
27424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
27524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        int shift = 0;
27624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        int size = sizeof (uint32_t) * 8;
27724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        const uint8_t *src = m_start + *offset_ptr;
27824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
2797559f33de7b3706324fcc8467179463f7aaec348Johnny Chen        uint8_t byte = 0;
28024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        int bytecount = 0;
28124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
28224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        while (src < m_end)
28324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
28424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            bytecount++;
28524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            byte = *src++;
28624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            result |= (byte & 0x7f) << shift;
28724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            shift += 7;
28824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            if ((byte & 0x80) == 0)
28924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                break;
29024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
29124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
29224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // Sign bit of byte is 2nd high order bit (0x40)
29324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (shift < size && (byte & 0x40))
29424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            result |= - (1ll << shift);
29524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
29624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        *offset_ptr += bytecount;
29724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
29824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return result;
29924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
30024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
30124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
30224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
30324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Skip_LEB128
30424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
30524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Skips past ULEB128 and SLEB128 numbers (just updates the offset)
30624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
30724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
30824943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDNBDataRef::Skip_LEB128 (offset_t *offset_ptr) const
30924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
31024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if ( m_start < m_end )
31124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
31224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        const uint8_t *start = m_start + *offset_ptr;
31324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        const uint8_t *src = start;
31424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
31524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        while ((src < m_end) && (*src++ & 0x80))
31624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            /* Do nothing */;
31724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
31824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        *offset_ptr += src - start;
31924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
32024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
32124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
32224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattneruint32_t
32324943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDNBDataRef::Dump
32424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner(
32524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    uint32_t startOffset,
32624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    uint32_t endOffset,
32724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    uint64_t offsetBase,
32824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    DNBDataRef::Type type,
32924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    uint32_t numPerLine,
33024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const char *format
33124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner)
33224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
33324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    uint32_t offset;
33424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    uint32_t count;
33524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    char str[1024];
33624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    str[0] = '\0';
33724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    int str_offset = 0;
33824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
33924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    for (offset = startOffset, count = 0; ValidOffset(offset) && offset < endOffset; ++count)
34024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
34124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if ((count % numPerLine) == 0)
34224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
34324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            // Print out any previous string
34424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            if (str[0] != '\0')
34524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                DNBLog("%s", str);
34624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            // Reset string offset and fill the current line string with address:
34724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            str_offset = 0;
34824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            str_offset += snprintf(str, sizeof(str), "0x%8.8llx:", (uint64_t)(offsetBase + (offset - startOffset)));
34924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
35024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
35124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // Make sure we don't pass the bounds of our current string buffer on each iteration through this loop
35224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (str_offset >= sizeof(str))
35324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
35424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            // The last snprintf consumed our string buffer, we will need to dump this out
35524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            // and reset the string with no address
35624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            DNBLog("%s", str);
35724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            str_offset = 0;
35824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            str[0] = '\0';
35924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
36024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
36124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // We already checked that there is at least some room in the string str above, so it is safe to make
36224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // the snprintf call each time through this loop
36324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        switch (type)
36424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
36524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            default:
36624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            case TypeUInt8:   str_offset += snprintf(str + str_offset, sizeof(str) - str_offset, format ? format : " %2.2x", Get8(&offset)); break;
36724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            case TypeChar:
36824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                {
36924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    char ch = Get8(&offset);
37024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    str_offset += snprintf(str + str_offset, sizeof(str) - str_offset, format ? format : " %c",    isprint(ch) ? ch : ' ');
37124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                }
37224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                break;
37324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            case TypeUInt16:  str_offset += snprintf(str + str_offset, sizeof(str) - str_offset, format ? format : " %4.4x",       Get16(&offset)); break;
37424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            case TypeUInt32:  str_offset += snprintf(str + str_offset, sizeof(str) - str_offset, format ? format : " %8.8x",       Get32(&offset)); break;
37524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            case TypeUInt64:  str_offset += snprintf(str + str_offset, sizeof(str) - str_offset, format ? format : " %16.16llx",   Get64(&offset)); break;
37624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            case TypePointer: str_offset += snprintf(str + str_offset, sizeof(str) - str_offset, format ? format : " 0x%llx",      GetPointer(&offset)); break;
37724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            case TypeULEB128: str_offset += snprintf(str + str_offset, sizeof(str) - str_offset, format ? format : " 0x%llx",      Get_ULEB128(&offset)); break;
37824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            case TypeSLEB128: str_offset += snprintf(str + str_offset, sizeof(str) - str_offset, format ? format : " %lld",        Get_SLEB128(&offset)); break;
37924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
38024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
38124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
38224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (str[0] != '\0')
38324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        DNBLog("%s", str);
38424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
38524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return offset;  // Return the offset at which we ended up
38624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
387