aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/ObjCopy/DXContainer/DXContainerWriter.cpp
blob: 6c26ec4cff6464f560510274aa442c88159cc1ed (plain)
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
//===- DXContainerWriter.cpp ----------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "DXContainerWriter.h"

namespace llvm {
namespace objcopy {
namespace dxbc {

using namespace object;

size_t DXContainerWriter::finalize() {
  assert(Offsets.empty() &&
         "Attempted to finalize writer with already computed offsets");
  Offsets.reserve(Obj.Parts.size());
  size_t Offset = Obj.headerSize();
  for (const Part &P : Obj.Parts) {
    Offsets.push_back(Offset);
    Offset += P.size();
  }
  return Obj.Header.FileSize;
}

Error DXContainerWriter::write() {
  size_t TotalSize = finalize();
  Out.reserveExtraSpace(TotalSize);

  llvm::dxbc::Header Header = Obj.Header;
  if (sys::IsBigEndianHost)
    Header.swapBytes();
  Out.write(reinterpret_cast<const char *>(&Header),
            sizeof(::llvm::dxbc::Header));
  if (sys::IsBigEndianHost)
    for (auto &O : Offsets)
      sys::swapByteOrder(O);
  Out.write(reinterpret_cast<const char *>(Offsets.data()),
            Offsets.size() * sizeof(uint32_t));

  for (const Part &P : Obj.Parts) {
    Out.write(reinterpret_cast<const char *>(P.Name.data()), 4);
    uint32_t Size = P.Data.size();
    if (sys::IsBigEndianHost)
      sys::swapByteOrder(Size);
    Out.write(reinterpret_cast<const char *>(&Size), sizeof(uint32_t));
    Out.write(reinterpret_cast<const char *>(P.Data.data()), P.Data.size());
  }

  return Error::success();
}

} // end namespace dxbc
} // end namespace objcopy
} // end namespace llvm