1*228c8f9cSJoseph Huber //===- OffloadEmitter.cpp -------------------------------------------------===//
2*228c8f9cSJoseph Huber //
3*228c8f9cSJoseph Huber // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*228c8f9cSJoseph Huber // See https://llvm.org/LICENSE.txt for license information.
5*228c8f9cSJoseph Huber // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*228c8f9cSJoseph Huber //
7*228c8f9cSJoseph Huber //===----------------------------------------------------------------------===//
8*228c8f9cSJoseph Huber 
9*228c8f9cSJoseph Huber #include "llvm/Object/OffloadBinary.h"
10*228c8f9cSJoseph Huber #include "llvm/ObjectYAML/OffloadYAML.h"
11*228c8f9cSJoseph Huber #include "llvm/ObjectYAML/yaml2obj.h"
12*228c8f9cSJoseph Huber #include "llvm/Support/Error.h"
13*228c8f9cSJoseph Huber #include "llvm/Support/raw_ostream.h"
14*228c8f9cSJoseph Huber 
15*228c8f9cSJoseph Huber using namespace llvm;
16*228c8f9cSJoseph Huber using namespace OffloadYAML;
17*228c8f9cSJoseph Huber 
18*228c8f9cSJoseph Huber namespace llvm {
19*228c8f9cSJoseph Huber namespace yaml {
20*228c8f9cSJoseph Huber 
yaml2offload(Binary & Doc,raw_ostream & Out,ErrorHandler EH)21*228c8f9cSJoseph Huber bool yaml2offload(Binary &Doc, raw_ostream &Out, ErrorHandler EH) {
22*228c8f9cSJoseph Huber   for (const auto &Member : Doc.Members) {
23*228c8f9cSJoseph Huber     object::OffloadBinary::OffloadingImage Image{};
24*228c8f9cSJoseph Huber     if (Member.ImageKind)
25*228c8f9cSJoseph Huber       Image.TheImageKind = *Member.ImageKind;
26*228c8f9cSJoseph Huber     if (Member.OffloadKind)
27*228c8f9cSJoseph Huber       Image.TheOffloadKind = *Member.OffloadKind;
28*228c8f9cSJoseph Huber     if (Member.Flags)
29*228c8f9cSJoseph Huber       Image.Flags = *Member.Flags;
30*228c8f9cSJoseph Huber 
31*228c8f9cSJoseph Huber     StringMap<StringRef> &StringData = Image.StringData;
32*228c8f9cSJoseph Huber     if (Member.StringEntries) {
33*228c8f9cSJoseph Huber       for (const auto &Entry : *Member.StringEntries) {
34*228c8f9cSJoseph Huber         StringData[Entry.Key] = Entry.Value;
35*228c8f9cSJoseph Huber       }
36*228c8f9cSJoseph Huber     }
37*228c8f9cSJoseph Huber 
38*228c8f9cSJoseph Huber     SmallVector<char, 1024> Data;
39*228c8f9cSJoseph Huber     raw_svector_ostream OS(Data);
40*228c8f9cSJoseph Huber     if (Member.Content)
41*228c8f9cSJoseph Huber       Member.Content->writeAsBinary(OS);
42*228c8f9cSJoseph Huber     Image.Image = MemoryBuffer::getMemBufferCopy(OS.str());
43*228c8f9cSJoseph Huber 
44*228c8f9cSJoseph Huber     std::unique_ptr<MemoryBuffer> Binary = object::OffloadBinary::write(Image);
45*228c8f9cSJoseph Huber 
46*228c8f9cSJoseph Huber     // Copy the data to a new buffer so we can modify the bytes directly.
47*228c8f9cSJoseph Huber     SmallVector<char> NewBuffer;
48*228c8f9cSJoseph Huber     std::copy(Binary->getBufferStart(), Binary->getBufferEnd(),
49*228c8f9cSJoseph Huber               std::back_inserter(NewBuffer));
50*228c8f9cSJoseph Huber     auto *TheHeader =
51*228c8f9cSJoseph Huber         reinterpret_cast<object::OffloadBinary::Header *>(&NewBuffer[0]);
52*228c8f9cSJoseph Huber     if (Doc.Version)
53*228c8f9cSJoseph Huber       TheHeader->Version = *Doc.Version;
54*228c8f9cSJoseph Huber     if (Doc.Size)
55*228c8f9cSJoseph Huber       TheHeader->Size = *Doc.Size;
56*228c8f9cSJoseph Huber     if (Doc.EntryOffset)
57*228c8f9cSJoseph Huber       TheHeader->EntryOffset = *Doc.EntryOffset;
58*228c8f9cSJoseph Huber     if (Doc.EntrySize)
59*228c8f9cSJoseph Huber       TheHeader->EntrySize = *Doc.EntrySize;
60*228c8f9cSJoseph Huber 
61*228c8f9cSJoseph Huber     Out.write(NewBuffer.begin(), NewBuffer.size());
62*228c8f9cSJoseph Huber   }
63*228c8f9cSJoseph Huber 
64*228c8f9cSJoseph Huber   return true;
65*228c8f9cSJoseph Huber }
66*228c8f9cSJoseph Huber 
67*228c8f9cSJoseph Huber } // namespace yaml
68*228c8f9cSJoseph Huber } // namespace llvm
69