+ uint8_t StorageClass;
+ uint8_t NumberOfAuxSymbols;
+};
+
+typedef coff_symbol<support::ulittle16_t> coff_symbol16;
+typedef coff_symbol<support::ulittle32_t> coff_symbol32;
+
+// Contains only common parts of coff_symbol16 and coff_symbol32.
+struct coff_symbol_generic {
+ union {
+ char ShortName[COFF::NameSize];
+ StringTableOffset Offset;
+ } Name;
+ support::ulittle32_t Value;
+};
+
+class COFFSymbolRef {
+public:
+ COFFSymbolRef(const coff_symbol16 *CS) : CS16(CS), CS32(nullptr) {}
+ COFFSymbolRef(const coff_symbol32 *CS) : CS16(nullptr), CS32(CS) {}
+ COFFSymbolRef() : CS16(nullptr), CS32(nullptr) {}
+
+ const void *getRawPtr() const {
+ return CS16 ? static_cast<const void *>(CS16) : CS32;
+ }
+
+ const coff_symbol_generic *getGeneric() const {
+ if (CS16)
+ return reinterpret_cast<const coff_symbol_generic *>(CS16);
+ return reinterpret_cast<const coff_symbol_generic *>(CS32);
+ }
+
+ friend bool operator<(COFFSymbolRef A, COFFSymbolRef B) {
+ return A.getRawPtr() < B.getRawPtr();
+ }
+
+ bool isBigObj() const {
+ if (CS16)
+ return false;
+ if (CS32)
+ return true;
+ llvm_unreachable("COFFSymbolRef points to nothing!");
+ }
+
+ const char *getShortName() const {
+ return CS16 ? CS16->Name.ShortName : CS32->Name.ShortName;
+ }
+
+ const StringTableOffset &getStringTableOffset() const {
+ assert(isSet() && "COFFSymbolRef points to nothing!");
+ return CS16 ? CS16->Name.Offset : CS32->Name.Offset;
+ }
+
+ uint32_t getValue() const { return CS16 ? CS16->Value : CS32->Value; }
+
+ int32_t getSectionNumber() const {
+ assert(isSet() && "COFFSymbolRef points to nothing!");
+ if (CS16) {
+ // Reserved sections are returned as negative numbers.
+ if (CS16->SectionNumber <= COFF::MaxNumberOfSections16)
+ return CS16->SectionNumber;
+ return static_cast<int16_t>(CS16->SectionNumber);
+ }
+ return static_cast<int32_t>(CS32->SectionNumber);
+ }
+
+ uint16_t getType() const {
+ assert(isSet() && "COFFSymbolRef points to nothing!");
+ return CS16 ? CS16->Type : CS32->Type;
+ }
+
+ uint8_t getStorageClass() const {
+ assert(isSet() && "COFFSymbolRef points to nothing!");
+ return CS16 ? CS16->StorageClass : CS32->StorageClass;
+ }
+
+ uint8_t getNumberOfAuxSymbols() const {
+ assert(isSet() && "COFFSymbolRef points to nothing!");
+ return CS16 ? CS16->NumberOfAuxSymbols : CS32->NumberOfAuxSymbols;
+ }
+
+ uint8_t getBaseType() const { return getType() & 0x0F; }
+
+ uint8_t getComplexType() const {
+ return (getType() & 0xF0) >> COFF::SCT_COMPLEX_TYPE_SHIFT;
+ }
+
+ bool isAbsolute() const {
+ return getSectionNumber() == -1;
+ }