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");
 
   64  SectionEntryImpl DummySection;
 
   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;
 
  133      SectionEntryImpl Section;
 
  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);
 
  170      TextPtrs.emplace_back(
I);
 
  183    PrevContinuationBits = 
I[1] & 0x03;
 
 
  188  const uint8_t *EsdRecord = EsdPtrs[Symb.
d.
a];
 
  193  if (
auto It = EsdNamesCache.find(Symb.
d.
a); It != EsdNamesCache.end()) {
 
  194    auto &StrPtr = It->second;
 
  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 {
 
  236  const uint8_t *Record = getSymbolEsdRecord(Symb);
 
  251bool GOFFObjectFile::isSymbolIndirect(
DataRefImpl Symb)
 const {
 
  252  const uint8_t *Record = getSymbolEsdRecord(Symb);
 
  258Expected<uint32_t> GOFFObjectFile::getSymbolFlags(
DataRefImpl Symb)
 const {
 
  260  if (isSymbolUnresolved(Symb))
 
  263  const uint8_t *Record = getSymbolEsdRecord(Symb);
 
  275    if (Name && *Name != 
" ") { 
 
  287Expected<SymbolRef::Type>
 
  288GOFFObjectFile::getSymbolType(
DataRefImpl Symb)
 const {
 
  289  const uint8_t *Record = getSymbolEsdRecord(Symb);
 
  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) {
 
  336Expected<section_iterator>
 
  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));
 
  369uint64_t GOFFObjectFile::getSymbolSize(
DataRefImpl Symb)
 const {
 
  370  const uint8_t *Record = getSymbolEsdRecord(Symb);
 
  376const uint8_t *GOFFObjectFile::getSectionEdEsdRecord(
DataRefImpl &Sec)
 const {
 
  377  SectionEntryImpl EsdIds = SectionList[Sec.
d.
a];
 
  378  const uint8_t *EsdRecord = EsdPtrs[EsdIds.d.a];
 
  382const uint8_t *GOFFObjectFile::getSectionPrEsdRecord(
DataRefImpl &Sec)
 const {
 
  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);
 
  406uint32_t GOFFObjectFile::getSectionDefEsdId(
DataRefImpl &Sec)
 const {
 
  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())
 
  428Expected<StringRef> GOFFObjectFile::getSectionName(
DataRefImpl Sec)
 const {
 
  430  SectionEntryImpl EsdIds = SectionList[Sec.
d.
a];
 
  431  EdSym.
d.
a = EsdIds.d.a;
 
  434    StringRef Res = *
Name;
 
  442uint64_t GOFFObjectFile::getSectionAddress(
DataRefImpl Sec)
 const {
 
  444  const uint8_t *EsdRecord = getSectionEdEsdRecord(Sec);
 
  449uint64_t GOFFObjectFile::getSectionSize(
DataRefImpl Sec)
 const {
 
  451  uint32_t DefEsdId = getSectionDefEsdId(Sec);
 
  452  const uint8_t *EsdRecord = EsdPtrs[DefEsdId];
 
  455  return static_cast<uint64_t
>(
Length);
 
  460Expected<ArrayRef<uint8_t>>
 
  461GOFFObjectFile::getSectionContents(
DataRefImpl Sec)
 const {
 
  462  if (
auto It = SectionDataCache.find(Sec.
d.
a); It != SectionDataCache.end()) {
 
  463    auto &Buf = It->second;
 
  464    return ArrayRef<uint8_t>(Buf);
 
  467  uint32_t DefEsdId = getSectionDefEsdId(Sec);
 
  469  const uint8_t *EdEsdRecord = getSectionEdEsdRecord(Sec);
 
  470  bool FillBytePresent;
 
  472  uint8_t FillByte = 
'\0';
 
  477  SmallVector<uint8_t> 
Data(SectionSize, FillByte);
 
  480  for (
const uint8_t *TxtRecordInt : TextPtrs) {
 
  481    const uint8_t *TxtRecordPtr = TxtRecordInt;
 
  486    if (TxtEsdId != DefEsdId)
 
  489    uint32_t TxtDataOffset;
 
  492    uint16_t TxtDataSize;
 
  495    LLVM_DEBUG(
dbgs() << 
"Record offset " << TxtDataOffset << 
", data size " 
  496                      << TxtDataSize << 
"\n");
 
  498    SmallString<256> CompleteData;
 
  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  auto &Cache = SectionDataCache[Sec.
d.
a];
 
  508  return ArrayRef<uint8_t>(Cache);
 
  511uint64_t GOFFObjectFile::getSectionAlignment(
DataRefImpl Sec)
 const {
 
  512  const uint8_t *EsdRecord = getSectionEdEsdRecord(Sec);
 
  515  return 1ULL << 
static_cast<uint64_t
>(Pow2Alignment);
 
  518bool GOFFObjectFile::isSectionText(
DataRefImpl Sec)
 const {
 
  519  const uint8_t *EsdRecord = getSectionEdEsdRecord(Sec);
 
  525bool GOFFObjectFile::isSectionData(
DataRefImpl Sec)
 const {
 
  526  const uint8_t *EsdRecord = getSectionEdEsdRecord(Sec);
 
  533  const uint8_t *EsdRecord = getSectionEdEsdRecord(Sec);
 
 
  540  if (!isSectionData(Sec))
 
  543  const uint8_t *EsdRecord = getSectionEdEsdRecord(Sec);
 
 
  557  moveSectionNext(Sec);
 
 
  567  for (
uint32_t I = Symb.
d.
a + 1, E = EsdPtrs.size(); 
I < E; ++
I) {
 
  568    if (
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(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
 
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
 
FunctionLoweringInfo::StatepointRelocationRecord RecordType
 
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.
 
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
 
void append(StringRef RHS)
Append from a StringRef.
 
void reserve(size_type N)
 
pointer data()
Return a pointer to the vector's buffer, even if empty().
 
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)
 
const uint8_t * base() const
 
static Expected< std::unique_ptr< ObjectFile > > createGOFFObjectFile(MemoryBufferRef Object)
 
ObjectFile(unsigned int Type, MemoryBufferRef Source)
 
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)
 
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.
 
LLVM_ABI 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.
 
FunctionAddr VTableAddr uintptr_t uintptr_t DataSize
 
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
 
LLVM_ABI 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.
 
struct llvm::object::DataRefImpl::@005117267142344013370254144343227032034000327225 d