21#define DEBUG_TYPE "goff"
30 std::unique_ptr<GOFFObjectFile> Ret(
new GOFFObjectFile(Object, Err));
32 return std::move(Err);
33 return std::move(Ret);
43 "object file is not the right size. Must be a multiple "
44 "of 80 bytes, but is " +
45 std::to_string(Object.getBufferSize()) +
" bytes");
50 if (Object.getBufferSize() != 0) {
53 "object file must start with HDR record");
59 "object file must end with END record");
65 SectionList.emplace_back(DummySection);
68 uint8_t PrevContinuationBits = 0;
72 bool IsContinuation =
I[1] & 0x02;
73 bool PrevWasContinued = PrevContinuationBits & 0x01;
78 if (PrevWasContinued && !IsContinuation) {
81 "record " + std::to_string(RecordNum) +
82 " is not a continuation record but the "
83 "preceding record is continued");
91 "record " + std::to_string(RecordNum) +
92 " is a continuation record that does not "
93 "match the type of the previous record");
96 if (!PrevWasContinued) {
98 "record " + std::to_string(RecordNum) +
99 " is a continuation record that is not "
100 "preceded by a continued record");
104 PrevContinuationBits =
I[1] & 0x03;
140 SectionList.emplace_back(Section);
147 Section.d.a = SymEdId;
149 SectionList.emplace_back(Section);
155 const uint8_t *SymEdRecord = EsdPtrs[SymEdId];
161 Section.d.a = SymEdId;
162 SectionList.emplace_back(Section);
183 PrevContinuationBits =
I[1] & 0x03;
188 const uint8_t *EsdRecord = EsdPtrs[Symb.
d.
a];
193 if (EsdNamesCache.
count(Symb.
d.
a)) {
194 auto &StrPtr = EsdNamesCache[Symb.
d.
a];
195 return StringRef(StrPtr.second.get(), StrPtr.first);
200 return std::move(Err);
205 size_t Size = SymbolNameConverted.
size();
206 auto StrPtr = std::make_pair(
Size, std::make_unique<
char[]>(
Size));
207 char *Buf = StrPtr.second.get();
208 memcpy(Buf, SymbolNameConverted.
data(),
Size);
209 EsdNamesCache[Symb.
d.
a] = std::move(StrPtr);
219 const uint8_t *EsdRecord = getSymbolEsdRecord(Symb);
226 const uint8_t *EsdRecord = getSymbolEsdRecord(Symb);
235bool GOFFObjectFile::isSymbolUnresolved(
DataRefImpl Symb)
const {
251bool GOFFObjectFile::isSymbolIndirect(
DataRefImpl Symb)
const {
260 if (isSymbolUnresolved(Symb))
288GOFFObjectFile::getSymbolType(
DataRefImpl Symb)
const {
303 "ESD record %" PRIu32
304 " has invalid symbol type 0x%02" PRIX8,
319 "ESD record %" PRIu32
320 " has unknown Executable type 0x%02X",
323 switch (Executable) {
337GOFFObjectFile::getSymbolSection(
DataRefImpl Symb)
const {
340 if (isSymbolUnresolved(Symb))
343 const uint8_t *SymEsdRecord = EsdPtrs[Symb.
d.
a];
346 const uint8_t *SymEdRecord = EsdPtrs[SymEdId];
348 for (
size_t I = 0, E = SectionList.size();
I < E; ++
I) {
350 const uint8_t *SectionPrRecord = getSectionPrEsdRecord(
I);
351 if (SectionPrRecord) {
352 Found = SymEsdRecord == SectionPrRecord;
354 const uint8_t *SectionEdRecord = getSectionEdEsdRecord(
I);
355 Found = SymEdRecord == SectionEdRecord;
364 "symbol with ESD id " + std::to_string(Symb.
d.
a) +
365 " refers to invalid section with ESD id " +
366 std::to_string(SymEdId));
377 SectionEntryImpl EsdIds = SectionList[Sec.
d.
a];
378 const uint8_t *EsdRecord = EsdPtrs[EsdIds.d.a];
383 SectionEntryImpl EsdIds = SectionList[Sec.
d.
a];
384 const uint8_t *EsdRecord =
nullptr;
386 EsdRecord = EsdPtrs[EsdIds.d.b];
391GOFFObjectFile::getSectionEdEsdRecord(
uint32_t SectionIndex)
const {
393 Sec.
d.
a = SectionIndex;
394 const uint8_t *EsdRecord = getSectionEdEsdRecord(Sec);
399GOFFObjectFile::getSectionPrEsdRecord(
uint32_t SectionIndex)
const {
401 Sec.
d.
a = SectionIndex;
402 const uint8_t *EsdRecord = getSectionPrEsdRecord(Sec);
407 const uint8_t *EsdRecord = getSectionEdEsdRecord(Sec);
411 const uint8_t *PrEsdRecord = getSectionPrEsdRecord(Sec);
413 EsdRecord = PrEsdRecord;
422void GOFFObjectFile::moveSectionNext(
DataRefImpl &Sec)
const {
424 if ((Sec.
d.
a) >= SectionList.size())
430 SectionEntryImpl EsdIds = SectionList[Sec.
d.
a];
431 EdSym.
d.
a = EsdIds.d.a;
444 const uint8_t *EsdRecord = getSectionEdEsdRecord(Sec);
451 uint32_t DefEsdId = getSectionDefEsdId(Sec);
452 const uint8_t *EsdRecord = EsdPtrs[DefEsdId];
461GOFFObjectFile::getSectionContents(
DataRefImpl Sec)
const {
462 if (SectionDataCache.count(Sec.
d.
a)) {
463 auto &Buf = SectionDataCache[Sec.
d.
a];
467 uint32_t DefEsdId = getSectionDefEsdId(Sec);
469 const uint8_t *EdEsdRecord = getSectionEdEsdRecord(Sec);
470 bool FillBytePresent;
480 for (
const uint8_t *TxtRecordInt : TextPtrs) {
481 const uint8_t *TxtRecordPtr = TxtRecordInt;
486 if (TxtEsdId != DefEsdId)
495 LLVM_DEBUG(
dbgs() <<
"Record offset " << TxtDataOffset <<
", data size "
496 << TxtDataSize <<
"\n");
499 CompleteData.
reserve(TxtDataSize);
501 return std::move(Err);
502 assert(CompleteData.
size() == TxtDataSize &&
"Wrong length of data");
503 std::copy(CompleteData.
data(), CompleteData.
data() + TxtDataSize,
504 Data.begin() + TxtDataOffset);
506 SectionDataCache[Sec.
d.
a] =
Data;
511 const uint8_t *EsdRecord = getSectionEdEsdRecord(Sec);
514 return 1ULL <<
static_cast<uint64_t>(Pow2Alignment);
517bool GOFFObjectFile::isSectionText(
DataRefImpl Sec)
const {
518 const uint8_t *EsdRecord = getSectionEdEsdRecord(Sec);
524bool GOFFObjectFile::isSectionData(
DataRefImpl Sec)
const {
525 const uint8_t *EsdRecord = getSectionEdEsdRecord(Sec);
532 const uint8_t *EsdRecord = getSectionEdEsdRecord(Sec);
539 if (!isSectionData(Sec))
542 const uint8_t *EsdRecord = getSectionEdEsdRecord(Sec);
556 moveSectionNext(Sec);
568 const uint8_t *EsdRecord = EsdPtrs[
I];
572 bool IgnoreSpecialGOFFSymbols =
true;
575 IgnoreSpecialGOFFSymbols;
603 DataLength -= SliceLength;
604 Slice += SliceLength;
607 for (; DataLength > 0;
615 "continued bit should not be set");
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
FunctionLoweringInfo::StatepointRelocationRecord RecordType
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
Helper for Errors used as out-parameters.
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
StorageT::size_type size() const
const char * getBufferEnd() const
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
void append(StringRef RHS)
Append from a StringRef.
reference emplace_back(ArgTypes &&... Args)
void reserve(size_type N)
pointer data()
Return a pointer to the vector's buffer, even if empty().
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
static Error getData(const uint8_t *Record, SmallString< 256 > &CompleteData)
static uint16_t getNameLength(const uint8_t *Record)
static void getIndirectReference(const uint8_t *Record, bool &Indirect)
static void getBindingStrength(const uint8_t *Record, GOFF::ESDBindingStrength &Strength)
static void getOffset(const uint8_t *Record, uint32_t &Offset)
static void getEsdId(const uint8_t *Record, uint32_t &EsdId)
static void getLoadingBehavior(const uint8_t *Record, GOFF::ESDLoadingBehavior &Behavior)
static Error getData(const uint8_t *Record, SmallString< 256 > &CompleteData)
static void getFillBytePresent(const uint8_t *Record, bool &Present)
static void getLength(const uint8_t *Record, uint32_t &Length)
static void getParentEsdId(const uint8_t *Record, uint32_t &EsdId)
static void getFillByteValue(const uint8_t *Record, uint8_t &Fill)
static void getSymbolType(const uint8_t *Record, GOFF::ESDSymbolType &SymbolType)
static void getAlignment(const uint8_t *Record, GOFF::ESDAlignment &Alignment)
static uint16_t getNameLength(const uint8_t *Record)
static void getExecutable(const uint8_t *Record, GOFF::ESDExecutable &Executable)
static void getBindingScope(const uint8_t *Record, GOFF::ESDBindingScope &Scope)
section_iterator section_begin() const override
basic_symbol_iterator symbol_end() const override
GOFFObjectFile(MemoryBufferRef Object, Error &Err)
bool isSectionReadOnlyData(DataRefImpl Sec) const
bool isSectionNoLoad(DataRefImpl Sec) const
section_iterator section_end() const override
Expected< StringRef > getSymbolName(SymbolRef Symbol) const
void moveSymbolNext(DataRefImpl &Symb) const override
basic_symbol_iterator symbol_begin() const override
bool isSectionZeroInit(DataRefImpl Sec) const
static Error getData(const uint8_t *Record, SmallString< 256 > &CompleteData)
static uint16_t getPropertyModuleLength(const uint8_t *Record)
This class is the base class for all object file types.
const uint8_t * base() const
static Expected< std::unique_ptr< ObjectFile > > createGOFFObjectFile(MemoryBufferRef Object)
Represents a GOFF physical record.
static bool isContinued(const uint8_t *Record)
static Error getContinuousData(const uint8_t *Record, uint16_t DataLength, int DataIndex, SmallString< 256 > &CompleteData)
static bool isContinuation(const uint8_t *Record)
This is a value type class that represents a single symbol in the list of symbols in the object file.
static void getElementEsdId(const uint8_t *Record, uint32_t &EsdId)
static void getDataLength(const uint8_t *Record, uint16_t &Length)
static Error getData(const uint8_t *Record, SmallString< 256 > &CompleteData)
static void getOffset(const uint8_t *Record, uint32_t &Offset)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
void convertToUTF8(StringRef Source, SmallVectorImpl< char > &Result)
constexpr uint8_t RecordPrefixLength
constexpr uint8_t PayloadLength
constexpr uint8_t RecordLength
Length of the parts of a physical GOFF record.
@ ESD_ST_ElementDefinition
@ ESD_ST_SectionDefinition
@ ESD_ST_ExternalReference
content_iterator< SectionRef > section_iterator
content_iterator< BasicSymbolRef > basic_symbol_iterator
This is an optimization pass for GlobalISel generic memory operations.
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
Helper object to track which of three possible relocation mechanisms are used for a particular value ...
struct llvm::object::DataRefImpl::@371 d