-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathLLVMDbiModuleDescriptorBuilder.cpp
More file actions
147 lines (118 loc) · 4.31 KB
/
LLVMDbiModuleDescriptorBuilder.cpp
File metadata and controls
147 lines (118 loc) · 4.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
// LLVMDbiModuleDescriptorBuilder.cpp : Implementation of CLLVMDbiModuleDescriptorBuilder
#include "pch.h"
#include "LLVMDbiStreamBuilder.h"
#include "LLVMDbiModuleDescriptorBuilder.h"
#include "LLVMDebugSubsection.h"
#include "Utilities.h"
using namespace boost::locale::conv;
// CLLVMDbiModuleDescriptorBuilder
HRESULT CLLVMDbiModuleDescriptorBuilder::construct(
const std::shared_ptr<BumpPtrAllocator>& theBumpPtrAllocator,
const std::shared_ptr<pdb::PDBFileBuilder>& thePDBFileBuilder, std::string& moduleName)
{
bumpPtrAllocator = theBumpPtrAllocator;
pdbFileBuilder = thePDBFileBuilder;
dbiStreamBuilder = pdbFileBuilder->getDbiBuilder();
auto expected = dbiStreamBuilder->addModuleInfo(moduleName);
HRESULT res = checkLLVMErrorAndSetCOMError(expected.takeError(), GetObjectCLSID(),
IID_ILLVMDbiStreamBuilder);
if (SUCCEEDED(res))
dbiModuleDescriptorBuilder = *expected;
return res;
}
STDMETHODIMP CLLVMDbiModuleDescriptorBuilder::InterfaceSupportsErrorInfo(REFIID riid)
{
static const IID* const arr[] =
{
&IID_ILLVMDbiModuleDescriptorBuilder
};
for (int i=0; i < sizeof(arr) / sizeof(arr[0]); i++)
{
if (InlineIsEqualGUID(*arr[i],riid))
return S_OK;
}
return S_FALSE;
}
STDMETHODIMP CLLVMDbiModuleDescriptorBuilder::setObjFileName(BSTR Name)
{
dbiModuleDescriptorBuilder->setObjFileName(boost::locale::conv::utf_to_utf<char>(Name));
return S_OK;
}
STDMETHODIMP CLLVMDbiModuleDescriptorBuilder::addSymbolsInBulk(VARIANT BulkSymbols)
{
if (BulkSymbols.vt != (VT_ARRAY | VT_UI1)) return E_INVALIDARG;
HRESULT hres = SafeArrayLock(BulkSymbols.parray);
if (FAILED(hres)) return hres;
BOOST_SCOPE_EXIT(&BulkSymbols) {
SafeArrayUnlock(BulkSymbols.parray);
} BOOST_SCOPE_EXIT_END
if (SafeArrayGetDim(BulkSymbols.parray) != 1) return E_INVALIDARG;
LONG l, u;
hres = SafeArrayGetLBound(BulkSymbols.parray, 1, &l);
if (FAILED(hres)) return hres;
hres = SafeArrayGetUBound(BulkSymbols.parray, 1, &u);
if (FAILED(hres)) return hres;
uint32_t len = u - l + 1;
uint8_t* storage = bumpPtrAllocator->Allocate<uint8_t>(len);
std::memcpy(storage, BulkSymbols.parray->pvData, len);
dbiModuleDescriptorBuilder->addSymbolsInBulk(
ArrayRef<uint8_t>(storage, len));
return S_OK;
}
STDMETHODIMP CLLVMDbiModuleDescriptorBuilder::getObjFileName(BSTR* res)
{
CComBSTR temp(
utf_to_utf<wchar_t>(
dbiModuleDescriptorBuilder->getObjFileName().str())
.c_str());
return temp.CopyTo(res);
}
STDMETHODIMP CLLVMDbiModuleDescriptorBuilder::addDebugSubsection(ILLVMDebugSubsection* Subsection)
{
dbiModuleDescriptorBuilder->addDebugSubsection(
dynamic_cast<CLLVMDebugSubsection*>(Subsection)->getSharedDebugSubsection());
return S_OK;
}
STDMETHODIMP CLLVMDbiModuleDescriptorBuilder::setFirstSectionContrib(const LLVM_SectionContrib* SC)
{
dbiModuleDescriptorBuilder->setFirstSectionContrib(*reinterpret_cast<const pdb::SectionContrib*>(SC));
return S_OK;
}
STDMETHODIMP CLLVMDbiModuleDescriptorBuilder::getModuleIndex(ULONG* ModI)
{
*ModI = dbiModuleDescriptorBuilder->getModuleIndex();
return S_OK;
}
STDMETHODIMP CLLVMDbiModuleDescriptorBuilder::setPdbFilePathNI(ULONG NI)
{
dbiModuleDescriptorBuilder->setPdbFilePathNI(NI);
return S_OK;
}
STDMETHODIMP CLLVMDbiModuleDescriptorBuilder::addSymbol(VARIANT Symbol)
{
if (Symbol.vt != (VT_ARRAY | VT_UI1)) return E_INVALIDARG;
HRESULT hres = SafeArrayLock(Symbol.parray);
if (FAILED(hres)) return hres;
BOOST_SCOPE_EXIT(&Symbol) {
SafeArrayUnlock(Symbol.parray);
} BOOST_SCOPE_EXIT_END
if (SafeArrayGetDim(Symbol.parray) != 1) return E_INVALIDARG;
LONG l, u;
hres = SafeArrayGetLBound(Symbol.parray, 1, &l);
if (FAILED(hres)) return hres;
hres = SafeArrayGetUBound(Symbol.parray, 1, &u);
if (FAILED(hres)) return hres;
uint32_t len = u - l + 1;
uint8_t* storage = reinterpret_cast<uint8_t*>(bumpPtrAllocator->Allocate(len, 4));
std::memcpy(storage, Symbol.parray->pvData, len);
// Technically not necessary, but it does provide a nice sanity check that the symbol coming in
// is valid
ArrayRef<uint8_t> rawSymbol(storage, len);
BinaryStreamRef streamRef(rawSymbol, support::little);
Expected<codeview::CVSymbol> symbol = codeview::readSymbolFromStream(streamRef, 0);
if (!symbol)
return checkLLVMErrorAndSetCOMError(symbol.takeError(), GetObjectCLSID(),
IID_ILLVMDbiModuleDescriptorBuilder);
dbiModuleDescriptorBuilder->addSymbol(symbol.get());
return S_OK;
}