LLVM 20.0.0git
GOFFObjectFile.cpp
Go to the documentation of this file.
1//===- GOFFObjectFile.cpp - GOFF object file implementation -----*- 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//
9// Implementation of the GOFFObjectFile class.
10//
11//===----------------------------------------------------------------------===//
12
15#include "llvm/Object/GOFF.h"
16#include "llvm/Support/Debug.h"
17#include "llvm/Support/Errc.h"
19
20#ifndef DEBUG_TYPE
21#define DEBUG_TYPE "goff"
22#endif
23
24using namespace llvm::object;
25using namespace llvm;
26
29 Error Err = Error::success();
30 std::unique_ptr<GOFFObjectFile> Ret(new GOFFObjectFile(Object, Err));
31 if (Err)
32 return std::move(Err);
33 return std::move(Ret);
34}
35
37 : ObjectFile(Binary::ID_GOFF, Object) {
38 ErrorAsOutParameter ErrAsOutParam(Err);
39 // Object file isn't the right size, bail out early.
40 if ((Object.getBufferSize() % GOFF::RecordLength) != 0) {
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");
46 return;
47 }
48 // Object file doesn't start/end with HDR/END records.
49 // Bail out early.
50 if (Object.getBufferSize() != 0) {
51 if ((base()[1] & 0xF0) >> 4 != GOFF::RT_HDR) {
53 "object file must start with HDR record");
54 return;
55 }
56 if ((base()[Object.getBufferSize() - GOFF::RecordLength + 1] & 0xF0) >> 4 !=
59 "object file must end with END record");
60 return;
61 }
62 }
63
64 SectionEntryImpl DummySection;
65 SectionList.emplace_back(DummySection); // Dummy entry at index 0.
66
67 uint8_t PrevRecordType = 0;
68 uint8_t PrevContinuationBits = 0;
69 const uint8_t *End = reinterpret_cast<const uint8_t *>(Data.getBufferEnd());
70 for (const uint8_t *I = base(); I < End; I += GOFF::RecordLength) {
71 uint8_t RecordType = (I[1] & 0xF0) >> 4;
72 bool IsContinuation = I[1] & 0x02;
73 bool PrevWasContinued = PrevContinuationBits & 0x01;
74 size_t RecordNum = (I - base()) / GOFF::RecordLength;
75
76 // If the previous record was continued, the current record should be a
77 // continuation.
78 if (PrevWasContinued && !IsContinuation) {
79 if (PrevRecordType == RecordType) {
81 "record " + std::to_string(RecordNum) +
82 " is not a continuation record but the "
83 "preceding record is continued");
84 return;
85 }
86 }
87 // Don't parse continuations records, only parse initial record.
88 if (IsContinuation) {
89 if (RecordType != PrevRecordType) {
91 "record " + std::to_string(RecordNum) +
92 " is a continuation record that does not "
93 "match the type of the previous record");
94 return;
95 }
96 if (!PrevWasContinued) {
98 "record " + std::to_string(RecordNum) +
99 " is a continuation record that is not "
100 "preceded by a continued record");
101 return;
102 }
103 PrevRecordType = RecordType;
104 PrevContinuationBits = I[1] & 0x03;
105 continue;
106 }
107 LLVM_DEBUG(for (size_t J = 0; J < GOFF::RecordLength; ++J) {
108 const uint8_t *P = I + J;
109 if (J % 8 == 0)
110 dbgs() << " ";
111 dbgs() << format("%02hhX", *P);
112 });
113
114 switch (RecordType) {
115 case GOFF::RT_ESD: {
116 // Save ESD record.
117 uint32_t EsdId;
118 ESDRecord::getEsdId(I, EsdId);
119 EsdPtrs.grow(EsdId);
120 EsdPtrs[EsdId] = I;
121
122 // Determine and save the "sections" in GOFF.
123 // A section is saved as a tuple of the form
124 // case (1): (ED,child PR)
125 // - where the PR must have non-zero length.
126 // case (2a) (ED,0)
127 // - where the ED is of non-zero length.
128 // case (2b) (ED,0)
129 // - where the ED is zero length but
130 // contains a label (LD).
133 SectionEntryImpl Section;
137 // case (2a)
138 if (Length != 0) {
139 Section.d.a = EsdId;
140 SectionList.emplace_back(Section);
141 }
143 // case (1)
144 if (Length != 0) {
145 uint32_t SymEdId;
147 Section.d.a = SymEdId;
148 Section.d.b = EsdId;
149 SectionList.emplace_back(Section);
150 }
152 // case (2b)
153 uint32_t SymEdId;
155 const uint8_t *SymEdRecord = EsdPtrs[SymEdId];
156 uint32_t EdLength;
157 ESDRecord::getLength(SymEdRecord, EdLength);
158 if (!EdLength) { // [ EDID, PRID ]
159 // LD child of a zero length parent ED.
160 // Add the section ED which was previously ignored.
161 Section.d.a = SymEdId;
162 SectionList.emplace_back(Section);
163 }
164 }
165 LLVM_DEBUG(dbgs() << " -- ESD " << EsdId << "\n");
166 break;
167 }
168 case GOFF::RT_TXT:
169 // Save TXT records.
170 TextPtrs.emplace_back(I);
171 LLVM_DEBUG(dbgs() << " -- TXT\n");
172 break;
173 case GOFF::RT_END:
174 LLVM_DEBUG(dbgs() << " -- END (GOFF record type) unhandled\n");
175 break;
176 case GOFF::RT_HDR:
177 LLVM_DEBUG(dbgs() << " -- HDR (GOFF record type) unhandled\n");
178 break;
179 default:
180 llvm_unreachable("Unknown record type");
181 }
182 PrevRecordType = RecordType;
183 PrevContinuationBits = I[1] & 0x03;
184 }
185}
186
187const uint8_t *GOFFObjectFile::getSymbolEsdRecord(DataRefImpl Symb) const {
188 const uint8_t *EsdRecord = EsdPtrs[Symb.d.a];
189 return EsdRecord;
190}
191
193 if (EsdNamesCache.count(Symb.d.a)) {
194 auto &StrPtr = EsdNamesCache[Symb.d.a];
195 return StringRef(StrPtr.second.get(), StrPtr.first);
196 }
197
198 SmallString<256> SymbolName;
199 if (auto Err = ESDRecord::getData(getSymbolEsdRecord(Symb), SymbolName))
200 return std::move(Err);
201
202 SmallString<256> SymbolNameConverted;
203 ConverterEBCDIC::convertToUTF8(SymbolName, SymbolNameConverted);
204
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);
210 return StringRef(Buf, Size);
211}
212
214 return getSymbolName(Symbol.getRawDataRefImpl());
215}
216
217Expected<uint64_t> GOFFObjectFile::getSymbolAddress(DataRefImpl Symb) const {
219 const uint8_t *EsdRecord = getSymbolEsdRecord(Symb);
220 ESDRecord::getOffset(EsdRecord, Offset);
221 return static_cast<uint64_t>(Offset);
222}
223
224uint64_t GOFFObjectFile::getSymbolValueImpl(DataRefImpl Symb) const {
226 const uint8_t *EsdRecord = getSymbolEsdRecord(Symb);
227 ESDRecord::getOffset(EsdRecord, Offset);
228 return static_cast<uint64_t>(Offset);
229}
230
231uint64_t GOFFObjectFile::getCommonSymbolSizeImpl(DataRefImpl Symb) const {
232 return 0;
233}
234
235bool GOFFObjectFile::isSymbolUnresolved(DataRefImpl Symb) const {
236 const uint8_t *Record = getSymbolEsdRecord(Symb);
239
241 return true;
245 if (Length == 0)
246 return true;
247 }
248 return false;
249}
250
251bool GOFFObjectFile::isSymbolIndirect(DataRefImpl Symb) const {
252 const uint8_t *Record = getSymbolEsdRecord(Symb);
253 bool Indirect;
255 return Indirect;
256}
257
258Expected<uint32_t> GOFFObjectFile::getSymbolFlags(DataRefImpl Symb) const {
259 uint32_t Flags = 0;
260 if (isSymbolUnresolved(Symb))
262
263 const uint8_t *Record = getSymbolEsdRecord(Symb);
264
265 GOFF::ESDBindingStrength BindingStrength;
266 ESDRecord::getBindingStrength(Record, BindingStrength);
267 if (BindingStrength == GOFF::ESD_BST_Weak)
269
270 GOFF::ESDBindingScope BindingScope;
271 ESDRecord::getBindingScope(Record, BindingScope);
272
273 if (BindingScope != GOFF::ESD_BSC_Section) {
275 if (Name && *Name != " ") { // Blank name is local.
277 if (BindingScope == GOFF::ESD_BSC_ImportExport)
279 else if (!(Flags & SymbolRef::SF_Undefined))
281 }
282 }
283
284 return Flags;
285}
286
288GOFFObjectFile::getSymbolType(DataRefImpl Symb) const {
289 const uint8_t *Record = getSymbolEsdRecord(Symb);
292 GOFF::ESDExecutable Executable;
293 ESDRecord::getExecutable(Record, Executable);
294
300 uint32_t EsdId;
303 "ESD record %" PRIu32
304 " has invalid symbol type 0x%02" PRIX8,
305 EsdId, SymbolType);
306 }
307 switch (SymbolType) {
310 return SymbolRef::ST_Other;
314 if (Executable != GOFF::ESD_EXE_CODE && Executable != GOFF::ESD_EXE_DATA &&
315 Executable != GOFF::ESD_EXE_Unspecified) {
316 uint32_t EsdId;
319 "ESD record %" PRIu32
320 " has unknown Executable type 0x%02X",
321 EsdId, Executable);
322 }
323 switch (Executable) {
327 return SymbolRef::ST_Data;
330 }
331 llvm_unreachable("Unhandled ESDExecutable");
332 }
333 llvm_unreachable("Unhandled ESDSymbolType");
334}
335
337GOFFObjectFile::getSymbolSection(DataRefImpl Symb) const {
338 DataRefImpl Sec;
339
340 if (isSymbolUnresolved(Symb))
341 return section_iterator(SectionRef(Sec, this));
342
343 const uint8_t *SymEsdRecord = EsdPtrs[Symb.d.a];
344 uint32_t SymEdId;
345 ESDRecord::getParentEsdId(SymEsdRecord, SymEdId);
346 const uint8_t *SymEdRecord = EsdPtrs[SymEdId];
347
348 for (size_t I = 0, E = SectionList.size(); I < E; ++I) {
349 bool Found;
350 const uint8_t *SectionPrRecord = getSectionPrEsdRecord(I);
351 if (SectionPrRecord) {
352 Found = SymEsdRecord == SectionPrRecord;
353 } else {
354 const uint8_t *SectionEdRecord = getSectionEdEsdRecord(I);
355 Found = SymEdRecord == SectionEdRecord;
356 }
357
358 if (Found) {
359 Sec.d.a = I;
360 return section_iterator(SectionRef(Sec, this));
361 }
362 }
364 "symbol with ESD id " + std::to_string(Symb.d.a) +
365 " refers to invalid section with ESD id " +
366 std::to_string(SymEdId));
367}
368
369uint64_t GOFFObjectFile::getSymbolSize(DataRefImpl Symb) const {
370 const uint8_t *Record = getSymbolEsdRecord(Symb);
373 return Length;
374}
375
376const uint8_t *GOFFObjectFile::getSectionEdEsdRecord(DataRefImpl &Sec) const {
377 SectionEntryImpl EsdIds = SectionList[Sec.d.a];
378 const uint8_t *EsdRecord = EsdPtrs[EsdIds.d.a];
379 return EsdRecord;
380}
381
382const uint8_t *GOFFObjectFile::getSectionPrEsdRecord(DataRefImpl &Sec) const {
383 SectionEntryImpl EsdIds = SectionList[Sec.d.a];
384 const uint8_t *EsdRecord = nullptr;
385 if (EsdIds.d.b)
386 EsdRecord = EsdPtrs[EsdIds.d.b];
387 return EsdRecord;
388}
389
390const uint8_t *
391GOFFObjectFile::getSectionEdEsdRecord(uint32_t SectionIndex) const {
392 DataRefImpl Sec;
393 Sec.d.a = SectionIndex;
394 const uint8_t *EsdRecord = getSectionEdEsdRecord(Sec);
395 return EsdRecord;
396}
397
398const uint8_t *
399GOFFObjectFile::getSectionPrEsdRecord(uint32_t SectionIndex) const {
400 DataRefImpl Sec;
401 Sec.d.a = SectionIndex;
402 const uint8_t *EsdRecord = getSectionPrEsdRecord(Sec);
403 return EsdRecord;
404}
405
406uint32_t GOFFObjectFile::getSectionDefEsdId(DataRefImpl &Sec) const {
407 const uint8_t *EsdRecord = getSectionEdEsdRecord(Sec);
409 ESDRecord::getLength(EsdRecord, Length);
410 if (Length == 0) {
411 const uint8_t *PrEsdRecord = getSectionPrEsdRecord(Sec);
412 if (PrEsdRecord)
413 EsdRecord = PrEsdRecord;
414 }
415
416 uint32_t DefEsdId;
417 ESDRecord::getEsdId(EsdRecord, DefEsdId);
418 LLVM_DEBUG(dbgs() << "Got def EsdId: " << DefEsdId << '\n');
419 return DefEsdId;
420}
421
422void GOFFObjectFile::moveSectionNext(DataRefImpl &Sec) const {
423 Sec.d.a++;
424 if ((Sec.d.a) >= SectionList.size())
425 Sec.d.a = 0;
426}
427
428Expected<StringRef> GOFFObjectFile::getSectionName(DataRefImpl Sec) const {
429 DataRefImpl EdSym;
430 SectionEntryImpl EsdIds = SectionList[Sec.d.a];
431 EdSym.d.a = EsdIds.d.a;
433 if (Name) {
434 StringRef Res = *Name;
435 LLVM_DEBUG(dbgs() << "Got section: " << Res << '\n');
436 LLVM_DEBUG(dbgs() << "Final section name: " << Res << '\n');
437 Name = Res;
438 }
439 return Name;
440}
441
442uint64_t GOFFObjectFile::getSectionAddress(DataRefImpl Sec) const {
444 const uint8_t *EsdRecord = getSectionEdEsdRecord(Sec);
445 ESDRecord::getOffset(EsdRecord, Offset);
446 return Offset;
447}
448
449uint64_t GOFFObjectFile::getSectionSize(DataRefImpl Sec) const {
451 uint32_t DefEsdId = getSectionDefEsdId(Sec);
452 const uint8_t *EsdRecord = EsdPtrs[DefEsdId];
453 ESDRecord::getLength(EsdRecord, Length);
454 LLVM_DEBUG(dbgs() << "Got section size: " << Length << '\n');
455 return static_cast<uint64_t>(Length);
456}
457
458// Unravel TXT records and expand fill characters to produce
459// a contiguous sequence of bytes.
461GOFFObjectFile::getSectionContents(DataRefImpl Sec) const {
462 if (SectionDataCache.count(Sec.d.a)) {
463 auto &Buf = SectionDataCache[Sec.d.a];
464 return ArrayRef<uint8_t>(Buf);
465 }
466 uint64_t SectionSize = getSectionSize(Sec);
467 uint32_t DefEsdId = getSectionDefEsdId(Sec);
468
469 const uint8_t *EdEsdRecord = getSectionEdEsdRecord(Sec);
470 bool FillBytePresent;
471 ESDRecord::getFillBytePresent(EdEsdRecord, FillBytePresent);
472 uint8_t FillByte = '\0';
473 if (FillBytePresent)
474 ESDRecord::getFillByteValue(EdEsdRecord, FillByte);
475
476 // Initialize section with fill byte.
477 SmallVector<uint8_t> Data(SectionSize, FillByte);
478
479 // Replace section with content from text records.
480 for (const uint8_t *TxtRecordInt : TextPtrs) {
481 const uint8_t *TxtRecordPtr = TxtRecordInt;
482 uint32_t TxtEsdId;
483 TXTRecord::getElementEsdId(TxtRecordPtr, TxtEsdId);
484 LLVM_DEBUG(dbgs() << "Got txt EsdId: " << TxtEsdId << '\n');
485
486 if (TxtEsdId != DefEsdId)
487 continue;
488
489 uint32_t TxtDataOffset;
490 TXTRecord::getOffset(TxtRecordPtr, TxtDataOffset);
491
492 uint16_t TxtDataSize;
493 TXTRecord::getDataLength(TxtRecordPtr, TxtDataSize);
494
495 LLVM_DEBUG(dbgs() << "Record offset " << TxtDataOffset << ", data size "
496 << TxtDataSize << "\n");
497
498 SmallString<256> CompleteData;
499 CompleteData.reserve(TxtDataSize);
500 if (Error Err = TXTRecord::getData(TxtRecordPtr, CompleteData))
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);
505 }
506 SectionDataCache[Sec.d.a] = Data;
507 return ArrayRef<uint8_t>(SectionDataCache[Sec.d.a]);
508}
509
510uint64_t GOFFObjectFile::getSectionAlignment(DataRefImpl Sec) const {
511 const uint8_t *EsdRecord = getSectionEdEsdRecord(Sec);
512 GOFF::ESDAlignment Pow2Alignment;
513 ESDRecord::getAlignment(EsdRecord, Pow2Alignment);
514 return 1ULL << static_cast<uint64_t>(Pow2Alignment);
515}
516
517bool GOFFObjectFile::isSectionText(DataRefImpl Sec) const {
518 const uint8_t *EsdRecord = getSectionEdEsdRecord(Sec);
519 GOFF::ESDExecutable Executable;
520 ESDRecord::getExecutable(EsdRecord, Executable);
521 return Executable == GOFF::ESD_EXE_CODE;
522}
523
524bool GOFFObjectFile::isSectionData(DataRefImpl Sec) const {
525 const uint8_t *EsdRecord = getSectionEdEsdRecord(Sec);
526 GOFF::ESDExecutable Executable;
527 ESDRecord::getExecutable(EsdRecord, Executable);
528 return Executable == GOFF::ESD_EXE_DATA;
529}
530
532 const uint8_t *EsdRecord = getSectionEdEsdRecord(Sec);
533 GOFF::ESDLoadingBehavior LoadingBehavior;
534 ESDRecord::getLoadingBehavior(EsdRecord, LoadingBehavior);
535 return LoadingBehavior == GOFF::ESD_LB_NoLoad;
536}
537
539 if (!isSectionData(Sec))
540 return false;
541
542 const uint8_t *EsdRecord = getSectionEdEsdRecord(Sec);
543 GOFF::ESDLoadingBehavior LoadingBehavior;
544 ESDRecord::getLoadingBehavior(EsdRecord, LoadingBehavior);
545 return LoadingBehavior == GOFF::ESD_LB_Initial;
546}
547
549 // GOFF uses fill characters and fill characters are applied
550 // on getSectionContents() - so we say false to zero init.
551 return false;
552}
553
555 DataRefImpl Sec;
556 moveSectionNext(Sec);
557 return section_iterator(SectionRef(Sec, this));
558}
559
561 DataRefImpl Sec;
562 return section_iterator(SectionRef(Sec, this));
563}
564
566 for (uint32_t I = Symb.d.a + 1, E = EsdPtrs.size(); I < E; ++I) {
567 if (EsdPtrs[I]) {
568 const uint8_t *EsdRecord = EsdPtrs[I];
571 // Skip EDs - i.e. section symbols.
572 bool IgnoreSpecialGOFFSymbols = true;
573 bool SkipSymbol = ((SymbolType == GOFF::ESD_ST_ElementDefinition) ||
575 IgnoreSpecialGOFFSymbols;
576 if (!SkipSymbol) {
577 Symb.d.a = I;
578 return;
579 }
580 }
581 }
582 Symb.d.a = 0;
583}
584
586 DataRefImpl Symb;
587 moveSymbolNext(Symb);
588 return basic_symbol_iterator(SymbolRef(Symb, this));
589}
590
592 DataRefImpl Symb;
593 return basic_symbol_iterator(SymbolRef(Symb, this));
594}
595
597 int DataIndex, SmallString<256> &CompleteData) {
598 // First record.
599 const uint8_t *Slice = Record + DataIndex;
600 size_t SliceLength =
601 std::min(DataLength, (uint16_t)(GOFF::RecordLength - DataIndex));
602 CompleteData.append(Slice, Slice + SliceLength);
603 DataLength -= SliceLength;
604 Slice += SliceLength;
605
606 // Continuation records.
607 for (; DataLength > 0;
608 DataLength -= SliceLength, Slice += GOFF::PayloadLength) {
609 // Slice points to the start of the new record.
610 // Check that this block is a Continuation.
611 assert(Record::isContinuation(Slice) && "Continuation bit must be set");
612 // Check that the last Continuation is terminated correctly.
613 if (DataLength <= 77 && Record::isContinued(Slice))
615 "continued bit should not be set");
616
617 SliceLength = std::min(DataLength, (uint16_t)GOFF::PayloadLength);
619 CompleteData.append(Slice, Slice + SliceLength);
620 }
621 return Error::success();
622}
623
625 SmallString<256> &CompleteData) {
627 return getContinuousData(Record, Length, 60, CompleteData);
628}
629
631 SmallString<256> &CompleteData) {
632 uint16_t DataSize = getNameLength(Record);
633 return getContinuousData(Record, DataSize, 72, CompleteData);
634}
635
637 SmallString<256> &CompleteData) {
640 return getContinuousData(Record, Length, 24, CompleteData);
641}
642
644 SmallString<256> &CompleteData) {
646 return getContinuousData(Record, Length, 26, CompleteData);
647}
#define LLVM_DEBUG(...)
Definition: Debug.h:106
std::string Name
uint64_t Size
bool End
Definition: ELF_riscv.cpp:480
#define I(x, y, z)
Definition: MD5.cpp:58
#define P(N)
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),...
Definition: ArrayRef.h:41
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
Definition: DenseMap.h:152
Helper for Errors used as out-parameters.
Definition: Error.h:1130
Lightweight error class with error context and mandatory checking.
Definition: Error.h:160
static ErrorSuccess success()
Create a success value.
Definition: Error.h:337
Tagged union holding either a T or a Error.
Definition: Error.h:481
StorageT::size_type size() const
Definition: IndexedMap.h:79
void grow(IndexT n)
Definition: IndexedMap.h:69
const char * getBufferEnd() const
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition: SmallString.h:26
void append(StringRef RHS)
Append from a StringRef.
Definition: SmallString.h:68
size_t size() const
Definition: SmallVector.h:78
reference emplace_back(ArgTypes &&... Args)
Definition: SmallVector.h:937
void reserve(size_type N)
Definition: SmallVector.h:663
pointer data()
Return a pointer to the vector's buffer, even if empty().
Definition: SmallVector.h:286
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1196
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:51
MemoryBufferRef Data
Definition: Binary.h:37
static Error getData(const uint8_t *Record, SmallString< 256 > &CompleteData)
static uint16_t getNameLength(const uint8_t *Record)
Definition: GOFF.h:293
static void getIndirectReference(const uint8_t *Record, bool &Indirect)
Definition: GOFF.h:255
static void getBindingStrength(const uint8_t *Record, GOFF::ESDBindingStrength &Strength)
Definition: GOFF.h:241
static void getOffset(const uint8_t *Record, uint32_t &Offset)
Definition: GOFF.h:139
static void getEsdId(const uint8_t *Record, uint32_t &EsdId)
Definition: GOFF.h:131
static void getLoadingBehavior(const uint8_t *Record, GOFF::ESDLoadingBehavior &Behavior)
Definition: GOFF.h:248
static Error getData(const uint8_t *Record, SmallString< 256 > &CompleteData)
static void getFillBytePresent(const uint8_t *Record, bool &Present)
Definition: GOFF.h:153
static void getLength(const uint8_t *Record, uint32_t &Length)
Definition: GOFF.h:143
static void getParentEsdId(const uint8_t *Record, uint32_t &EsdId)
Definition: GOFF.h:135
static void getFillByteValue(const uint8_t *Record, uint8_t &Fill)
Definition: GOFF.h:177
static void getSymbolType(const uint8_t *Record, GOFF::ESDSymbolType &SymbolType)
Definition: GOFF.h:124
static void getAlignment(const uint8_t *Record, GOFF::ESDAlignment &Alignment)
Definition: GOFF.h:275
static uint16_t getNameLength(const uint8_t *Record)
Definition: GOFF.h:282
static void getExecutable(const uint8_t *Record, GOFF::ESDExecutable &Executable)
Definition: GOFF.h:227
static void getBindingScope(const uint8_t *Record, GOFF::ESDBindingScope &Scope)
Definition: GOFF.h:261
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)
Definition: GOFF.h:100
This class is the base class for all object file types.
Definition: ObjectFile.h:229
friend class SymbolRef
Definition: ObjectFile.h:247
friend class SectionRef
Definition: ObjectFile.h:261
const uint8_t * base() const
Definition: ObjectFile.h:235
static Expected< std::unique_ptr< ObjectFile > > createGOFFObjectFile(MemoryBufferRef Object)
Represents a GOFF physical record.
Definition: GOFF.h:31
static bool isContinued(const uint8_t *Record)
Definition: GOFF.h:36
static Error getContinuousData(const uint8_t *Record, uint16_t DataLength, int DataIndex, SmallString< 256 > &CompleteData)
static bool isContinuation(const uint8_t *Record)
Definition: GOFF.h:42
This is a value type class that represents a single symbol in the list of symbols in the object file.
Definition: ObjectFile.h:168
static void getElementEsdId(const uint8_t *Record, uint32_t &EsdId)
Definition: GOFF.h:83
static void getDataLength(const uint8_t *Record, uint16_t &Length)
Definition: GOFF.h:91
static Error getData(const uint8_t *Record, SmallString< 256 > &CompleteData)
static void getOffset(const uint8_t *Record, uint32_t &Offset)
Definition: GOFF.h:87
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ SectionSize
Definition: COFF.h:60
void convertToUTF8(StringRef Source, SmallVectorImpl< char > &Result)
ESDLoadingBehavior
Definition: GOFF.h:127
@ ESD_LB_NoLoad
Definition: GOFF.h:130
@ ESD_LB_Initial
Definition: GOFF.h:128
@ RT_TXT
Definition: GOFF.h:46
@ RT_ESD
Definition: GOFF.h:45
@ RT_HDR
Definition: GOFF.h:50
@ RT_END
Definition: GOFF.h:49
constexpr uint8_t RecordPrefixLength
Definition: GOFF.h:29
constexpr uint8_t PayloadLength
Definition: GOFF.h:30
ESDExecutable
Definition: GOFF.h:109
@ ESD_EXE_Unspecified
Definition: GOFF.h:110
@ ESD_EXE_CODE
Definition: GOFF.h:112
@ ESD_EXE_DATA
Definition: GOFF.h:111
ESDAlignment
Definition: GOFF.h:144
ESDBindingScope
Definition: GOFF.h:134
@ ESD_BSC_ImportExport
Definition: GOFF.h:139
@ ESD_BSC_Section
Definition: GOFF.h:136
constexpr uint8_t RecordLength
Length of the parts of a physical GOFF record.
Definition: GOFF.h:28
ESDSymbolType
Definition: GOFF.h:53
@ ESD_ST_PartReference
Definition: GOFF.h:57
@ ESD_ST_ElementDefinition
Definition: GOFF.h:55
@ ESD_ST_LabelDefinition
Definition: GOFF.h:56
@ ESD_ST_SectionDefinition
Definition: GOFF.h:54
@ ESD_ST_ExternalReference
Definition: GOFF.h:58
ESDBindingStrength
Definition: GOFF.h:122
@ ESD_BST_Weak
Definition: GOFF.h:124
content_iterator< SectionRef > section_iterator
Definition: ObjectFile.h:47
content_iterator< BasicSymbolRef > basic_symbol_iterator
Definition: SymbolicFile.h:143
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:480
@ Length
Definition: DWP.cpp:480
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition: Error.h:1291
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
Definition: Format.h:125
Helper object to track which of three possible relocation mechanisms are used for a particular value ...
struct llvm::object::DataRefImpl::@371 d