llvm.org GIT mirror llvm / 13b58ec
Object/COFF: Define coff_symbol_generic. If you only need Name and Value fields in the COFF symbol, you don't need to distinguish 32 bit and 64 bit COFF symbols. These fields start at the same offsets and have the same size. This data strucutre is one pointer smaller than COFFSymbolRef thus slightly efficient. I'll use this class in LLD as we create millions of LLD symbol objects that currently contain COFFSymbolRef. Shaving off 8 byte (or 4 byte on 32 bit) from that class actually matters becasue of the number of objects we create in LLD. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@241024 91177308-0d34-0410-b5e6-96231b3b80d8 Rui Ueyama 4 years ago
2 changed file(s) with 27 addition(s) and 6 deletion(s). Raw diff Collapse all Expand all
248248 typedef coff_symbol coff_symbol16;
249249 typedef coff_symbol coff_symbol32;
250250
251 // Contains only common parts of coff_symbol16 and coff_symbol32.
252 struct coff_symbol_generic {
253 union {
254 char ShortName[COFF::NameSize];
255 StringTableOffset Offset;
256 } Name;
257 support::ulittle32_t Value;
258 };
259
251260 class COFFSymbolRef {
252261 public:
253262 COFFSymbolRef(const coff_symbol16 *CS) : CS16(CS), CS32(nullptr) {}
256265
257266 const void *getRawPtr() const {
258267 return CS16 ? static_cast(CS16) : CS32;
268 }
269
270 const coff_symbol_generic *getGeneric() const {
271 if (CS16)
272 return reinterpret_cast(CS16);
273 return reinterpret_cast(CS32);
259274 }
260275
261276 friend bool operator<(COFFSymbolRef A, COFFSymbolRef B) {
743758 return std::error_code();
744759 }
745760 std::error_code getSymbolName(COFFSymbolRef Symbol, StringRef &Res) const;
761 std::error_code getSymbolName(const coff_symbol_generic *Symbol,
762 StringRef &Res) const;
746763
747764 ArrayRef getSymbolAuxData(COFFSymbolRef Symbol) const;
748765
846846
847847 std::error_code COFFObjectFile::getSymbolName(COFFSymbolRef Symbol,
848848 StringRef &Res) const {
849 return getSymbolName(Symbol.getGeneric(), Res);
850 }
851
852 std::error_code COFFObjectFile::getSymbolName(const coff_symbol_generic *Symbol,
853 StringRef &Res) const {
849854 // Check for string table entry. First 4 bytes are 0.
850 if (Symbol.getStringTableOffset().Zeroes == 0) {
851 uint32_t Offset = Symbol.getStringTableOffset().Offset;
852 if (std::error_code EC = getString(Offset, Res))
855 if (Symbol->Name.Offset.Zeroes == 0) {
856 if (std::error_code EC = getString(Symbol->Name.Offset.Offset, Res))
853857 return EC;
854858 return std::error_code();
855859 }
856860
857 if (Symbol.getShortName()[COFF::NameSize - 1] == 0)
861 if (Symbol->Name.ShortName[COFF::NameSize - 1] == 0)
858862 // Null terminated, let ::strlen figure out the length.
859 Res = StringRef(Symbol.getShortName());
863 Res = StringRef(Symbol->Name.ShortName);
860864 else
861865 // Not null terminated, use all 8 bytes.
862 Res = StringRef(Symbol.getShortName(), COFF::NameSize);
866 Res = StringRef(Symbol->Name.ShortName, COFF::NameSize);
863867 return std::error_code();
864868 }
865869