+std::error_code DelayImportDirectoryEntryRef::
+getImportAddress(int AddrIndex, uint64_t &Result) const {
+ uint32_t RVA = Table[Index].DelayImportAddressTable +
+ AddrIndex * (OwningObject->is64() ? 8 : 4);
+ uintptr_t IntPtr = 0;
+ if (std::error_code EC = OwningObject->getRvaPtr(RVA, IntPtr))
+ return EC;
+ if (OwningObject->is64())
+ Result = *reinterpret_cast<const ulittle64_t *>(IntPtr);
+ else
+ Result = *reinterpret_cast<const ulittle32_t *>(IntPtr);
+ return object_error::success;
+}
+
+bool ExportDirectoryEntryRef::
+operator==(const ExportDirectoryEntryRef &Other) const {
+ return ExportTable == Other.ExportTable && Index == Other.Index;
+}
+
+void ExportDirectoryEntryRef::moveNext() {
+ ++Index;
+}
+
+// Returns the name of the current export symbol. If the symbol is exported only
+// by ordinal, the empty string is set as a result.
+std::error_code ExportDirectoryEntryRef::getDllName(StringRef &Result) const {
+ uintptr_t IntPtr = 0;
+ if (std::error_code EC =
+ OwningObject->getRvaPtr(ExportTable->NameRVA, IntPtr))
+ return EC;
+ Result = StringRef(reinterpret_cast<const char *>(IntPtr));
+ return object_error::success;
+}
+
+// Returns the starting ordinal number.
+std::error_code
+ExportDirectoryEntryRef::getOrdinalBase(uint32_t &Result) const {
+ Result = ExportTable->OrdinalBase;
+ return object_error::success;
+}
+
+// Returns the export ordinal of the current export symbol.
+std::error_code ExportDirectoryEntryRef::getOrdinal(uint32_t &Result) const {
+ Result = ExportTable->OrdinalBase + Index;
+ return object_error::success;
+}
+
+// Returns the address of the current export symbol.
+std::error_code ExportDirectoryEntryRef::getExportRVA(uint32_t &Result) const {
+ uintptr_t IntPtr = 0;
+ if (std::error_code EC =
+ OwningObject->getRvaPtr(ExportTable->ExportAddressTableRVA, IntPtr))
+ return EC;
+ const export_address_table_entry *entry =
+ reinterpret_cast<const export_address_table_entry *>(IntPtr);
+ Result = entry[Index].ExportRVA;
+ return object_error::success;
+}
+
+// Returns the name of the current export symbol. If the symbol is exported only
+// by ordinal, the empty string is set as a result.
+std::error_code
+ExportDirectoryEntryRef::getSymbolName(StringRef &Result) const {
+ uintptr_t IntPtr = 0;
+ if (std::error_code EC =
+ OwningObject->getRvaPtr(ExportTable->OrdinalTableRVA, IntPtr))
+ return EC;
+ const ulittle16_t *Start = reinterpret_cast<const ulittle16_t *>(IntPtr);
+
+ uint32_t NumEntries = ExportTable->NumberOfNamePointers;
+ int Offset = 0;
+ for (const ulittle16_t *I = Start, *E = Start + NumEntries;
+ I < E; ++I, ++Offset) {
+ if (*I != Index)
+ continue;
+ if (std::error_code EC =
+ OwningObject->getRvaPtr(ExportTable->NamePointerRVA, IntPtr))
+ return EC;
+ const ulittle32_t *NamePtr = reinterpret_cast<const ulittle32_t *>(IntPtr);
+ if (std::error_code EC = OwningObject->getRvaPtr(NamePtr[Offset], IntPtr))
+ return EC;
+ Result = StringRef(reinterpret_cast<const char *>(IntPtr));
+ return object_error::success;
+ }
+ Result = "";
+ return object_error::success;
+}
+
+bool ImportedSymbolRef::
+operator==(const ImportedSymbolRef &Other) const {
+ return Entry32 == Other.Entry32 && Entry64 == Other.Entry64
+ && Index == Other.Index;
+}
+
+void ImportedSymbolRef::moveNext() {
+ ++Index;
+}
+
+std::error_code
+ImportedSymbolRef::getSymbolName(StringRef &Result) const {
+ uint32_t RVA;
+ if (Entry32) {
+ // If a symbol is imported only by ordinal, it has no name.
+ if (Entry32[Index].isOrdinal())
+ return object_error::success;
+ RVA = Entry32[Index].getHintNameRVA();
+ } else {
+ if (Entry64[Index].isOrdinal())
+ return object_error::success;
+ RVA = Entry64[Index].getHintNameRVA();
+ }
+ uintptr_t IntPtr = 0;
+ if (std::error_code EC = OwningObject->getRvaPtr(RVA, IntPtr))
+ return EC;
+ // +2 because the first two bytes is hint.
+ Result = StringRef(reinterpret_cast<const char *>(IntPtr + 2));
+ return object_error::success;
+}
+
+std::error_code ImportedSymbolRef::getOrdinal(uint16_t &Result) const {
+ uint32_t RVA;
+ if (Entry32) {
+ if (Entry32[Index].isOrdinal()) {
+ Result = Entry32[Index].getOrdinal();
+ return object_error::success;
+ }
+ RVA = Entry32[Index].getHintNameRVA();
+ } else {
+ if (Entry64[Index].isOrdinal()) {
+ Result = Entry64[Index].getOrdinal();
+ return object_error::success;
+ }
+ RVA = Entry64[Index].getHintNameRVA();