xref: /llvm-project/llvm/lib/Object/GOFFObjectFile.cpp (revision 3f1be86a1acd5286bac16cae833481ee3f80dcbb)
12fa6bcf0SYusra Syeda //===- GOFFObjectFile.cpp - GOFF object file implementation -----*- C++ -*-===//
22fa6bcf0SYusra Syeda //
32fa6bcf0SYusra Syeda // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42fa6bcf0SYusra Syeda // See https://llvm.org/LICENSE.txt for license information.
52fa6bcf0SYusra Syeda // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
62fa6bcf0SYusra Syeda //
72fa6bcf0SYusra Syeda //===----------------------------------------------------------------------===//
82fa6bcf0SYusra Syeda //
92fa6bcf0SYusra Syeda // Implementation of the GOFFObjectFile class.
102fa6bcf0SYusra Syeda //
112fa6bcf0SYusra Syeda //===----------------------------------------------------------------------===//
122fa6bcf0SYusra Syeda 
132fa6bcf0SYusra Syeda #include "llvm/Object/GOFFObjectFile.h"
142fa6bcf0SYusra Syeda #include "llvm/BinaryFormat/GOFF.h"
152fa6bcf0SYusra Syeda #include "llvm/Object/GOFF.h"
162fa6bcf0SYusra Syeda #include "llvm/Support/Debug.h"
172fa6bcf0SYusra Syeda #include "llvm/Support/Errc.h"
182fa6bcf0SYusra Syeda #include "llvm/Support/raw_ostream.h"
192fa6bcf0SYusra Syeda 
202fa6bcf0SYusra Syeda #ifndef DEBUG_TYPE
212fa6bcf0SYusra Syeda #define DEBUG_TYPE "goff"
222fa6bcf0SYusra Syeda #endif
232fa6bcf0SYusra Syeda 
242fa6bcf0SYusra Syeda using namespace llvm::object;
252fa6bcf0SYusra Syeda using namespace llvm;
262fa6bcf0SYusra Syeda 
272fa6bcf0SYusra Syeda Expected<std::unique_ptr<ObjectFile>>
282fa6bcf0SYusra Syeda ObjectFile::createGOFFObjectFile(MemoryBufferRef Object) {
292fa6bcf0SYusra Syeda   Error Err = Error::success();
302fa6bcf0SYusra Syeda   std::unique_ptr<GOFFObjectFile> Ret(new GOFFObjectFile(Object, Err));
312fa6bcf0SYusra Syeda   if (Err)
322fa6bcf0SYusra Syeda     return std::move(Err);
332fa6bcf0SYusra Syeda   return std::move(Ret);
342fa6bcf0SYusra Syeda }
352fa6bcf0SYusra Syeda 
362fa6bcf0SYusra Syeda GOFFObjectFile::GOFFObjectFile(MemoryBufferRef Object, Error &Err)
372fa6bcf0SYusra Syeda     : ObjectFile(Binary::ID_GOFF, Object) {
38d02c1676SLang Hames   ErrorAsOutParameter ErrAsOutParam(Err);
392fa6bcf0SYusra Syeda   // Object file isn't the right size, bail out early.
402fa6bcf0SYusra Syeda   if ((Object.getBufferSize() % GOFF::RecordLength) != 0) {
412fa6bcf0SYusra Syeda     Err = createStringError(
422fa6bcf0SYusra Syeda         object_error::unexpected_eof,
432fa6bcf0SYusra Syeda         "object file is not the right size. Must be a multiple "
442fa6bcf0SYusra Syeda         "of 80 bytes, but is " +
452fa6bcf0SYusra Syeda             std::to_string(Object.getBufferSize()) + " bytes");
462fa6bcf0SYusra Syeda     return;
472fa6bcf0SYusra Syeda   }
482fa6bcf0SYusra Syeda   // Object file doesn't start/end with HDR/END records.
492fa6bcf0SYusra Syeda   // Bail out early.
502fa6bcf0SYusra Syeda   if (Object.getBufferSize() != 0) {
512fa6bcf0SYusra Syeda     if ((base()[1] & 0xF0) >> 4 != GOFF::RT_HDR) {
522fa6bcf0SYusra Syeda       Err = createStringError(object_error::parse_failed,
532fa6bcf0SYusra Syeda                               "object file must start with HDR record");
542fa6bcf0SYusra Syeda       return;
552fa6bcf0SYusra Syeda     }
562fa6bcf0SYusra Syeda     if ((base()[Object.getBufferSize() - GOFF::RecordLength + 1] & 0xF0) >> 4 !=
572fa6bcf0SYusra Syeda         GOFF::RT_END) {
582fa6bcf0SYusra Syeda       Err = createStringError(object_error::parse_failed,
592fa6bcf0SYusra Syeda                               "object file must end with END record");
602fa6bcf0SYusra Syeda       return;
612fa6bcf0SYusra Syeda     }
622fa6bcf0SYusra Syeda   }
632fa6bcf0SYusra Syeda 
642fa6bcf0SYusra Syeda   SectionEntryImpl DummySection;
652fa6bcf0SYusra Syeda   SectionList.emplace_back(DummySection); // Dummy entry at index 0.
662fa6bcf0SYusra Syeda 
672fa6bcf0SYusra Syeda   uint8_t PrevRecordType = 0;
682fa6bcf0SYusra Syeda   uint8_t PrevContinuationBits = 0;
692fa6bcf0SYusra Syeda   const uint8_t *End = reinterpret_cast<const uint8_t *>(Data.getBufferEnd());
702fa6bcf0SYusra Syeda   for (const uint8_t *I = base(); I < End; I += GOFF::RecordLength) {
712fa6bcf0SYusra Syeda     uint8_t RecordType = (I[1] & 0xF0) >> 4;
722fa6bcf0SYusra Syeda     bool IsContinuation = I[1] & 0x02;
732fa6bcf0SYusra Syeda     bool PrevWasContinued = PrevContinuationBits & 0x01;
742fa6bcf0SYusra Syeda     size_t RecordNum = (I - base()) / GOFF::RecordLength;
752fa6bcf0SYusra Syeda 
762fa6bcf0SYusra Syeda     // If the previous record was continued, the current record should be a
772fa6bcf0SYusra Syeda     // continuation.
782fa6bcf0SYusra Syeda     if (PrevWasContinued && !IsContinuation) {
792fa6bcf0SYusra Syeda       if (PrevRecordType == RecordType) {
802fa6bcf0SYusra Syeda         Err = createStringError(object_error::parse_failed,
812fa6bcf0SYusra Syeda                                 "record " + std::to_string(RecordNum) +
822fa6bcf0SYusra Syeda                                     " is not a continuation record but the "
832fa6bcf0SYusra Syeda                                     "preceding record is continued");
842fa6bcf0SYusra Syeda         return;
852fa6bcf0SYusra Syeda       }
862fa6bcf0SYusra Syeda     }
872fa6bcf0SYusra Syeda     // Don't parse continuations records, only parse initial record.
882fa6bcf0SYusra Syeda     if (IsContinuation) {
892fa6bcf0SYusra Syeda       if (RecordType != PrevRecordType) {
902fa6bcf0SYusra Syeda         Err = createStringError(object_error::parse_failed,
912fa6bcf0SYusra Syeda                                 "record " + std::to_string(RecordNum) +
922fa6bcf0SYusra Syeda                                     " is a continuation record that does not "
932fa6bcf0SYusra Syeda                                     "match the type of the previous record");
942fa6bcf0SYusra Syeda         return;
952fa6bcf0SYusra Syeda       }
962fa6bcf0SYusra Syeda       if (!PrevWasContinued) {
972fa6bcf0SYusra Syeda         Err = createStringError(object_error::parse_failed,
982fa6bcf0SYusra Syeda                                 "record " + std::to_string(RecordNum) +
992fa6bcf0SYusra Syeda                                     " is a continuation record that is not "
1002fa6bcf0SYusra Syeda                                     "preceded by a continued record");
1012fa6bcf0SYusra Syeda         return;
1022fa6bcf0SYusra Syeda       }
1032fa6bcf0SYusra Syeda       PrevRecordType = RecordType;
1042fa6bcf0SYusra Syeda       PrevContinuationBits = I[1] & 0x03;
1052fa6bcf0SYusra Syeda       continue;
1062fa6bcf0SYusra Syeda     }
1076634c3e9SKai Nacke     LLVM_DEBUG(for (size_t J = 0; J < GOFF::RecordLength; ++J) {
1082fa6bcf0SYusra Syeda       const uint8_t *P = I + J;
1092fa6bcf0SYusra Syeda       if (J % 8 == 0)
11078ceb39bSNAKAMURA Takumi         dbgs() << "  ";
11178ceb39bSNAKAMURA Takumi       dbgs() << format("%02hhX", *P);
1126634c3e9SKai Nacke     });
1136634c3e9SKai Nacke 
1142fa6bcf0SYusra Syeda     switch (RecordType) {
1152fa6bcf0SYusra Syeda     case GOFF::RT_ESD: {
1162fa6bcf0SYusra Syeda       // Save ESD record.
1172fa6bcf0SYusra Syeda       uint32_t EsdId;
1182fa6bcf0SYusra Syeda       ESDRecord::getEsdId(I, EsdId);
1192fa6bcf0SYusra Syeda       EsdPtrs.grow(EsdId);
1202fa6bcf0SYusra Syeda       EsdPtrs[EsdId] = I;
1212fa6bcf0SYusra Syeda 
1222fa6bcf0SYusra Syeda       // Determine and save the "sections" in GOFF.
1232fa6bcf0SYusra Syeda       // A section is saved as a tuple of the form
1242fa6bcf0SYusra Syeda       // case (1): (ED,child PR)
1252fa6bcf0SYusra Syeda       //    - where the PR must have non-zero length.
1262fa6bcf0SYusra Syeda       // case (2a) (ED,0)
1272fa6bcf0SYusra Syeda       //   - where the ED is of non-zero length.
1282fa6bcf0SYusra Syeda       // case (2b) (ED,0)
1292fa6bcf0SYusra Syeda       //   - where the ED is zero length but
1302fa6bcf0SYusra Syeda       //     contains a label (LD).
1312fa6bcf0SYusra Syeda       GOFF::ESDSymbolType SymbolType;
1322fa6bcf0SYusra Syeda       ESDRecord::getSymbolType(I, SymbolType);
1332fa6bcf0SYusra Syeda       SectionEntryImpl Section;
1342fa6bcf0SYusra Syeda       uint32_t Length;
1352fa6bcf0SYusra Syeda       ESDRecord::getLength(I, Length);
1362fa6bcf0SYusra Syeda       if (SymbolType == GOFF::ESD_ST_ElementDefinition) {
1372fa6bcf0SYusra Syeda         // case (2a)
1382fa6bcf0SYusra Syeda         if (Length != 0) {
1392fa6bcf0SYusra Syeda           Section.d.a = EsdId;
1402fa6bcf0SYusra Syeda           SectionList.emplace_back(Section);
1412fa6bcf0SYusra Syeda         }
1422fa6bcf0SYusra Syeda       } else if (SymbolType == GOFF::ESD_ST_PartReference) {
1432fa6bcf0SYusra Syeda         // case (1)
1442fa6bcf0SYusra Syeda         if (Length != 0) {
1452fa6bcf0SYusra Syeda           uint32_t SymEdId;
1462fa6bcf0SYusra Syeda           ESDRecord::getParentEsdId(I, SymEdId);
1472fa6bcf0SYusra Syeda           Section.d.a = SymEdId;
1482fa6bcf0SYusra Syeda           Section.d.b = EsdId;
1492fa6bcf0SYusra Syeda           SectionList.emplace_back(Section);
1502fa6bcf0SYusra Syeda         }
1512fa6bcf0SYusra Syeda       } else if (SymbolType == GOFF::ESD_ST_LabelDefinition) {
1522fa6bcf0SYusra Syeda         // case (2b)
1532fa6bcf0SYusra Syeda         uint32_t SymEdId;
1542fa6bcf0SYusra Syeda         ESDRecord::getParentEsdId(I, SymEdId);
1552fa6bcf0SYusra Syeda         const uint8_t *SymEdRecord = EsdPtrs[SymEdId];
1562fa6bcf0SYusra Syeda         uint32_t EdLength;
1572fa6bcf0SYusra Syeda         ESDRecord::getLength(SymEdRecord, EdLength);
1582fa6bcf0SYusra Syeda         if (!EdLength) { // [ EDID, PRID ]
1592fa6bcf0SYusra Syeda           // LD child of a zero length parent ED.
1602fa6bcf0SYusra Syeda           // Add the section ED which was previously ignored.
1612fa6bcf0SYusra Syeda           Section.d.a = SymEdId;
1622fa6bcf0SYusra Syeda           SectionList.emplace_back(Section);
1632fa6bcf0SYusra Syeda         }
1642fa6bcf0SYusra Syeda       }
1652fa6bcf0SYusra Syeda       LLVM_DEBUG(dbgs() << "  --  ESD " << EsdId << "\n");
1662fa6bcf0SYusra Syeda       break;
1672fa6bcf0SYusra Syeda     }
1684c718fdbSYusra Syeda     case GOFF::RT_TXT:
1694c718fdbSYusra Syeda       // Save TXT records.
1704c718fdbSYusra Syeda       TextPtrs.emplace_back(I);
1714c718fdbSYusra Syeda       LLVM_DEBUG(dbgs() << "  --  TXT\n");
1724c718fdbSYusra Syeda       break;
1732fa6bcf0SYusra Syeda     case GOFF::RT_END:
1742fa6bcf0SYusra Syeda       LLVM_DEBUG(dbgs() << "  --  END (GOFF record type) unhandled\n");
1752fa6bcf0SYusra Syeda       break;
1762fa6bcf0SYusra Syeda     case GOFF::RT_HDR:
1772fa6bcf0SYusra Syeda       LLVM_DEBUG(dbgs() << "  --  HDR (GOFF record type) unhandled\n");
1782fa6bcf0SYusra Syeda       break;
1792fa6bcf0SYusra Syeda     default:
1802fa6bcf0SYusra Syeda       llvm_unreachable("Unknown record type");
1812fa6bcf0SYusra Syeda     }
1822fa6bcf0SYusra Syeda     PrevRecordType = RecordType;
1832fa6bcf0SYusra Syeda     PrevContinuationBits = I[1] & 0x03;
1842fa6bcf0SYusra Syeda   }
1852fa6bcf0SYusra Syeda }
1862fa6bcf0SYusra Syeda 
1872fa6bcf0SYusra Syeda const uint8_t *GOFFObjectFile::getSymbolEsdRecord(DataRefImpl Symb) const {
1882fa6bcf0SYusra Syeda   const uint8_t *EsdRecord = EsdPtrs[Symb.d.a];
1892fa6bcf0SYusra Syeda   return EsdRecord;
1902fa6bcf0SYusra Syeda }
1912fa6bcf0SYusra Syeda 
1922fa6bcf0SYusra Syeda Expected<StringRef> GOFFObjectFile::getSymbolName(DataRefImpl Symb) const {
193*3f1be86aSKazu Hirata   if (auto It = EsdNamesCache.find(Symb.d.a); It != EsdNamesCache.end()) {
194*3f1be86aSKazu Hirata     auto &StrPtr = It->second;
1952fa6bcf0SYusra Syeda     return StringRef(StrPtr.second.get(), StrPtr.first);
1962fa6bcf0SYusra Syeda   }
1972fa6bcf0SYusra Syeda 
1982fa6bcf0SYusra Syeda   SmallString<256> SymbolName;
1992fa6bcf0SYusra Syeda   if (auto Err = ESDRecord::getData(getSymbolEsdRecord(Symb), SymbolName))
2002fa6bcf0SYusra Syeda     return std::move(Err);
2012fa6bcf0SYusra Syeda 
2022fa6bcf0SYusra Syeda   SmallString<256> SymbolNameConverted;
20302bc772dSJie Fu   ConverterEBCDIC::convertToUTF8(SymbolName, SymbolNameConverted);
2042fa6bcf0SYusra Syeda 
2052fa6bcf0SYusra Syeda   size_t Size = SymbolNameConverted.size();
2062fa6bcf0SYusra Syeda   auto StrPtr = std::make_pair(Size, std::make_unique<char[]>(Size));
2072fa6bcf0SYusra Syeda   char *Buf = StrPtr.second.get();
2082fa6bcf0SYusra Syeda   memcpy(Buf, SymbolNameConverted.data(), Size);
2092fa6bcf0SYusra Syeda   EsdNamesCache[Symb.d.a] = std::move(StrPtr);
2102fa6bcf0SYusra Syeda   return StringRef(Buf, Size);
2112fa6bcf0SYusra Syeda }
2122fa6bcf0SYusra Syeda 
2132fa6bcf0SYusra Syeda Expected<StringRef> GOFFObjectFile::getSymbolName(SymbolRef Symbol) const {
2142fa6bcf0SYusra Syeda   return getSymbolName(Symbol.getRawDataRefImpl());
2152fa6bcf0SYusra Syeda }
2162fa6bcf0SYusra Syeda 
2172fa6bcf0SYusra Syeda Expected<uint64_t> GOFFObjectFile::getSymbolAddress(DataRefImpl Symb) const {
2182fa6bcf0SYusra Syeda   uint32_t Offset;
2192fa6bcf0SYusra Syeda   const uint8_t *EsdRecord = getSymbolEsdRecord(Symb);
2202fa6bcf0SYusra Syeda   ESDRecord::getOffset(EsdRecord, Offset);
2212fa6bcf0SYusra Syeda   return static_cast<uint64_t>(Offset);
2222fa6bcf0SYusra Syeda }
2232fa6bcf0SYusra Syeda 
2242fa6bcf0SYusra Syeda uint64_t GOFFObjectFile::getSymbolValueImpl(DataRefImpl Symb) const {
2252fa6bcf0SYusra Syeda   uint32_t Offset;
2262fa6bcf0SYusra Syeda   const uint8_t *EsdRecord = getSymbolEsdRecord(Symb);
2272fa6bcf0SYusra Syeda   ESDRecord::getOffset(EsdRecord, Offset);
2282fa6bcf0SYusra Syeda   return static_cast<uint64_t>(Offset);
2292fa6bcf0SYusra Syeda }
2302fa6bcf0SYusra Syeda 
2312fa6bcf0SYusra Syeda uint64_t GOFFObjectFile::getCommonSymbolSizeImpl(DataRefImpl Symb) const {
2322fa6bcf0SYusra Syeda   return 0;
2332fa6bcf0SYusra Syeda }
2342fa6bcf0SYusra Syeda 
2352fa6bcf0SYusra Syeda bool GOFFObjectFile::isSymbolUnresolved(DataRefImpl Symb) const {
2362fa6bcf0SYusra Syeda   const uint8_t *Record = getSymbolEsdRecord(Symb);
2372fa6bcf0SYusra Syeda   GOFF::ESDSymbolType SymbolType;
2382fa6bcf0SYusra Syeda   ESDRecord::getSymbolType(Record, SymbolType);
2392fa6bcf0SYusra Syeda 
2402fa6bcf0SYusra Syeda   if (SymbolType == GOFF::ESD_ST_ExternalReference)
2412fa6bcf0SYusra Syeda     return true;
2422fa6bcf0SYusra Syeda   if (SymbolType == GOFF::ESD_ST_PartReference) {
2432fa6bcf0SYusra Syeda     uint32_t Length;
2442fa6bcf0SYusra Syeda     ESDRecord::getLength(Record, Length);
2452fa6bcf0SYusra Syeda     if (Length == 0)
2462fa6bcf0SYusra Syeda       return true;
2472fa6bcf0SYusra Syeda   }
2482fa6bcf0SYusra Syeda   return false;
2492fa6bcf0SYusra Syeda }
2502fa6bcf0SYusra Syeda 
2512fa6bcf0SYusra Syeda bool GOFFObjectFile::isSymbolIndirect(DataRefImpl Symb) const {
2522fa6bcf0SYusra Syeda   const uint8_t *Record = getSymbolEsdRecord(Symb);
2532fa6bcf0SYusra Syeda   bool Indirect;
2542fa6bcf0SYusra Syeda   ESDRecord::getIndirectReference(Record, Indirect);
2552fa6bcf0SYusra Syeda   return Indirect;
2562fa6bcf0SYusra Syeda }
2572fa6bcf0SYusra Syeda 
2582fa6bcf0SYusra Syeda Expected<uint32_t> GOFFObjectFile::getSymbolFlags(DataRefImpl Symb) const {
2592fa6bcf0SYusra Syeda   uint32_t Flags = 0;
2602fa6bcf0SYusra Syeda   if (isSymbolUnresolved(Symb))
2612fa6bcf0SYusra Syeda     Flags |= SymbolRef::SF_Undefined;
2622fa6bcf0SYusra Syeda 
2632fa6bcf0SYusra Syeda   const uint8_t *Record = getSymbolEsdRecord(Symb);
2642fa6bcf0SYusra Syeda 
2652fa6bcf0SYusra Syeda   GOFF::ESDBindingStrength BindingStrength;
2662fa6bcf0SYusra Syeda   ESDRecord::getBindingStrength(Record, BindingStrength);
2672fa6bcf0SYusra Syeda   if (BindingStrength == GOFF::ESD_BST_Weak)
2682fa6bcf0SYusra Syeda     Flags |= SymbolRef::SF_Weak;
2692fa6bcf0SYusra Syeda 
2702fa6bcf0SYusra Syeda   GOFF::ESDBindingScope BindingScope;
2712fa6bcf0SYusra Syeda   ESDRecord::getBindingScope(Record, BindingScope);
2722fa6bcf0SYusra Syeda 
2732fa6bcf0SYusra Syeda   if (BindingScope != GOFF::ESD_BSC_Section) {
2742fa6bcf0SYusra Syeda     Expected<StringRef> Name = getSymbolName(Symb);
2752fa6bcf0SYusra Syeda     if (Name && *Name != " ") { // Blank name is local.
2762fa6bcf0SYusra Syeda       Flags |= SymbolRef::SF_Global;
2772fa6bcf0SYusra Syeda       if (BindingScope == GOFF::ESD_BSC_ImportExport)
2782fa6bcf0SYusra Syeda         Flags |= SymbolRef::SF_Exported;
2792fa6bcf0SYusra Syeda       else if (!(Flags & SymbolRef::SF_Undefined))
2802fa6bcf0SYusra Syeda         Flags |= SymbolRef::SF_Hidden;
2812fa6bcf0SYusra Syeda     }
2822fa6bcf0SYusra Syeda   }
2832fa6bcf0SYusra Syeda 
2842fa6bcf0SYusra Syeda   return Flags;
2852fa6bcf0SYusra Syeda }
2862fa6bcf0SYusra Syeda 
2872fa6bcf0SYusra Syeda Expected<SymbolRef::Type>
2882fa6bcf0SYusra Syeda GOFFObjectFile::getSymbolType(DataRefImpl Symb) const {
2892fa6bcf0SYusra Syeda   const uint8_t *Record = getSymbolEsdRecord(Symb);
2902fa6bcf0SYusra Syeda   GOFF::ESDSymbolType SymbolType;
2912fa6bcf0SYusra Syeda   ESDRecord::getSymbolType(Record, SymbolType);
2922fa6bcf0SYusra Syeda   GOFF::ESDExecutable Executable;
2932fa6bcf0SYusra Syeda   ESDRecord::getExecutable(Record, Executable);
2942fa6bcf0SYusra Syeda 
2952fa6bcf0SYusra Syeda   if (SymbolType != GOFF::ESD_ST_SectionDefinition &&
2962fa6bcf0SYusra Syeda       SymbolType != GOFF::ESD_ST_ElementDefinition &&
2972fa6bcf0SYusra Syeda       SymbolType != GOFF::ESD_ST_LabelDefinition &&
2982fa6bcf0SYusra Syeda       SymbolType != GOFF::ESD_ST_PartReference &&
2992fa6bcf0SYusra Syeda       SymbolType != GOFF::ESD_ST_ExternalReference) {
3002fa6bcf0SYusra Syeda     uint32_t EsdId;
3012fa6bcf0SYusra Syeda     ESDRecord::getEsdId(Record, EsdId);
3022fa6bcf0SYusra Syeda     return createStringError(llvm::errc::invalid_argument,
3032fa6bcf0SYusra Syeda                              "ESD record %" PRIu32
3042fa6bcf0SYusra Syeda                              " has invalid symbol type 0x%02" PRIX8,
3052fa6bcf0SYusra Syeda                              EsdId, SymbolType);
3062fa6bcf0SYusra Syeda   }
3072fa6bcf0SYusra Syeda   switch (SymbolType) {
3082fa6bcf0SYusra Syeda   case GOFF::ESD_ST_SectionDefinition:
3092fa6bcf0SYusra Syeda   case GOFF::ESD_ST_ElementDefinition:
3102fa6bcf0SYusra Syeda     return SymbolRef::ST_Other;
3112fa6bcf0SYusra Syeda   case GOFF::ESD_ST_LabelDefinition:
3122fa6bcf0SYusra Syeda   case GOFF::ESD_ST_PartReference:
3132fa6bcf0SYusra Syeda   case GOFF::ESD_ST_ExternalReference:
3142fa6bcf0SYusra Syeda     if (Executable != GOFF::ESD_EXE_CODE && Executable != GOFF::ESD_EXE_DATA &&
3152fa6bcf0SYusra Syeda         Executable != GOFF::ESD_EXE_Unspecified) {
3162fa6bcf0SYusra Syeda       uint32_t EsdId;
3172fa6bcf0SYusra Syeda       ESDRecord::getEsdId(Record, EsdId);
3182fa6bcf0SYusra Syeda       return createStringError(llvm::errc::invalid_argument,
3192fa6bcf0SYusra Syeda                                "ESD record %" PRIu32
3202fa6bcf0SYusra Syeda                                " has unknown Executable type 0x%02X",
3212fa6bcf0SYusra Syeda                                EsdId, Executable);
3222fa6bcf0SYusra Syeda     }
3232fa6bcf0SYusra Syeda     switch (Executable) {
3242fa6bcf0SYusra Syeda     case GOFF::ESD_EXE_CODE:
3252fa6bcf0SYusra Syeda       return SymbolRef::ST_Function;
3262fa6bcf0SYusra Syeda     case GOFF::ESD_EXE_DATA:
3272fa6bcf0SYusra Syeda       return SymbolRef::ST_Data;
3282fa6bcf0SYusra Syeda     case GOFF::ESD_EXE_Unspecified:
3292fa6bcf0SYusra Syeda       return SymbolRef::ST_Unknown;
3302fa6bcf0SYusra Syeda     }
33114390ecbSSimon Pilgrim     llvm_unreachable("Unhandled ESDExecutable");
3322fa6bcf0SYusra Syeda   }
33314390ecbSSimon Pilgrim   llvm_unreachable("Unhandled ESDSymbolType");
3342fa6bcf0SYusra Syeda }
3352fa6bcf0SYusra Syeda 
3362fa6bcf0SYusra Syeda Expected<section_iterator>
3372fa6bcf0SYusra Syeda GOFFObjectFile::getSymbolSection(DataRefImpl Symb) const {
3382fa6bcf0SYusra Syeda   DataRefImpl Sec;
3392fa6bcf0SYusra Syeda 
3402fa6bcf0SYusra Syeda   if (isSymbolUnresolved(Symb))
3412fa6bcf0SYusra Syeda     return section_iterator(SectionRef(Sec, this));
3422fa6bcf0SYusra Syeda 
3432fa6bcf0SYusra Syeda   const uint8_t *SymEsdRecord = EsdPtrs[Symb.d.a];
3442fa6bcf0SYusra Syeda   uint32_t SymEdId;
3452fa6bcf0SYusra Syeda   ESDRecord::getParentEsdId(SymEsdRecord, SymEdId);
3462fa6bcf0SYusra Syeda   const uint8_t *SymEdRecord = EsdPtrs[SymEdId];
3472fa6bcf0SYusra Syeda 
3482fa6bcf0SYusra Syeda   for (size_t I = 0, E = SectionList.size(); I < E; ++I) {
3492fa6bcf0SYusra Syeda     bool Found;
3502fa6bcf0SYusra Syeda     const uint8_t *SectionPrRecord = getSectionPrEsdRecord(I);
3512fa6bcf0SYusra Syeda     if (SectionPrRecord) {
3522fa6bcf0SYusra Syeda       Found = SymEsdRecord == SectionPrRecord;
3532fa6bcf0SYusra Syeda     } else {
3542fa6bcf0SYusra Syeda       const uint8_t *SectionEdRecord = getSectionEdEsdRecord(I);
3552fa6bcf0SYusra Syeda       Found = SymEdRecord == SectionEdRecord;
3562fa6bcf0SYusra Syeda     }
3572fa6bcf0SYusra Syeda 
3582fa6bcf0SYusra Syeda     if (Found) {
3592fa6bcf0SYusra Syeda       Sec.d.a = I;
3602fa6bcf0SYusra Syeda       return section_iterator(SectionRef(Sec, this));
3612fa6bcf0SYusra Syeda     }
3622fa6bcf0SYusra Syeda   }
3632fa6bcf0SYusra Syeda   return createStringError(llvm::errc::invalid_argument,
3642fa6bcf0SYusra Syeda                            "symbol with ESD id " + std::to_string(Symb.d.a) +
3652fa6bcf0SYusra Syeda                                " refers to invalid section with ESD id " +
3662fa6bcf0SYusra Syeda                                std::to_string(SymEdId));
3672fa6bcf0SYusra Syeda }
3682fa6bcf0SYusra Syeda 
3694c718fdbSYusra Syeda uint64_t GOFFObjectFile::getSymbolSize(DataRefImpl Symb) const {
3704c718fdbSYusra Syeda   const uint8_t *Record = getSymbolEsdRecord(Symb);
3714c718fdbSYusra Syeda   uint32_t Length;
3724c718fdbSYusra Syeda   ESDRecord::getLength(Record, Length);
3734c718fdbSYusra Syeda   return Length;
3744c718fdbSYusra Syeda }
3754c718fdbSYusra Syeda 
3762fa6bcf0SYusra Syeda const uint8_t *GOFFObjectFile::getSectionEdEsdRecord(DataRefImpl &Sec) const {
3772fa6bcf0SYusra Syeda   SectionEntryImpl EsdIds = SectionList[Sec.d.a];
3782fa6bcf0SYusra Syeda   const uint8_t *EsdRecord = EsdPtrs[EsdIds.d.a];
3792fa6bcf0SYusra Syeda   return EsdRecord;
3802fa6bcf0SYusra Syeda }
3812fa6bcf0SYusra Syeda 
3822fa6bcf0SYusra Syeda const uint8_t *GOFFObjectFile::getSectionPrEsdRecord(DataRefImpl &Sec) const {
3832fa6bcf0SYusra Syeda   SectionEntryImpl EsdIds = SectionList[Sec.d.a];
3842fa6bcf0SYusra Syeda   const uint8_t *EsdRecord = nullptr;
3852fa6bcf0SYusra Syeda   if (EsdIds.d.b)
3862fa6bcf0SYusra Syeda     EsdRecord = EsdPtrs[EsdIds.d.b];
3872fa6bcf0SYusra Syeda   return EsdRecord;
3882fa6bcf0SYusra Syeda }
3892fa6bcf0SYusra Syeda 
3902fa6bcf0SYusra Syeda const uint8_t *
3912fa6bcf0SYusra Syeda GOFFObjectFile::getSectionEdEsdRecord(uint32_t SectionIndex) const {
3922fa6bcf0SYusra Syeda   DataRefImpl Sec;
3932fa6bcf0SYusra Syeda   Sec.d.a = SectionIndex;
3942fa6bcf0SYusra Syeda   const uint8_t *EsdRecord = getSectionEdEsdRecord(Sec);
3952fa6bcf0SYusra Syeda   return EsdRecord;
3962fa6bcf0SYusra Syeda }
3972fa6bcf0SYusra Syeda 
3982fa6bcf0SYusra Syeda const uint8_t *
3992fa6bcf0SYusra Syeda GOFFObjectFile::getSectionPrEsdRecord(uint32_t SectionIndex) const {
4002fa6bcf0SYusra Syeda   DataRefImpl Sec;
4012fa6bcf0SYusra Syeda   Sec.d.a = SectionIndex;
4022fa6bcf0SYusra Syeda   const uint8_t *EsdRecord = getSectionPrEsdRecord(Sec);
4032fa6bcf0SYusra Syeda   return EsdRecord;
4042fa6bcf0SYusra Syeda }
4052fa6bcf0SYusra Syeda 
4064c718fdbSYusra Syeda uint32_t GOFFObjectFile::getSectionDefEsdId(DataRefImpl &Sec) const {
4074c718fdbSYusra Syeda   const uint8_t *EsdRecord = getSectionEdEsdRecord(Sec);
4084c718fdbSYusra Syeda   uint32_t Length;
4094c718fdbSYusra Syeda   ESDRecord::getLength(EsdRecord, Length);
4104c718fdbSYusra Syeda   if (Length == 0) {
4114c718fdbSYusra Syeda     const uint8_t *PrEsdRecord = getSectionPrEsdRecord(Sec);
4124c718fdbSYusra Syeda     if (PrEsdRecord)
4134c718fdbSYusra Syeda       EsdRecord = PrEsdRecord;
4144c718fdbSYusra Syeda   }
4154c718fdbSYusra Syeda 
4164c718fdbSYusra Syeda   uint32_t DefEsdId;
4174c718fdbSYusra Syeda   ESDRecord::getEsdId(EsdRecord, DefEsdId);
4184c718fdbSYusra Syeda   LLVM_DEBUG(dbgs() << "Got def EsdId: " << DefEsdId << '\n');
4194c718fdbSYusra Syeda   return DefEsdId;
4204c718fdbSYusra Syeda }
4214c718fdbSYusra Syeda 
4224c718fdbSYusra Syeda void GOFFObjectFile::moveSectionNext(DataRefImpl &Sec) const {
4234c718fdbSYusra Syeda   Sec.d.a++;
4244c718fdbSYusra Syeda   if ((Sec.d.a) >= SectionList.size())
4254c718fdbSYusra Syeda     Sec.d.a = 0;
4264c718fdbSYusra Syeda }
4274c718fdbSYusra Syeda 
4284c718fdbSYusra Syeda Expected<StringRef> GOFFObjectFile::getSectionName(DataRefImpl Sec) const {
4294c718fdbSYusra Syeda   DataRefImpl EdSym;
4304c718fdbSYusra Syeda   SectionEntryImpl EsdIds = SectionList[Sec.d.a];
4314c718fdbSYusra Syeda   EdSym.d.a = EsdIds.d.a;
4324c718fdbSYusra Syeda   Expected<StringRef> Name = getSymbolName(EdSym);
4334c718fdbSYusra Syeda   if (Name) {
4344c718fdbSYusra Syeda     StringRef Res = *Name;
4354c718fdbSYusra Syeda     LLVM_DEBUG(dbgs() << "Got section: " << Res << '\n');
4364c718fdbSYusra Syeda     LLVM_DEBUG(dbgs() << "Final section name: " << Res << '\n');
4374c718fdbSYusra Syeda     Name = Res;
4384c718fdbSYusra Syeda   }
4394c718fdbSYusra Syeda   return Name;
4404c718fdbSYusra Syeda }
4414c718fdbSYusra Syeda 
4424c718fdbSYusra Syeda uint64_t GOFFObjectFile::getSectionAddress(DataRefImpl Sec) const {
4434c718fdbSYusra Syeda   uint32_t Offset;
4444c718fdbSYusra Syeda   const uint8_t *EsdRecord = getSectionEdEsdRecord(Sec);
4454c718fdbSYusra Syeda   ESDRecord::getOffset(EsdRecord, Offset);
4464c718fdbSYusra Syeda   return Offset;
4474c718fdbSYusra Syeda }
4484c718fdbSYusra Syeda 
4494c718fdbSYusra Syeda uint64_t GOFFObjectFile::getSectionSize(DataRefImpl Sec) const {
4504c718fdbSYusra Syeda   uint32_t Length;
4514c718fdbSYusra Syeda   uint32_t DefEsdId = getSectionDefEsdId(Sec);
4524c718fdbSYusra Syeda   const uint8_t *EsdRecord = EsdPtrs[DefEsdId];
4534c718fdbSYusra Syeda   ESDRecord::getLength(EsdRecord, Length);
4544c718fdbSYusra Syeda   LLVM_DEBUG(dbgs() << "Got section size: " << Length << '\n');
4554c718fdbSYusra Syeda   return static_cast<uint64_t>(Length);
4564c718fdbSYusra Syeda }
4574c718fdbSYusra Syeda 
4584c718fdbSYusra Syeda // Unravel TXT records and expand fill characters to produce
4594c718fdbSYusra Syeda // a contiguous sequence of bytes.
4604c718fdbSYusra Syeda Expected<ArrayRef<uint8_t>>
4614c718fdbSYusra Syeda GOFFObjectFile::getSectionContents(DataRefImpl Sec) const {
462*3f1be86aSKazu Hirata   if (auto It = SectionDataCache.find(Sec.d.a); It != SectionDataCache.end()) {
463*3f1be86aSKazu Hirata     auto &Buf = It->second;
4644c718fdbSYusra Syeda     return ArrayRef<uint8_t>(Buf);
4654c718fdbSYusra Syeda   }
4664c718fdbSYusra Syeda   uint64_t SectionSize = getSectionSize(Sec);
4674c718fdbSYusra Syeda   uint32_t DefEsdId = getSectionDefEsdId(Sec);
4684c718fdbSYusra Syeda 
4694c718fdbSYusra Syeda   const uint8_t *EdEsdRecord = getSectionEdEsdRecord(Sec);
4704c718fdbSYusra Syeda   bool FillBytePresent;
4714c718fdbSYusra Syeda   ESDRecord::getFillBytePresent(EdEsdRecord, FillBytePresent);
4724c718fdbSYusra Syeda   uint8_t FillByte = '\0';
4734c718fdbSYusra Syeda   if (FillBytePresent)
4744c718fdbSYusra Syeda     ESDRecord::getFillByteValue(EdEsdRecord, FillByte);
4754c718fdbSYusra Syeda 
4764c718fdbSYusra Syeda   // Initialize section with fill byte.
4774c718fdbSYusra Syeda   SmallVector<uint8_t> Data(SectionSize, FillByte);
4784c718fdbSYusra Syeda 
4794c718fdbSYusra Syeda   // Replace section with content from text records.
4804c718fdbSYusra Syeda   for (const uint8_t *TxtRecordInt : TextPtrs) {
4814c718fdbSYusra Syeda     const uint8_t *TxtRecordPtr = TxtRecordInt;
4824c718fdbSYusra Syeda     uint32_t TxtEsdId;
4834c718fdbSYusra Syeda     TXTRecord::getElementEsdId(TxtRecordPtr, TxtEsdId);
4844c718fdbSYusra Syeda     LLVM_DEBUG(dbgs() << "Got txt EsdId: " << TxtEsdId << '\n');
4854c718fdbSYusra Syeda 
4864c718fdbSYusra Syeda     if (TxtEsdId != DefEsdId)
4874c718fdbSYusra Syeda       continue;
4884c718fdbSYusra Syeda 
4894c718fdbSYusra Syeda     uint32_t TxtDataOffset;
4904c718fdbSYusra Syeda     TXTRecord::getOffset(TxtRecordPtr, TxtDataOffset);
4914c718fdbSYusra Syeda 
4924c718fdbSYusra Syeda     uint16_t TxtDataSize;
4934c718fdbSYusra Syeda     TXTRecord::getDataLength(TxtRecordPtr, TxtDataSize);
4944c718fdbSYusra Syeda 
4954c718fdbSYusra Syeda     LLVM_DEBUG(dbgs() << "Record offset " << TxtDataOffset << ", data size "
4964c718fdbSYusra Syeda                       << TxtDataSize << "\n");
4974c718fdbSYusra Syeda 
4984c718fdbSYusra Syeda     SmallString<256> CompleteData;
4994c718fdbSYusra Syeda     CompleteData.reserve(TxtDataSize);
5004c718fdbSYusra Syeda     if (Error Err = TXTRecord::getData(TxtRecordPtr, CompleteData))
5014c718fdbSYusra Syeda       return std::move(Err);
5024c718fdbSYusra Syeda     assert(CompleteData.size() == TxtDataSize && "Wrong length of data");
5034c718fdbSYusra Syeda     std::copy(CompleteData.data(), CompleteData.data() + TxtDataSize,
5044c718fdbSYusra Syeda               Data.begin() + TxtDataOffset);
5054c718fdbSYusra Syeda   }
5064c718fdbSYusra Syeda   SectionDataCache[Sec.d.a] = Data;
5074c718fdbSYusra Syeda   return ArrayRef<uint8_t>(SectionDataCache[Sec.d.a]);
5084c718fdbSYusra Syeda }
5094c718fdbSYusra Syeda 
5104c718fdbSYusra Syeda uint64_t GOFFObjectFile::getSectionAlignment(DataRefImpl Sec) const {
5114c718fdbSYusra Syeda   const uint8_t *EsdRecord = getSectionEdEsdRecord(Sec);
5124c718fdbSYusra Syeda   GOFF::ESDAlignment Pow2Alignment;
5134c718fdbSYusra Syeda   ESDRecord::getAlignment(EsdRecord, Pow2Alignment);
514db080605SSimon Pilgrim   return 1ULL << static_cast<uint64_t>(Pow2Alignment);
5154c718fdbSYusra Syeda }
5164c718fdbSYusra Syeda 
5174c718fdbSYusra Syeda bool GOFFObjectFile::isSectionText(DataRefImpl Sec) const {
5184c718fdbSYusra Syeda   const uint8_t *EsdRecord = getSectionEdEsdRecord(Sec);
5194c718fdbSYusra Syeda   GOFF::ESDExecutable Executable;
5204c718fdbSYusra Syeda   ESDRecord::getExecutable(EsdRecord, Executable);
5214c718fdbSYusra Syeda   return Executable == GOFF::ESD_EXE_CODE;
5224c718fdbSYusra Syeda }
5234c718fdbSYusra Syeda 
5244c718fdbSYusra Syeda bool GOFFObjectFile::isSectionData(DataRefImpl Sec) const {
5254c718fdbSYusra Syeda   const uint8_t *EsdRecord = getSectionEdEsdRecord(Sec);
5264c718fdbSYusra Syeda   GOFF::ESDExecutable Executable;
5274c718fdbSYusra Syeda   ESDRecord::getExecutable(EsdRecord, Executable);
5284c718fdbSYusra Syeda   return Executable == GOFF::ESD_EXE_DATA;
5294c718fdbSYusra Syeda }
5304c718fdbSYusra Syeda 
5314c718fdbSYusra Syeda bool GOFFObjectFile::isSectionNoLoad(DataRefImpl Sec) const {
5324c718fdbSYusra Syeda   const uint8_t *EsdRecord = getSectionEdEsdRecord(Sec);
5334c718fdbSYusra Syeda   GOFF::ESDLoadingBehavior LoadingBehavior;
5344c718fdbSYusra Syeda   ESDRecord::getLoadingBehavior(EsdRecord, LoadingBehavior);
5354c718fdbSYusra Syeda   return LoadingBehavior == GOFF::ESD_LB_NoLoad;
5364c718fdbSYusra Syeda }
5374c718fdbSYusra Syeda 
5384c718fdbSYusra Syeda bool GOFFObjectFile::isSectionReadOnlyData(DataRefImpl Sec) const {
5394c718fdbSYusra Syeda   if (!isSectionData(Sec))
5404c718fdbSYusra Syeda     return false;
5414c718fdbSYusra Syeda 
5424c718fdbSYusra Syeda   const uint8_t *EsdRecord = getSectionEdEsdRecord(Sec);
5434c718fdbSYusra Syeda   GOFF::ESDLoadingBehavior LoadingBehavior;
5444c718fdbSYusra Syeda   ESDRecord::getLoadingBehavior(EsdRecord, LoadingBehavior);
5454c718fdbSYusra Syeda   return LoadingBehavior == GOFF::ESD_LB_Initial;
5464c718fdbSYusra Syeda }
5474c718fdbSYusra Syeda 
5484c718fdbSYusra Syeda bool GOFFObjectFile::isSectionZeroInit(DataRefImpl Sec) const {
5494c718fdbSYusra Syeda   // GOFF uses fill characters and fill characters are applied
5504c718fdbSYusra Syeda   // on getSectionContents() - so we say false to zero init.
5514c718fdbSYusra Syeda   return false;
5524c718fdbSYusra Syeda }
5534c718fdbSYusra Syeda 
5542fa6bcf0SYusra Syeda section_iterator GOFFObjectFile::section_begin() const {
5552fa6bcf0SYusra Syeda   DataRefImpl Sec;
5562fa6bcf0SYusra Syeda   moveSectionNext(Sec);
5572fa6bcf0SYusra Syeda   return section_iterator(SectionRef(Sec, this));
5582fa6bcf0SYusra Syeda }
5592fa6bcf0SYusra Syeda 
5602fa6bcf0SYusra Syeda section_iterator GOFFObjectFile::section_end() const {
5612fa6bcf0SYusra Syeda   DataRefImpl Sec;
5622fa6bcf0SYusra Syeda   return section_iterator(SectionRef(Sec, this));
5632fa6bcf0SYusra Syeda }
5642fa6bcf0SYusra Syeda 
5652fa6bcf0SYusra Syeda void GOFFObjectFile::moveSymbolNext(DataRefImpl &Symb) const {
5662fa6bcf0SYusra Syeda   for (uint32_t I = Symb.d.a + 1, E = EsdPtrs.size(); I < E; ++I) {
5672fa6bcf0SYusra Syeda     if (EsdPtrs[I]) {
5682fa6bcf0SYusra Syeda       const uint8_t *EsdRecord = EsdPtrs[I];
5692fa6bcf0SYusra Syeda       GOFF::ESDSymbolType SymbolType;
5702fa6bcf0SYusra Syeda       ESDRecord::getSymbolType(EsdRecord, SymbolType);
5712fa6bcf0SYusra Syeda       // Skip EDs - i.e. section symbols.
5722fa6bcf0SYusra Syeda       bool IgnoreSpecialGOFFSymbols = true;
5732fa6bcf0SYusra Syeda       bool SkipSymbol = ((SymbolType == GOFF::ESD_ST_ElementDefinition) ||
5742fa6bcf0SYusra Syeda                          (SymbolType == GOFF::ESD_ST_SectionDefinition)) &&
5752fa6bcf0SYusra Syeda                         IgnoreSpecialGOFFSymbols;
5762fa6bcf0SYusra Syeda       if (!SkipSymbol) {
5772fa6bcf0SYusra Syeda         Symb.d.a = I;
5782fa6bcf0SYusra Syeda         return;
5792fa6bcf0SYusra Syeda       }
5802fa6bcf0SYusra Syeda     }
5812fa6bcf0SYusra Syeda   }
5822fa6bcf0SYusra Syeda   Symb.d.a = 0;
5832fa6bcf0SYusra Syeda }
5842fa6bcf0SYusra Syeda 
5852fa6bcf0SYusra Syeda basic_symbol_iterator GOFFObjectFile::symbol_begin() const {
5862fa6bcf0SYusra Syeda   DataRefImpl Symb;
5872fa6bcf0SYusra Syeda   moveSymbolNext(Symb);
5882fa6bcf0SYusra Syeda   return basic_symbol_iterator(SymbolRef(Symb, this));
5892fa6bcf0SYusra Syeda }
5902fa6bcf0SYusra Syeda 
5912fa6bcf0SYusra Syeda basic_symbol_iterator GOFFObjectFile::symbol_end() const {
5922fa6bcf0SYusra Syeda   DataRefImpl Symb;
5932fa6bcf0SYusra Syeda   return basic_symbol_iterator(SymbolRef(Symb, this));
5942fa6bcf0SYusra Syeda }
5952fa6bcf0SYusra Syeda 
5962fa6bcf0SYusra Syeda Error Record::getContinuousData(const uint8_t *Record, uint16_t DataLength,
5972fa6bcf0SYusra Syeda                                 int DataIndex, SmallString<256> &CompleteData) {
5982fa6bcf0SYusra Syeda   // First record.
5992fa6bcf0SYusra Syeda   const uint8_t *Slice = Record + DataIndex;
6002fa6bcf0SYusra Syeda   size_t SliceLength =
6012fa6bcf0SYusra Syeda       std::min(DataLength, (uint16_t)(GOFF::RecordLength - DataIndex));
6022fa6bcf0SYusra Syeda   CompleteData.append(Slice, Slice + SliceLength);
6032fa6bcf0SYusra Syeda   DataLength -= SliceLength;
6042fa6bcf0SYusra Syeda   Slice += SliceLength;
6052fa6bcf0SYusra Syeda 
6062fa6bcf0SYusra Syeda   // Continuation records.
6072fa6bcf0SYusra Syeda   for (; DataLength > 0;
6082fa6bcf0SYusra Syeda        DataLength -= SliceLength, Slice += GOFF::PayloadLength) {
6092fa6bcf0SYusra Syeda     // Slice points to the start of the new record.
6102fa6bcf0SYusra Syeda     // Check that this block is a Continuation.
6112fa6bcf0SYusra Syeda     assert(Record::isContinuation(Slice) && "Continuation bit must be set");
6122fa6bcf0SYusra Syeda     // Check that the last Continuation is terminated correctly.
6132fa6bcf0SYusra Syeda     if (DataLength <= 77 && Record::isContinued(Slice))
6142fa6bcf0SYusra Syeda       return createStringError(object_error::parse_failed,
6152fa6bcf0SYusra Syeda                                "continued bit should not be set");
6162fa6bcf0SYusra Syeda 
6172fa6bcf0SYusra Syeda     SliceLength = std::min(DataLength, (uint16_t)GOFF::PayloadLength);
6182fa6bcf0SYusra Syeda     Slice += GOFF::RecordPrefixLength;
6192fa6bcf0SYusra Syeda     CompleteData.append(Slice, Slice + SliceLength);
6202fa6bcf0SYusra Syeda   }
6212fa6bcf0SYusra Syeda   return Error::success();
6222fa6bcf0SYusra Syeda }
6232fa6bcf0SYusra Syeda 
6242fa6bcf0SYusra Syeda Error HDRRecord::getData(const uint8_t *Record,
6252fa6bcf0SYusra Syeda                          SmallString<256> &CompleteData) {
6262fa6bcf0SYusra Syeda   uint16_t Length = getPropertyModuleLength(Record);
6272fa6bcf0SYusra Syeda   return getContinuousData(Record, Length, 60, CompleteData);
6282fa6bcf0SYusra Syeda }
6292fa6bcf0SYusra Syeda 
6302fa6bcf0SYusra Syeda Error ESDRecord::getData(const uint8_t *Record,
6312fa6bcf0SYusra Syeda                          SmallString<256> &CompleteData) {
6322fa6bcf0SYusra Syeda   uint16_t DataSize = getNameLength(Record);
6332fa6bcf0SYusra Syeda   return getContinuousData(Record, DataSize, 72, CompleteData);
6342fa6bcf0SYusra Syeda }
6352fa6bcf0SYusra Syeda 
6364c718fdbSYusra Syeda Error TXTRecord::getData(const uint8_t *Record,
6374c718fdbSYusra Syeda                          SmallString<256> &CompleteData) {
6384c718fdbSYusra Syeda   uint16_t Length;
6394c718fdbSYusra Syeda   getDataLength(Record, Length);
6404c718fdbSYusra Syeda   return getContinuousData(Record, Length, 24, CompleteData);
6414c718fdbSYusra Syeda }
6424c718fdbSYusra Syeda 
6432fa6bcf0SYusra Syeda Error ENDRecord::getData(const uint8_t *Record,
6442fa6bcf0SYusra Syeda                          SmallString<256> &CompleteData) {
6452fa6bcf0SYusra Syeda   uint16_t Length = getNameLength(Record);
6462fa6bcf0SYusra Syeda   return getContinuousData(Record, Length, 26, CompleteData);
6472fa6bcf0SYusra Syeda }
648