LLVM  15.0.0git
OffloadBinary.cpp
Go to the documentation of this file.
1 //===- Offloading.cpp - Utilities for handling offloading code -*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
10 
11 #include "llvm/ADT/StringSwitch.h"
14 #include "llvm/Object/Error.h"
15 #include "llvm/Support/Alignment.h"
17 
18 using namespace llvm;
19 using namespace llvm::object;
20 
23  if (Buf.getBufferSize() < sizeof(Header) + sizeof(Entry))
25 
26  // Check for 0x10FF1OAD magic bytes.
29 
30  // Make sure that the data has sufficient alignment.
33 
34  const char *Start = Buf.getBufferStart();
35  const Header *TheHeader = reinterpret_cast<const Header *>(Start);
36  if (TheHeader->Version != OffloadBinary::Version)
38 
39  if (TheHeader->Size > Buf.getBufferSize() ||
40  TheHeader->EntryOffset > TheHeader->Size - sizeof(Entry) ||
41  TheHeader->EntrySize > TheHeader->Size - sizeof(Header))
43 
44  const Entry *TheEntry =
45  reinterpret_cast<const Entry *>(&Start[TheHeader->EntryOffset]);
46 
47  if (TheEntry->ImageOffset > Buf.getBufferSize() ||
48  TheEntry->StringOffset > Buf.getBufferSize())
50 
51  return std::unique_ptr<OffloadBinary>(
52  new OffloadBinary(Buf, TheHeader, TheEntry));
53 }
54 
55 std::unique_ptr<MemoryBuffer>
56 OffloadBinary::write(const OffloadingImage &OffloadingData) {
57  // Create a null-terminated string table with all the used strings.
59  for (auto &KeyAndValue : OffloadingData.StringData) {
60  StrTab.add(KeyAndValue.getKey());
61  StrTab.add(KeyAndValue.getValue());
62  }
63  StrTab.finalize();
64 
65  uint64_t StringEntrySize =
66  sizeof(StringEntry) * OffloadingData.StringData.size();
67 
68  // Make sure the image we're wrapping around is aligned as well.
69  uint64_t BinaryDataSize = alignTo(sizeof(Header) + sizeof(Entry) +
70  StringEntrySize + StrTab.getSize(),
71  getAlignment());
72 
73  // Create the header and fill in the offsets. The entry will be directly
74  // placed after the header in memory. Align the size to the alignment of the
75  // header so this can be placed contiguously in a single section.
76  Header TheHeader;
77  TheHeader.Size = alignTo(
78  BinaryDataSize + OffloadingData.Image->getBufferSize(), getAlignment());
79  TheHeader.EntryOffset = sizeof(Header);
80  TheHeader.EntrySize = sizeof(Entry);
81 
82  // Create the entry using the string table offsets. The string table will be
83  // placed directly after the entry in memory, and the image after that.
84  Entry TheEntry;
85  TheEntry.TheImageKind = OffloadingData.TheImageKind;
86  TheEntry.TheOffloadKind = OffloadingData.TheOffloadKind;
87  TheEntry.Flags = OffloadingData.Flags;
88  TheEntry.StringOffset = sizeof(Header) + sizeof(Entry);
89  TheEntry.NumStrings = OffloadingData.StringData.size();
90 
91  TheEntry.ImageOffset = BinaryDataSize;
92  TheEntry.ImageSize = OffloadingData.Image->getBufferSize();
93 
95  Data.reserve(TheHeader.Size);
97  OS << StringRef(reinterpret_cast<char *>(&TheHeader), sizeof(Header));
98  OS << StringRef(reinterpret_cast<char *>(&TheEntry), sizeof(Entry));
99  for (auto &KeyAndValue : OffloadingData.StringData) {
100  uint64_t Offset = sizeof(Header) + sizeof(Entry) + StringEntrySize;
101  StringEntry Map{Offset + StrTab.getOffset(KeyAndValue.getKey()),
102  Offset + StrTab.getOffset(KeyAndValue.getValue())};
103  OS << StringRef(reinterpret_cast<char *>(&Map), sizeof(StringEntry));
104  }
105  StrTab.write(OS);
106  // Add padding to required image alignment.
107  OS.write_zeros(TheEntry.ImageOffset - OS.tell());
108  OS << OffloadingData.Image->getBuffer();
109 
110  // Add final padding to required alignment.
111  assert(TheHeader.Size >= OS.tell() && "Too much data written?");
112  OS.write_zeros(TheHeader.Size - OS.tell());
113  assert(TheHeader.Size == OS.tell() && "Size mismatch");
114 
115  return MemoryBuffer::getMemBufferCopy(OS.str());
116 }
117 
120  .Case("openmp", OFK_OpenMP)
121  .Case("cuda", OFK_Cuda)
122  .Case("hip", OFK_HIP)
123  .Default(OFK_None);
124 }
125 
127  switch (Kind) {
128  case OFK_OpenMP:
129  return "openmp";
130  case OFK_Cuda:
131  return "cuda";
132  case OFK_HIP:
133  return "hip";
134  default:
135  return "none";
136  }
137 }
138 
141  .Case("o", IMG_Object)
142  .Case("bc", IMG_Bitcode)
143  .Case("cubin", IMG_Cubin)
144  .Case("fatbin", IMG_Fatbinary)
145  .Case("s", IMG_PTX)
146  .Default(IMG_None);
147 }
148 
150  switch (Kind) {
151  case IMG_Object:
152  return "o";
153  case IMG_Bitcode:
154  return "bc";
155  case IMG_Cubin:
156  return "cubin";
157  case IMG_Fatbinary:
158  return "fatbin";
159  case IMG_PTX:
160  return "s";
161  default:
162  return "";
163  }
164 }
llvm::StringSwitch::Case
StringSwitch & Case(StringLiteral S, T Value)
Definition: StringSwitch.h:69
llvm::object::object_error::unexpected_eof
@ unexpected_eof
llvm::object::OFK_None
@ OFK_None
Definition: OffloadBinary.h:33
llvm::alignTo
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition: Alignment.h:156
llvm::raw_ostream::tell
uint64_t tell() const
tell - Return the current offset with the file.
Definition: raw_ostream.h:136
llvm::object::IMG_Fatbinary
@ IMG_Fatbinary
Definition: OffloadBinary.h:46
llvm::object::OffloadBinary::create
static Expected< std::unique_ptr< OffloadBinary > > create(MemoryBufferRef)
Attempt to parse the offloading binary stored in Data.
Definition: OffloadBinary.cpp:22
llvm::MemoryBufferRef::getBufferStart
const char * getBufferStart() const
Definition: MemoryBufferRef.h:35
llvm::object::Kind
Kind
Definition: COFFModuleDefinition.cpp:31
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:17
llvm::raw_ostream::write_zeros
raw_ostream & write_zeros(unsigned NumZeros)
write_zeros - Insert 'NumZeros' nulls.
Definition: raw_ostream.cpp:501
llvm::StringSwitch::Default
LLVM_NODISCARD R Default(T Value)
Definition: StringSwitch.h:183
llvm::object::OffloadBinary::OffloadingImage::TheImageKind
ImageKind TheImageKind
Definition: OffloadBinary.h:70
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1185
llvm::object::OffloadBinary::Header::EntryOffset
uint64_t EntryOffset
Definition: OffloadBinary.h:110
llvm::object::OffloadBinary::Entry::StringOffset
uint64_t StringOffset
Definition: OffloadBinary.h:118
llvm::file_magic::offload_binary
@ offload_binary
LLVM offload object file.
Definition: Magic.h:55
llvm::object::Binary::Data
MemoryBufferRef Data
Definition: Binary.h:37
llvm::object::OffloadBinary::Entry
Definition: OffloadBinary.h:114
llvm::MemoryBufferRef::getBufferSize
size_t getBufferSize() const
Definition: MemoryBufferRef.h:37
FileOutputBuffer.h
llvm::object::IMG_Bitcode
@ IMG_Bitcode
Definition: OffloadBinary.h:44
llvm::Expected
Tagged union holding either a T or a Error.
Definition: APFloat.h:41
llvm::StringTableBuilder::finalize
void finalize()
Analyze the strings and build the final table.
Definition: StringTableBuilder.cpp:128
llvm::StringTableBuilder::getOffset
size_t getOffset(CachedHashStringRef S) const
Get the offest of a string in the string table.
Definition: StringTableBuilder.cpp:194
llvm::object::OffloadBinary::OffloadingImage
The offloading metadata that will be serialized to a memory buffer.
Definition: OffloadBinary.h:69
llvm::object::OffloadBinary::OffloadingImage::Image
std::unique_ptr< MemoryBuffer > Image
Definition: OffloadBinary.h:74
llvm::MemoryBufferRef
Definition: MemoryBufferRef.h:22
llvm::object::getOffloadKind
OffloadKind getOffloadKind(StringRef Name)
Convert a string Name to an offload kind.
Definition: OffloadBinary.cpp:118
llvm::object::OffloadBinary::StringEntry
Definition: OffloadBinary.h:124
llvm::object::OffloadBinary::Header::Size
uint64_t Size
Definition: OffloadBinary.h:109
llvm::object::OffloadBinary::Header::Version
uint32_t Version
Definition: OffloadBinary.h:108
llvm::object::OffloadBinary::write
static std::unique_ptr< MemoryBuffer > write(const OffloadingImage &)
Serialize the contents of File to a binary buffer to be read later.
Definition: OffloadBinary.cpp:56
StringTableBuilder.h
llvm::object
Definition: DWARFDebugLoc.h:25
Error.h
llvm::object::IMG_PTX
@ IMG_PTX
Definition: OffloadBinary.h:47
Magic.h
llvm::object::OffloadBinary::Entry::TheOffloadKind
OffloadKind TheOffloadKind
Definition: OffloadBinary.h:116
llvm::object::OffloadBinary::Entry::ImageOffset
uint64_t ImageOffset
Definition: OffloadBinary.h:120
llvm::object::OffloadBinary::Entry::TheImageKind
ImageKind TheImageKind
Definition: OffloadBinary.h:115
llvm::errorCodeToError
Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
Definition: Error.cpp:90
llvm::StringTableBuilder::getSize
size_t getSize() const
Definition: StringTableBuilder.h:82
llvm::object::object_error::parse_failed
@ parse_failed
llvm::object::OffloadBinary::OffloadingImage::StringData
StringMap< StringRef > StringData
Definition: OffloadBinary.h:73
llvm::object::OFK_OpenMP
@ OFK_OpenMP
Definition: OffloadBinary.h:34
Align
uint64_t Align
Definition: ELFObjHandler.cpp:81
llvm::object::OffloadBinary::Entry::ImageSize
uint64_t ImageSize
Definition: OffloadBinary.h:121
llvm::object::OffloadBinary
A simple binary serialization of an offloading file.
Definition: OffloadBinary.h:60
llvm::object::OffloadBinary::getAlignment
static uint64_t getAlignment()
Definition: OffloadBinary.h:83
llvm::object::OffloadKind
OffloadKind
The producer of the associated offloading image.
Definition: OffloadBinary.h:32
uint64_t
llvm::object::OffloadBinary::OffloadingImage::TheOffloadKind
OffloadKind TheOffloadKind
Definition: OffloadBinary.h:71
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::object::OFK_Cuda
@ OFK_Cuda
Definition: OffloadBinary.h:35
llvm::MemoryBufferRef::getBuffer
StringRef getBuffer() const
Definition: MemoryBufferRef.h:32
llvm::StringTableBuilder::write
void write(raw_ostream &OS) const
Definition: StringTableBuilder.cpp:60
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
llvm::raw_svector_ostream::str
StringRef str() const
Return a StringRef for the vector contents.
Definition: raw_ostream.h:687
llvm::object::IMG_Cubin
@ IMG_Cubin
Definition: OffloadBinary.h:45
OffloadBinary.h
llvm::object::OffloadBinary::Entry::NumStrings
uint64_t NumStrings
Definition: OffloadBinary.h:119
Alignment.h
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:50
llvm::object::IMG_Object
@ IMG_Object
Definition: OffloadBinary.h:43
llvm::object::getImageKindName
StringRef getImageKindName(ImageKind Name)
Convert an image kind to its string representation.
Definition: OffloadBinary.cpp:149
llvm::isAddrAligned
bool isAddrAligned(Align Lhs, const void *Addr)
Checks that Addr is a multiple of the alignment.
Definition: Alignment.h:151
llvm::StringTableBuilder::add
size_t add(CachedHashStringRef S)
Add a string to the builder.
Definition: StringTableBuilder.cpp:201
StringSwitch.h
llvm::StringTableBuilder
Utility for building string tables with deduplicated suffixes.
Definition: StringTableBuilder.h:23
llvm::object::OffloadBinary::OffloadingImage::Flags
uint32_t Flags
Definition: OffloadBinary.h:72
llvm::object::getOffloadKindName
StringRef getOffloadKindName(OffloadKind Name)
Convert an offload kind to its string representation.
Definition: OffloadBinary.cpp:126
llvm::object::OffloadBinary::Header
Definition: OffloadBinary.h:106
llvm::object::OffloadBinary::Version
static const uint32_t Version
The current version of the binary used for backwards compatibility.
Definition: OffloadBinary.h:66
llvm::object::IMG_None
@ IMG_None
Definition: OffloadBinary.h:42
llvm::StringTableBuilder::ELF
@ ELF
Definition: StringTableBuilder.h:26
llvm::raw_svector_ostream
A raw_ostream that writes to an SmallVector or SmallString.
Definition: raw_ostream.h:662
llvm::object::getImageKind
ImageKind getImageKind(StringRef Name)
Convert a string Name to an image kind.
Definition: OffloadBinary.cpp:139
llvm::StringSwitch
A switch()-like statement whose cases are string literals.
Definition: StringSwitch.h:44
llvm::object::OffloadBinary::Header::EntrySize
uint64_t EntrySize
Definition: OffloadBinary.h:111
llvm::object::OFK_HIP
@ OFK_HIP
Definition: OffloadBinary.h:36
llvm::object::OffloadBinary::Entry::Flags
uint32_t Flags
Definition: OffloadBinary.h:117
llvm::MemoryBuffer::getMemBufferCopy
static std::unique_ptr< MemoryBuffer > getMemBufferCopy(StringRef InputData, const Twine &BufferName="")
Open the specified memory range as a MemoryBuffer, copying the contents and taking ownership of it.
Definition: MemoryBuffer.cpp:138
llvm::identify_magic
file_magic identify_magic(StringRef magic)
Identify the type of a binary file based on how magical it is.
Definition: Magic.cpp:33
llvm::object::ImageKind
ImageKind
The type of contents the offloading image contains.
Definition: OffloadBinary.h:41