comparison lib/Object/COFFObjectFile.cpp @ 95:afa8332a0e37 LLVM3.8

LLVM 3.8
author Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
date Tue, 13 Oct 2015 17:48:58 +0900
parents 60c9769439b8
children 7d135dc70f03
comparison
equal deleted inserted replaced
84:f3e34b893a5f 95:afa8332a0e37
14 #include "llvm/Object/COFF.h" 14 #include "llvm/Object/COFF.h"
15 #include "llvm/ADT/ArrayRef.h" 15 #include "llvm/ADT/ArrayRef.h"
16 #include "llvm/ADT/SmallString.h" 16 #include "llvm/ADT/SmallString.h"
17 #include "llvm/ADT/StringSwitch.h" 17 #include "llvm/ADT/StringSwitch.h"
18 #include "llvm/ADT/Triple.h" 18 #include "llvm/ADT/Triple.h"
19 #include "llvm/ADT/iterator_range.h"
19 #include "llvm/Support/COFF.h" 20 #include "llvm/Support/COFF.h"
20 #include "llvm/Support/Debug.h" 21 #include "llvm/Support/Debug.h"
21 #include "llvm/Support/raw_ostream.h" 22 #include "llvm/Support/raw_ostream.h"
22 #include <cctype> 23 #include <cctype>
23 #include <limits> 24 #include <limits>
44 if (Addr + Size < Addr || Addr + Size < Size || 45 if (Addr + Size < Addr || Addr + Size < Size ||
45 Addr + Size > uintptr_t(M.getBufferEnd()) || 46 Addr + Size > uintptr_t(M.getBufferEnd()) ||
46 Addr < uintptr_t(M.getBufferStart())) { 47 Addr < uintptr_t(M.getBufferStart())) {
47 return object_error::unexpected_eof; 48 return object_error::unexpected_eof;
48 } 49 }
49 return object_error::success; 50 return std::error_code();
50 } 51 }
51 52
52 // Sets Obj unless any bytes in [addr, addr + size) fall outsize of m. 53 // Sets Obj unless any bytes in [addr, addr + size) fall outsize of m.
53 // Returns unexpected_eof if error. 54 // Returns unexpected_eof if error.
54 template <typename T> 55 template <typename T>
57 const uint64_t Size = sizeof(T)) { 58 const uint64_t Size = sizeof(T)) {
58 uintptr_t Addr = uintptr_t(Ptr); 59 uintptr_t Addr = uintptr_t(Ptr);
59 if (std::error_code EC = checkOffset(M, Addr, Size)) 60 if (std::error_code EC = checkOffset(M, Addr, Size))
60 return EC; 61 return EC;
61 Obj = reinterpret_cast<const T *>(Addr); 62 Obj = reinterpret_cast<const T *>(Addr);
62 return object_error::success; 63 return std::error_code();
63 } 64 }
64 65
65 // Decode a string table entry in base 64 (//AAAAAA). Expects \arg Str without 66 // Decode a string table entry in base 64 (//AAAAAA). Expects \arg Str without
66 // prefixed slashes. 67 // prefixed slashes.
67 static bool decodeBase64StringEntry(StringRef Str, uint32_t &Result) { 68 static bool decodeBase64StringEntry(StringRef Str, uint32_t &Result) {
142 } else { 143 } else {
143 llvm_unreachable("no symbol table pointer!"); 144 llvm_unreachable("no symbol table pointer!");
144 } 145 }
145 } 146 }
146 147
147 std::error_code COFFObjectFile::getSymbolName(DataRefImpl Ref, 148 ErrorOr<StringRef> COFFObjectFile::getSymbolName(DataRefImpl Ref) const {
148 StringRef &Result) const {
149 COFFSymbolRef Symb = getCOFFSymbol(Ref); 149 COFFSymbolRef Symb = getCOFFSymbol(Ref);
150 return getSymbolName(Symb, Result); 150 StringRef Result;
151 } 151 std::error_code EC = getSymbolName(Symb, Result);
152 152 if (EC)
153 std::error_code COFFObjectFile::getSymbolAddress(DataRefImpl Ref, 153 return EC;
154 uint64_t &Result) const { 154 return Result;
155 COFFSymbolRef Symb = getCOFFSymbol(Ref); 155 }
156 156
157 if (Symb.isAnyUndefined()) { 157 uint64_t COFFObjectFile::getSymbolValueImpl(DataRefImpl Ref) const {
158 Result = UnknownAddressOrSize; 158 return getCOFFSymbol(Ref).getValue();
159 return object_error::success; 159 }
160 } 160
161 if (Symb.isCommon()) { 161 ErrorOr<uint64_t> COFFObjectFile::getSymbolAddress(DataRefImpl Ref) const {
162 Result = UnknownAddressOrSize; 162 uint64_t Result = getSymbolValue(Ref);
163 return object_error::success;
164 }
165 int32_t SectionNumber = Symb.getSectionNumber();
166 if (!COFF::isReservedSectionNumber(SectionNumber)) {
167 const coff_section *Section = nullptr;
168 if (std::error_code EC = getSection(SectionNumber, Section))
169 return EC;
170
171 Result = Section->VirtualAddress + Symb.getValue();
172 return object_error::success;
173 }
174
175 Result = Symb.getValue();
176 return object_error::success;
177 }
178
179 std::error_code COFFObjectFile::getSymbolType(DataRefImpl Ref,
180 SymbolRef::Type &Result) const {
181 COFFSymbolRef Symb = getCOFFSymbol(Ref); 163 COFFSymbolRef Symb = getCOFFSymbol(Ref);
182 int32_t SectionNumber = Symb.getSectionNumber(); 164 int32_t SectionNumber = Symb.getSectionNumber();
183 Result = SymbolRef::ST_Other; 165
184 166 if (Symb.isAnyUndefined() || Symb.isCommon() ||
185 if (Symb.isAnyUndefined()) { 167 COFF::isReservedSectionNumber(SectionNumber))
186 Result = SymbolRef::ST_Unknown; 168 return Result;
187 } else if (Symb.isFunctionDefinition()) { 169
188 Result = SymbolRef::ST_Function; 170 const coff_section *Section = nullptr;
189 } else if (Symb.isCommon()) { 171 if (std::error_code EC = getSection(SectionNumber, Section))
190 Result = SymbolRef::ST_Data; 172 return EC;
191 } else if (Symb.isFileRecord()) { 173 Result += Section->VirtualAddress;
192 Result = SymbolRef::ST_File; 174
193 } else if (SectionNumber == COFF::IMAGE_SYM_DEBUG) { 175 // The section VirtualAddress does not include ImageBase, and we want to
194 Result = SymbolRef::ST_Debug; 176 // return virtual addresses.
195 } else if (!COFF::isReservedSectionNumber(SectionNumber)) { 177 Result += getImageBase();
196 const coff_section *Section = nullptr; 178
197 if (std::error_code EC = getSection(SectionNumber, Section)) 179 return Result;
198 return EC; 180 }
199 uint32_t Characteristics = Section->Characteristics; 181
200 if (Characteristics & COFF::IMAGE_SCN_CNT_CODE) 182 SymbolRef::Type COFFObjectFile::getSymbolType(DataRefImpl Ref) const {
201 Result = SymbolRef::ST_Function; 183 COFFSymbolRef Symb = getCOFFSymbol(Ref);
202 else if (Characteristics & (COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 184 int32_t SectionNumber = Symb.getSectionNumber();
203 COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA)) 185
204 Result = SymbolRef::ST_Data; 186 if (Symb.getComplexType() == COFF::IMAGE_SYM_DTYPE_FUNCTION)
205 } 187 return SymbolRef::ST_Function;
206 return object_error::success; 188 if (Symb.isAnyUndefined())
189 return SymbolRef::ST_Unknown;
190 if (Symb.isCommon())
191 return SymbolRef::ST_Data;
192 if (Symb.isFileRecord())
193 return SymbolRef::ST_File;
194
195 // TODO: perhaps we need a new symbol type ST_Section.
196 if (SectionNumber == COFF::IMAGE_SYM_DEBUG || Symb.isSectionDefinition())
197 return SymbolRef::ST_Debug;
198
199 if (!COFF::isReservedSectionNumber(SectionNumber))
200 return SymbolRef::ST_Data;
201
202 return SymbolRef::ST_Other;
207 } 203 }
208 204
209 uint32_t COFFObjectFile::getSymbolFlags(DataRefImpl Ref) const { 205 uint32_t COFFObjectFile::getSymbolFlags(DataRefImpl Ref) const {
210 COFFSymbolRef Symb = getCOFFSymbol(Ref); 206 COFFSymbolRef Symb = getCOFFSymbol(Ref);
211 uint32_t Result = SymbolRef::SF_None; 207 uint32_t Result = SymbolRef::SF_None;
232 Result |= SymbolRef::SF_Undefined; 228 Result |= SymbolRef::SF_Undefined;
233 229
234 return Result; 230 return Result;
235 } 231 }
236 232
237 std::error_code COFFObjectFile::getSymbolSize(DataRefImpl Ref, 233 uint64_t COFFObjectFile::getCommonSymbolSizeImpl(DataRefImpl Ref) const {
238 uint64_t &Result) const {
239 COFFSymbolRef Symb = getCOFFSymbol(Ref); 234 COFFSymbolRef Symb = getCOFFSymbol(Ref);
240 235 return Symb.getValue();
241 if (Symb.isAnyUndefined()) { 236 }
242 Result = UnknownAddressOrSize; 237
243 return object_error::success; 238 ErrorOr<section_iterator>
244 } 239 COFFObjectFile::getSymbolSection(DataRefImpl Ref) const {
245 if (Symb.isCommon()) {
246 Result = Symb.getValue();
247 return object_error::success;
248 }
249
250 // Let's attempt to get the size of the symbol by looking at the address of
251 // the symbol after the symbol in question.
252 uint64_t SymbAddr;
253 if (std::error_code EC = getSymbolAddress(Ref, SymbAddr))
254 return EC;
255 int32_t SectionNumber = Symb.getSectionNumber();
256 if (COFF::isReservedSectionNumber(SectionNumber)) {
257 // Absolute and debug symbols aren't sorted in any interesting way.
258 Result = 0;
259 return object_error::success;
260 }
261 const section_iterator SecEnd = section_end();
262 uint64_t AfterAddr = UnknownAddressOrSize;
263 for (const symbol_iterator &SymbI : symbols()) {
264 section_iterator SecI = SecEnd;
265 if (std::error_code EC = SymbI->getSection(SecI))
266 return EC;
267 // Check the symbol's section, skip it if it's in the wrong section.
268 // First, make sure it is in any section.
269 if (SecI == SecEnd)
270 continue;
271 // Second, make sure it is in the same section as the symbol in question.
272 if (!sectionContainsSymbol(SecI->getRawDataRefImpl(), Ref))
273 continue;
274 uint64_t Addr;
275 if (std::error_code EC = SymbI->getAddress(Addr))
276 return EC;
277 // We want to compare our symbol in question with the closest possible
278 // symbol that comes after.
279 if (AfterAddr > Addr && Addr > SymbAddr)
280 AfterAddr = Addr;
281 }
282 if (AfterAddr == UnknownAddressOrSize) {
283 // No symbol comes after this one, assume that everything after our symbol
284 // is part of it.
285 const coff_section *Section = nullptr;
286 if (std::error_code EC = getSection(SectionNumber, Section))
287 return EC;
288 Result = Section->SizeOfRawData - Symb.getValue();
289 } else {
290 // Take the difference between our symbol and the symbol that comes after
291 // our symbol.
292 Result = AfterAddr - SymbAddr;
293 }
294
295 return object_error::success;
296 }
297
298 std::error_code
299 COFFObjectFile::getSymbolSection(DataRefImpl Ref,
300 section_iterator &Result) const {
301 COFFSymbolRef Symb = getCOFFSymbol(Ref); 240 COFFSymbolRef Symb = getCOFFSymbol(Ref);
302 if (COFF::isReservedSectionNumber(Symb.getSectionNumber())) { 241 if (COFF::isReservedSectionNumber(Symb.getSectionNumber()))
303 Result = section_end(); 242 return section_end();
304 } else { 243 const coff_section *Sec = nullptr;
305 const coff_section *Sec = nullptr; 244 if (std::error_code EC = getSection(Symb.getSectionNumber(), Sec))
306 if (std::error_code EC = getSection(Symb.getSectionNumber(), Sec)) 245 return EC;
307 return EC; 246 DataRefImpl Ret;
308 DataRefImpl Ref; 247 Ret.p = reinterpret_cast<uintptr_t>(Sec);
309 Ref.p = reinterpret_cast<uintptr_t>(Sec); 248 return section_iterator(SectionRef(Ret, this));
310 Result = section_iterator(SectionRef(Ref, this)); 249 }
311 } 250
312 return object_error::success; 251 unsigned COFFObjectFile::getSymbolSectionID(SymbolRef Sym) const {
252 COFFSymbolRef Symb = getCOFFSymbol(Sym.getRawDataRefImpl());
253 return Symb.getSectionNumber();
313 } 254 }
314 255
315 void COFFObjectFile::moveSectionNext(DataRefImpl &Ref) const { 256 void COFFObjectFile::moveSectionNext(DataRefImpl &Ref) const {
316 const coff_section *Sec = toSec(Ref); 257 const coff_section *Sec = toSec(Ref);
317 Sec += 1; 258 Sec += 1;
324 return getSectionName(Sec, Result); 265 return getSectionName(Sec, Result);
325 } 266 }
326 267
327 uint64_t COFFObjectFile::getSectionAddress(DataRefImpl Ref) const { 268 uint64_t COFFObjectFile::getSectionAddress(DataRefImpl Ref) const {
328 const coff_section *Sec = toSec(Ref); 269 const coff_section *Sec = toSec(Ref);
329 return Sec->VirtualAddress; 270 uint64_t Result = Sec->VirtualAddress;
271
272 // The section VirtualAddress does not include ImageBase, and we want to
273 // return virtual addresses.
274 Result += getImageBase();
275 return Result;
330 } 276 }
331 277
332 uint64_t COFFObjectFile::getSectionSize(DataRefImpl Ref) const { 278 uint64_t COFFObjectFile::getSectionSize(DataRefImpl Ref) const {
333 return getSectionSize(toSec(Ref)); 279 return getSectionSize(toSec(Ref));
334 } 280 }
357 return Sec->Characteristics & COFF::IMAGE_SCN_CNT_INITIALIZED_DATA; 303 return Sec->Characteristics & COFF::IMAGE_SCN_CNT_INITIALIZED_DATA;
358 } 304 }
359 305
360 bool COFFObjectFile::isSectionBSS(DataRefImpl Ref) const { 306 bool COFFObjectFile::isSectionBSS(DataRefImpl Ref) const {
361 const coff_section *Sec = toSec(Ref); 307 const coff_section *Sec = toSec(Ref);
362 return Sec->Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA; 308 const uint32_t BssFlags = COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA |
309 COFF::IMAGE_SCN_MEM_READ |
310 COFF::IMAGE_SCN_MEM_WRITE;
311 return (Sec->Characteristics & BssFlags) == BssFlags;
312 }
313
314 unsigned COFFObjectFile::getSectionID(SectionRef Sec) const {
315 uintptr_t Offset =
316 uintptr_t(Sec.getRawDataRefImpl().p) - uintptr_t(SectionTable);
317 assert((Offset % sizeof(coff_section)) == 0);
318 return (Offset / sizeof(coff_section)) + 1;
363 } 319 }
364 320
365 bool COFFObjectFile::isSectionVirtual(DataRefImpl Ref) const { 321 bool COFFObjectFile::isSectionVirtual(DataRefImpl Ref) const {
366 const coff_section *Sec = toSec(Ref); 322 const coff_section *Sec = toSec(Ref);
367 return Sec->Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA; 323 // In COFF, a virtual section won't have any in-file
368 } 324 // content, so the file pointer to the content will be zero.
369 325 return Sec->PointerToRawData == 0;
370 bool COFFObjectFile::sectionContainsSymbol(DataRefImpl SecRef,
371 DataRefImpl SymbRef) const {
372 const coff_section *Sec = toSec(SecRef);
373 COFFSymbolRef Symb = getCOFFSymbol(SymbRef);
374 int32_t SecNumber = (Sec - SectionTable) + 1;
375 return SecNumber == Symb.getSectionNumber();
376 } 326 }
377 327
378 static uint32_t getNumberOfRelocations(const coff_section *Sec, 328 static uint32_t getNumberOfRelocations(const coff_section *Sec,
379 MemoryBufferRef M, const uint8_t *base) { 329 MemoryBufferRef M, const uint8_t *base) {
380 // The field for the number of relocations in COFF section table is only 330 // The field for the number of relocations in COFF section table is only
410 } 360 }
411 361
412 relocation_iterator COFFObjectFile::section_rel_begin(DataRefImpl Ref) const { 362 relocation_iterator COFFObjectFile::section_rel_begin(DataRefImpl Ref) const {
413 const coff_section *Sec = toSec(Ref); 363 const coff_section *Sec = toSec(Ref);
414 const coff_relocation *begin = getFirstReloc(Sec, Data, base()); 364 const coff_relocation *begin = getFirstReloc(Sec, Data, base());
365 if (begin && Sec->VirtualAddress != 0)
366 report_fatal_error("Sections with relocations should have an address of 0");
415 DataRefImpl Ret; 367 DataRefImpl Ret;
416 Ret.p = reinterpret_cast<uintptr_t>(begin); 368 Ret.p = reinterpret_cast<uintptr_t>(begin);
417 return relocation_iterator(RelocationRef(Ret, this)); 369 return relocation_iterator(RelocationRef(Ret, this));
418 } 370 }
419 371
461 StringTableSize = 4; 413 StringTableSize = 4;
462 414
463 // Check that the string table is null terminated if has any in it. 415 // Check that the string table is null terminated if has any in it.
464 if (StringTableSize > 4 && StringTable[StringTableSize - 1] != 0) 416 if (StringTableSize > 4 && StringTable[StringTableSize - 1] != 0)
465 return object_error::parse_failed; 417 return object_error::parse_failed;
466 return object_error::success; 418 return std::error_code();
419 }
420
421 uint64_t COFFObjectFile::getImageBase() const {
422 if (PE32Header)
423 return PE32Header->ImageBase;
424 else if (PE32PlusHeader)
425 return PE32PlusHeader->ImageBase;
426 // This actually comes up in practice.
427 return 0;
467 } 428 }
468 429
469 // Returns the file offset for the given VA. 430 // Returns the file offset for the given VA.
470 std::error_code COFFObjectFile::getVaPtr(uint64_t Addr, uintptr_t &Res) const { 431 std::error_code COFFObjectFile::getVaPtr(uint64_t Addr, uintptr_t &Res) const {
471 uint64_t ImageBase = PE32Header ? (uint64_t)PE32Header->ImageBase 432 uint64_t ImageBase = getImageBase();
472 : (uint64_t)PE32PlusHeader->ImageBase;
473 uint64_t Rva = Addr - ImageBase; 433 uint64_t Rva = Addr - ImageBase;
474 assert(Rva <= UINT32_MAX); 434 assert(Rva <= UINT32_MAX);
475 return getRvaPtr((uint32_t)Rva, Res); 435 return getRvaPtr((uint32_t)Rva, Res);
476 } 436 }
477 437
482 uint32_t SectionStart = Section->VirtualAddress; 442 uint32_t SectionStart = Section->VirtualAddress;
483 uint32_t SectionEnd = Section->VirtualAddress + Section->VirtualSize; 443 uint32_t SectionEnd = Section->VirtualAddress + Section->VirtualSize;
484 if (SectionStart <= Addr && Addr < SectionEnd) { 444 if (SectionStart <= Addr && Addr < SectionEnd) {
485 uint32_t Offset = Addr - SectionStart; 445 uint32_t Offset = Addr - SectionStart;
486 Res = uintptr_t(base()) + Section->PointerToRawData + Offset; 446 Res = uintptr_t(base()) + Section->PointerToRawData + Offset;
487 return object_error::success; 447 return std::error_code();
488 } 448 }
489 } 449 }
490 return object_error::parse_failed; 450 return object_error::parse_failed;
491 } 451 }
492 452
498 if (std::error_code EC = getRvaPtr(Rva, IntPtr)) 458 if (std::error_code EC = getRvaPtr(Rva, IntPtr))
499 return EC; 459 return EC;
500 const uint8_t *Ptr = reinterpret_cast<const uint8_t *>(IntPtr); 460 const uint8_t *Ptr = reinterpret_cast<const uint8_t *>(IntPtr);
501 Hint = *reinterpret_cast<const ulittle16_t *>(Ptr); 461 Hint = *reinterpret_cast<const ulittle16_t *>(Ptr);
502 Name = StringRef(reinterpret_cast<const char *>(Ptr + 2)); 462 Name = StringRef(reinterpret_cast<const char *>(Ptr + 2));
503 return object_error::success; 463 return std::error_code();
504 } 464 }
505 465
506 // Find the import table. 466 // Find the import table.
507 std::error_code COFFObjectFile::initImportTablePtr() { 467 std::error_code COFFObjectFile::initImportTablePtr() {
508 // First, we get the RVA of the import table. If the file lacks a pointer to 468 // First, we get the RVA of the import table. If the file lacks a pointer to
509 // the import table, do nothing. 469 // the import table, do nothing.
510 const data_directory *DataEntry; 470 const data_directory *DataEntry;
511 if (getDataDirectory(COFF::IMPORT_TABLE, DataEntry)) 471 if (getDataDirectory(COFF::IMPORT_TABLE, DataEntry))
512 return object_error::success; 472 return std::error_code();
513 473
514 // Do nothing if the pointer to import table is NULL. 474 // Do nothing if the pointer to import table is NULL.
515 if (DataEntry->RelativeVirtualAddress == 0) 475 if (DataEntry->RelativeVirtualAddress == 0)
516 return object_error::success; 476 return std::error_code();
517 477
518 uint32_t ImportTableRva = DataEntry->RelativeVirtualAddress; 478 uint32_t ImportTableRva = DataEntry->RelativeVirtualAddress;
519 // -1 because the last entry is the null entry. 479 // -1 because the last entry is the null entry.
520 NumberOfImportDirectory = DataEntry->Size / 480 NumberOfImportDirectory = DataEntry->Size /
521 sizeof(import_directory_table_entry) - 1; 481 sizeof(import_directory_table_entry) - 1;
525 uintptr_t IntPtr = 0; 485 uintptr_t IntPtr = 0;
526 if (std::error_code EC = getRvaPtr(ImportTableRva, IntPtr)) 486 if (std::error_code EC = getRvaPtr(ImportTableRva, IntPtr))
527 return EC; 487 return EC;
528 ImportDirectory = reinterpret_cast< 488 ImportDirectory = reinterpret_cast<
529 const import_directory_table_entry *>(IntPtr); 489 const import_directory_table_entry *>(IntPtr);
530 return object_error::success; 490 return std::error_code();
531 } 491 }
532 492
533 // Initializes DelayImportDirectory and NumberOfDelayImportDirectory. 493 // Initializes DelayImportDirectory and NumberOfDelayImportDirectory.
534 std::error_code COFFObjectFile::initDelayImportTablePtr() { 494 std::error_code COFFObjectFile::initDelayImportTablePtr() {
535 const data_directory *DataEntry; 495 const data_directory *DataEntry;
536 if (getDataDirectory(COFF::DELAY_IMPORT_DESCRIPTOR, DataEntry)) 496 if (getDataDirectory(COFF::DELAY_IMPORT_DESCRIPTOR, DataEntry))
537 return object_error::success; 497 return std::error_code();
538 if (DataEntry->RelativeVirtualAddress == 0) 498 if (DataEntry->RelativeVirtualAddress == 0)
539 return object_error::success; 499 return std::error_code();
540 500
541 uint32_t RVA = DataEntry->RelativeVirtualAddress; 501 uint32_t RVA = DataEntry->RelativeVirtualAddress;
542 NumberOfDelayImportDirectory = DataEntry->Size / 502 NumberOfDelayImportDirectory = DataEntry->Size /
543 sizeof(delay_import_directory_table_entry) - 1; 503 sizeof(delay_import_directory_table_entry) - 1;
544 504
545 uintptr_t IntPtr = 0; 505 uintptr_t IntPtr = 0;
546 if (std::error_code EC = getRvaPtr(RVA, IntPtr)) 506 if (std::error_code EC = getRvaPtr(RVA, IntPtr))
547 return EC; 507 return EC;
548 DelayImportDirectory = reinterpret_cast< 508 DelayImportDirectory = reinterpret_cast<
549 const delay_import_directory_table_entry *>(IntPtr); 509 const delay_import_directory_table_entry *>(IntPtr);
550 return object_error::success; 510 return std::error_code();
551 } 511 }
552 512
553 // Find the export table. 513 // Find the export table.
554 std::error_code COFFObjectFile::initExportTablePtr() { 514 std::error_code COFFObjectFile::initExportTablePtr() {
555 // First, we get the RVA of the export table. If the file lacks a pointer to 515 // First, we get the RVA of the export table. If the file lacks a pointer to
556 // the export table, do nothing. 516 // the export table, do nothing.
557 const data_directory *DataEntry; 517 const data_directory *DataEntry;
558 if (getDataDirectory(COFF::EXPORT_TABLE, DataEntry)) 518 if (getDataDirectory(COFF::EXPORT_TABLE, DataEntry))
559 return object_error::success; 519 return std::error_code();
560 520
561 // Do nothing if the pointer to export table is NULL. 521 // Do nothing if the pointer to export table is NULL.
562 if (DataEntry->RelativeVirtualAddress == 0) 522 if (DataEntry->RelativeVirtualAddress == 0)
563 return object_error::success; 523 return std::error_code();
564 524
565 uint32_t ExportTableRva = DataEntry->RelativeVirtualAddress; 525 uint32_t ExportTableRva = DataEntry->RelativeVirtualAddress;
566 uintptr_t IntPtr = 0; 526 uintptr_t IntPtr = 0;
567 if (std::error_code EC = getRvaPtr(ExportTableRva, IntPtr)) 527 if (std::error_code EC = getRvaPtr(ExportTableRva, IntPtr))
568 return EC; 528 return EC;
569 ExportDirectory = 529 ExportDirectory =
570 reinterpret_cast<const export_directory_table_entry *>(IntPtr); 530 reinterpret_cast<const export_directory_table_entry *>(IntPtr);
571 return object_error::success; 531 return std::error_code();
572 } 532 }
573 533
574 std::error_code COFFObjectFile::initBaseRelocPtr() { 534 std::error_code COFFObjectFile::initBaseRelocPtr() {
575 const data_directory *DataEntry; 535 const data_directory *DataEntry;
576 if (getDataDirectory(COFF::BASE_RELOCATION_TABLE, DataEntry)) 536 if (getDataDirectory(COFF::BASE_RELOCATION_TABLE, DataEntry))
577 return object_error::success; 537 return std::error_code();
578 if (DataEntry->RelativeVirtualAddress == 0) 538 if (DataEntry->RelativeVirtualAddress == 0)
579 return object_error::success; 539 return std::error_code();
580 540
581 uintptr_t IntPtr = 0; 541 uintptr_t IntPtr = 0;
582 if (std::error_code EC = getRvaPtr(DataEntry->RelativeVirtualAddress, IntPtr)) 542 if (std::error_code EC = getRvaPtr(DataEntry->RelativeVirtualAddress, IntPtr))
583 return EC; 543 return EC;
584 BaseRelocHeader = reinterpret_cast<const coff_base_reloc_block_header *>( 544 BaseRelocHeader = reinterpret_cast<const coff_base_reloc_block_header *>(
585 IntPtr); 545 IntPtr);
586 BaseRelocEnd = reinterpret_cast<coff_base_reloc_block_header *>( 546 BaseRelocEnd = reinterpret_cast<coff_base_reloc_block_header *>(
587 IntPtr + DataEntry->Size); 547 IntPtr + DataEntry->Size);
588 return object_error::success; 548 return std::error_code();
589 } 549 }
590 550
591 COFFObjectFile::COFFObjectFile(MemoryBufferRef Object, std::error_code &EC) 551 COFFObjectFile::COFFObjectFile(MemoryBufferRef Object, std::error_code &EC)
592 : ObjectFile(Binary::ID_COFF, Object), COFFHeader(nullptr), 552 : ObjectFile(Binary::ID_COFF, Object), COFFHeader(nullptr),
593 COFFBigObjHeader(nullptr), PE32Header(nullptr), PE32PlusHeader(nullptr), 553 COFFBigObjHeader(nullptr), PE32Header(nullptr), PE32PlusHeader(nullptr),
648 } 608 }
649 } 609 }
650 if (COFFHeader) { 610 if (COFFHeader) {
651 // The prior checkSize call may have failed. This isn't a hard error 611 // The prior checkSize call may have failed. This isn't a hard error
652 // because we were just trying to sniff out bigobj. 612 // because we were just trying to sniff out bigobj.
653 EC = object_error::success; 613 EC = std::error_code();
654 CurPtr += sizeof(coff_file_header); 614 CurPtr += sizeof(coff_file_header);
655 615
656 if (COFFHeader->isImportLibrary()) 616 if (COFFHeader->isImportLibrary())
657 return; 617 return;
658 } 618 }
710 670
711 // Initialize the pointer to the base relocation table. 671 // Initialize the pointer to the base relocation table.
712 if ((EC = initBaseRelocPtr())) 672 if ((EC = initBaseRelocPtr()))
713 return; 673 return;
714 674
715 EC = object_error::success; 675 EC = std::error_code();
716 } 676 }
717 677
718 basic_symbol_iterator COFFObjectFile::symbol_begin_impl() const { 678 basic_symbol_iterator COFFObjectFile::symbol_begin_impl() const {
719 DataRefImpl Ret; 679 DataRefImpl Ret;
720 Ret.p = getSymbolTable(); 680 Ret.p = getSymbolTable();
796 return "COFF-i386"; 756 return "COFF-i386";
797 case COFF::IMAGE_FILE_MACHINE_AMD64: 757 case COFF::IMAGE_FILE_MACHINE_AMD64:
798 return "COFF-x86-64"; 758 return "COFF-x86-64";
799 case COFF::IMAGE_FILE_MACHINE_ARMNT: 759 case COFF::IMAGE_FILE_MACHINE_ARMNT:
800 return "COFF-ARM"; 760 return "COFF-ARM";
761 case COFF::IMAGE_FILE_MACHINE_ARM64:
762 return "COFF-ARM64";
801 default: 763 default:
802 return "COFF-<unknown arch>"; 764 return "COFF-<unknown arch>";
803 } 765 }
804 } 766 }
805 767
809 return Triple::x86; 771 return Triple::x86;
810 case COFF::IMAGE_FILE_MACHINE_AMD64: 772 case COFF::IMAGE_FILE_MACHINE_AMD64:
811 return Triple::x86_64; 773 return Triple::x86_64;
812 case COFF::IMAGE_FILE_MACHINE_ARMNT: 774 case COFF::IMAGE_FILE_MACHINE_ARMNT:
813 return Triple::thumb; 775 return Triple::thumb;
776 case COFF::IMAGE_FILE_MACHINE_ARM64:
777 return Triple::aarch64;
814 default: 778 default:
815 return Triple::UnknownArch; 779 return Triple::UnknownArch;
816 } 780 }
817 } 781 }
818 782
836 return make_range(base_reloc_begin(), base_reloc_end()); 800 return make_range(base_reloc_begin(), base_reloc_end());
837 } 801 }
838 802
839 std::error_code COFFObjectFile::getPE32Header(const pe32_header *&Res) const { 803 std::error_code COFFObjectFile::getPE32Header(const pe32_header *&Res) const {
840 Res = PE32Header; 804 Res = PE32Header;
841 return object_error::success; 805 return std::error_code();
842 } 806 }
843 807
844 std::error_code 808 std::error_code
845 COFFObjectFile::getPE32PlusHeader(const pe32plus_header *&Res) const { 809 COFFObjectFile::getPE32PlusHeader(const pe32plus_header *&Res) const {
846 Res = PE32PlusHeader; 810 Res = PE32PlusHeader;
847 return object_error::success; 811 return std::error_code();
848 } 812 }
849 813
850 std::error_code 814 std::error_code
851 COFFObjectFile::getDataDirectory(uint32_t Index, 815 COFFObjectFile::getDataDirectory(uint32_t Index,
852 const data_directory *&Res) const { 816 const data_directory *&Res) const {
861 if (Index >= NumEnt) { 825 if (Index >= NumEnt) {
862 Res = nullptr; 826 Res = nullptr;
863 return object_error::parse_failed; 827 return object_error::parse_failed;
864 } 828 }
865 Res = &DataDirectory[Index]; 829 Res = &DataDirectory[Index];
866 return object_error::success; 830 return std::error_code();
867 } 831 }
868 832
869 std::error_code COFFObjectFile::getSection(int32_t Index, 833 std::error_code COFFObjectFile::getSection(int32_t Index,
870 const coff_section *&Result) const { 834 const coff_section *&Result) const {
871 Result = nullptr; 835 Result = nullptr;
872 if (COFF::isReservedSectionNumber(Index)) 836 if (COFF::isReservedSectionNumber(Index))
873 return object_error::success; 837 return std::error_code();
874 if (static_cast<uint32_t>(Index) <= getNumberOfSections()) { 838 if (static_cast<uint32_t>(Index) <= getNumberOfSections()) {
875 // We already verified the section table data, so no need to check again. 839 // We already verified the section table data, so no need to check again.
876 Result = SectionTable + (Index - 1); 840 Result = SectionTable + (Index - 1);
877 return object_error::success; 841 return std::error_code();
878 } 842 }
879 return object_error::parse_failed; 843 return object_error::parse_failed;
880 } 844 }
881 845
882 std::error_code COFFObjectFile::getString(uint32_t Offset, 846 std::error_code COFFObjectFile::getString(uint32_t Offset,
885 // Tried to get a string from an empty string table. 849 // Tried to get a string from an empty string table.
886 return object_error::parse_failed; 850 return object_error::parse_failed;
887 if (Offset >= StringTableSize) 851 if (Offset >= StringTableSize)
888 return object_error::unexpected_eof; 852 return object_error::unexpected_eof;
889 Result = StringRef(StringTable + Offset); 853 Result = StringRef(StringTable + Offset);
890 return object_error::success; 854 return std::error_code();
891 } 855 }
892 856
893 std::error_code COFFObjectFile::getSymbolName(COFFSymbolRef Symbol, 857 std::error_code COFFObjectFile::getSymbolName(COFFSymbolRef Symbol,
894 StringRef &Res) const { 858 StringRef &Res) const {
859 return getSymbolName(Symbol.getGeneric(), Res);
860 }
861
862 std::error_code COFFObjectFile::getSymbolName(const coff_symbol_generic *Symbol,
863 StringRef &Res) const {
895 // Check for string table entry. First 4 bytes are 0. 864 // Check for string table entry. First 4 bytes are 0.
896 if (Symbol.getStringTableOffset().Zeroes == 0) { 865 if (Symbol->Name.Offset.Zeroes == 0) {
897 uint32_t Offset = Symbol.getStringTableOffset().Offset; 866 if (std::error_code EC = getString(Symbol->Name.Offset.Offset, Res))
898 if (std::error_code EC = getString(Offset, Res))
899 return EC; 867 return EC;
900 return object_error::success; 868 return std::error_code();
901 } 869 }
902 870
903 if (Symbol.getShortName()[COFF::NameSize - 1] == 0) 871 if (Symbol->Name.ShortName[COFF::NameSize - 1] == 0)
904 // Null terminated, let ::strlen figure out the length. 872 // Null terminated, let ::strlen figure out the length.
905 Res = StringRef(Symbol.getShortName()); 873 Res = StringRef(Symbol->Name.ShortName);
906 else 874 else
907 // Not null terminated, use all 8 bytes. 875 // Not null terminated, use all 8 bytes.
908 Res = StringRef(Symbol.getShortName(), COFF::NameSize); 876 Res = StringRef(Symbol->Name.ShortName, COFF::NameSize);
909 return object_error::success; 877 return std::error_code();
910 } 878 }
911 879
912 ArrayRef<uint8_t> 880 ArrayRef<uint8_t>
913 COFFObjectFile::getSymbolAuxData(COFFSymbolRef Symbol) const { 881 COFFObjectFile::getSymbolAuxData(COFFSymbolRef Symbol) const {
914 const uint8_t *Aux = nullptr; 882 const uint8_t *Aux = nullptr;
955 if (std::error_code EC = getString(Offset, Name)) 923 if (std::error_code EC = getString(Offset, Name))
956 return EC; 924 return EC;
957 } 925 }
958 926
959 Res = Name; 927 Res = Name;
960 return object_error::success; 928 return std::error_code();
961 } 929 }
962 930
963 uint64_t COFFObjectFile::getSectionSize(const coff_section *Sec) const { 931 uint64_t COFFObjectFile::getSectionSize(const coff_section *Sec) const {
964 // SizeOfRawData and VirtualSize change what they represent depending on 932 // SizeOfRawData and VirtualSize change what they represent depending on
965 // whether or not we have an executable image. 933 // whether or not we have an executable image.
966 // 934 //
967 // For object files, SizeOfRawData contains the size of section's data; 935 // For object files, SizeOfRawData contains the size of section's data;
968 // VirtualSize is always zero. 936 // VirtualSize should be zero but isn't due to buggy COFF writers.
969 // 937 //
970 // For executables, SizeOfRawData *must* be a multiple of FileAlignment; the 938 // For executables, SizeOfRawData *must* be a multiple of FileAlignment; the
971 // actual section size is in VirtualSize. It is possible for VirtualSize to 939 // actual section size is in VirtualSize. It is possible for VirtualSize to
972 // be greater than SizeOfRawData; the contents past that point should be 940 // be greater than SizeOfRawData; the contents past that point should be
973 // considered to be zero. 941 // considered to be zero.
974 uint32_t SectionSize; 942 if (getDOSHeader())
975 if (Sec->VirtualSize) 943 return std::min(Sec->VirtualSize, Sec->SizeOfRawData);
976 SectionSize = std::min(Sec->VirtualSize, Sec->SizeOfRawData); 944 return Sec->SizeOfRawData;
977 else
978 SectionSize = Sec->SizeOfRawData;
979
980 return SectionSize;
981 } 945 }
982 946
983 std::error_code 947 std::error_code
984 COFFObjectFile::getSectionContents(const coff_section *Sec, 948 COFFObjectFile::getSectionContents(const coff_section *Sec,
985 ArrayRef<uint8_t> &Res) const { 949 ArrayRef<uint8_t> &Res) const {
993 uintptr_t ConStart = uintptr_t(base()) + Sec->PointerToRawData; 957 uintptr_t ConStart = uintptr_t(base()) + Sec->PointerToRawData;
994 uint32_t SectionSize = getSectionSize(Sec); 958 uint32_t SectionSize = getSectionSize(Sec);
995 if (checkOffset(Data, ConStart, SectionSize)) 959 if (checkOffset(Data, ConStart, SectionSize))
996 return object_error::parse_failed; 960 return object_error::parse_failed;
997 Res = makeArrayRef(reinterpret_cast<const uint8_t *>(ConStart), SectionSize); 961 Res = makeArrayRef(reinterpret_cast<const uint8_t *>(ConStart), SectionSize);
998 return object_error::success; 962 return std::error_code();
999 } 963 }
1000 964
1001 const coff_relocation *COFFObjectFile::toRel(DataRefImpl Rel) const { 965 const coff_relocation *COFFObjectFile::toRel(DataRefImpl Rel) const {
1002 return reinterpret_cast<const coff_relocation*>(Rel.p); 966 return reinterpret_cast<const coff_relocation*>(Rel.p);
1003 } 967 }
1005 void COFFObjectFile::moveRelocationNext(DataRefImpl &Rel) const { 969 void COFFObjectFile::moveRelocationNext(DataRefImpl &Rel) const {
1006 Rel.p = reinterpret_cast<uintptr_t>( 970 Rel.p = reinterpret_cast<uintptr_t>(
1007 reinterpret_cast<const coff_relocation*>(Rel.p) + 1); 971 reinterpret_cast<const coff_relocation*>(Rel.p) + 1);
1008 } 972 }
1009 973
1010 std::error_code COFFObjectFile::getRelocationAddress(DataRefImpl Rel, 974 uint64_t COFFObjectFile::getRelocationOffset(DataRefImpl Rel) const {
1011 uint64_t &Res) const {
1012 report_fatal_error("getRelocationAddress not implemented in COFFObjectFile");
1013 }
1014
1015 std::error_code COFFObjectFile::getRelocationOffset(DataRefImpl Rel,
1016 uint64_t &Res) const {
1017 const coff_relocation *R = toRel(Rel); 975 const coff_relocation *R = toRel(Rel);
1018 const support::ulittle32_t *VirtualAddressPtr; 976 return R->VirtualAddress;
1019 if (std::error_code EC =
1020 getObject(VirtualAddressPtr, Data, &R->VirtualAddress))
1021 return EC;
1022 Res = *VirtualAddressPtr;
1023 return object_error::success;
1024 } 977 }
1025 978
1026 symbol_iterator COFFObjectFile::getRelocationSymbol(DataRefImpl Rel) const { 979 symbol_iterator COFFObjectFile::getRelocationSymbol(DataRefImpl Rel) const {
1027 const coff_relocation *R = toRel(Rel); 980 const coff_relocation *R = toRel(Rel);
1028 DataRefImpl Ref; 981 DataRefImpl Ref;
1035 else 988 else
1036 llvm_unreachable("no symbol table pointer!"); 989 llvm_unreachable("no symbol table pointer!");
1037 return symbol_iterator(SymbolRef(Ref, this)); 990 return symbol_iterator(SymbolRef(Ref, this));
1038 } 991 }
1039 992
1040 std::error_code COFFObjectFile::getRelocationType(DataRefImpl Rel, 993 uint64_t COFFObjectFile::getRelocationType(DataRefImpl Rel) const {
1041 uint64_t &Res) const {
1042 const coff_relocation* R = toRel(Rel); 994 const coff_relocation* R = toRel(Rel);
1043 Res = R->Type; 995 return R->Type;
1044 return object_error::success;
1045 } 996 }
1046 997
1047 const coff_section * 998 const coff_section *
1048 COFFObjectFile::getCOFFSection(const SectionRef &Section) const { 999 COFFObjectFile::getCOFFSection(const SectionRef &Section) const {
1049 return toSec(Section.getRawDataRefImpl()); 1000 return toSec(Section.getRawDataRefImpl());
1064 const coff_relocation * 1015 const coff_relocation *
1065 COFFObjectFile::getCOFFRelocation(const RelocationRef &Reloc) const { 1016 COFFObjectFile::getCOFFRelocation(const RelocationRef &Reloc) const {
1066 return toRel(Reloc.getRawDataRefImpl()); 1017 return toRel(Reloc.getRawDataRefImpl());
1067 } 1018 }
1068 1019
1020 iterator_range<const coff_relocation *>
1021 COFFObjectFile::getRelocations(const coff_section *Sec) const {
1022 const coff_relocation *I = getFirstReloc(Sec, Data, base());
1023 const coff_relocation *E = I;
1024 if (I)
1025 E += getNumberOfRelocations(Sec, Data, base());
1026 return make_range(I, E);
1027 }
1028
1069 #define LLVM_COFF_SWITCH_RELOC_TYPE_NAME(reloc_type) \ 1029 #define LLVM_COFF_SWITCH_RELOC_TYPE_NAME(reloc_type) \
1070 case COFF::reloc_type: \ 1030 case COFF::reloc_type: \
1071 Res = #reloc_type; \ 1031 Res = #reloc_type; \
1072 break; 1032 break;
1073 1033
1074 std::error_code 1034 void COFFObjectFile::getRelocationTypeName(
1075 COFFObjectFile::getRelocationTypeName(DataRefImpl Rel, 1035 DataRefImpl Rel, SmallVectorImpl<char> &Result) const {
1076 SmallVectorImpl<char> &Result) const {
1077 const coff_relocation *Reloc = toRel(Rel); 1036 const coff_relocation *Reloc = toRel(Rel);
1078 StringRef Res; 1037 StringRef Res;
1079 switch (getMachine()) { 1038 switch (getMachine()) {
1080 case COFF::IMAGE_FILE_MACHINE_AMD64: 1039 case COFF::IMAGE_FILE_MACHINE_AMD64:
1081 switch (Reloc->Type) { 1040 switch (Reloc->Type) {
1140 break; 1099 break;
1141 default: 1100 default:
1142 Res = "Unknown"; 1101 Res = "Unknown";
1143 } 1102 }
1144 Result.append(Res.begin(), Res.end()); 1103 Result.append(Res.begin(), Res.end());
1145 return object_error::success;
1146 } 1104 }
1147 1105
1148 #undef LLVM_COFF_SWITCH_RELOC_TYPE_NAME 1106 #undef LLVM_COFF_SWITCH_RELOC_TYPE_NAME
1149
1150 std::error_code
1151 COFFObjectFile::getRelocationValueString(DataRefImpl Rel,
1152 SmallVectorImpl<char> &Result) const {
1153 const coff_relocation *Reloc = toRel(Rel);
1154 DataRefImpl Sym;
1155 ErrorOr<COFFSymbolRef> Symb = getSymbol(Reloc->SymbolTableIndex);
1156 if (std::error_code EC = Symb.getError())
1157 return EC;
1158 Sym.p = reinterpret_cast<uintptr_t>(Symb->getRawPtr());
1159 StringRef SymName;
1160 if (std::error_code EC = getSymbolName(Sym, SymName))
1161 return EC;
1162 Result.append(SymName.begin(), SymName.end());
1163 return object_error::success;
1164 }
1165 1107
1166 bool COFFObjectFile::isRelocatableObject() const { 1108 bool COFFObjectFile::isRelocatableObject() const {
1167 return !DataDirectory; 1109 return !DataDirectory;
1168 } 1110 }
1169 1111
1177 } 1119 }
1178 1120
1179 std::error_code ImportDirectoryEntryRef::getImportTableEntry( 1121 std::error_code ImportDirectoryEntryRef::getImportTableEntry(
1180 const import_directory_table_entry *&Result) const { 1122 const import_directory_table_entry *&Result) const {
1181 Result = ImportTable + Index; 1123 Result = ImportTable + Index;
1182 return object_error::success; 1124 return std::error_code();
1183 } 1125 }
1184 1126
1185 static imported_symbol_iterator 1127 static imported_symbol_iterator
1186 makeImportedSymbolIterator(const COFFObjectFile *Object, 1128 makeImportedSymbolIterator(const COFFObjectFile *Object,
1187 uintptr_t Ptr, int Index) { 1129 uintptr_t Ptr, int Index) {
1239 uintptr_t IntPtr = 0; 1181 uintptr_t IntPtr = 0;
1240 if (std::error_code EC = 1182 if (std::error_code EC =
1241 OwningObject->getRvaPtr(ImportTable[Index].NameRVA, IntPtr)) 1183 OwningObject->getRvaPtr(ImportTable[Index].NameRVA, IntPtr))
1242 return EC; 1184 return EC;
1243 Result = StringRef(reinterpret_cast<const char *>(IntPtr)); 1185 Result = StringRef(reinterpret_cast<const char *>(IntPtr));
1244 return object_error::success; 1186 return std::error_code();
1245 } 1187 }
1246 1188
1247 std::error_code 1189 std::error_code
1248 ImportDirectoryEntryRef::getImportLookupTableRVA(uint32_t &Result) const { 1190 ImportDirectoryEntryRef::getImportLookupTableRVA(uint32_t &Result) const {
1249 Result = ImportTable[Index].ImportLookupTableRVA; 1191 Result = ImportTable[Index].ImportLookupTableRVA;
1250 return object_error::success; 1192 return std::error_code();
1251 } 1193 }
1252 1194
1253 std::error_code 1195 std::error_code
1254 ImportDirectoryEntryRef::getImportAddressTableRVA(uint32_t &Result) const { 1196 ImportDirectoryEntryRef::getImportAddressTableRVA(uint32_t &Result) const {
1255 Result = ImportTable[Index].ImportAddressTableRVA; 1197 Result = ImportTable[Index].ImportAddressTableRVA;
1256 return object_error::success; 1198 return std::error_code();
1257 } 1199 }
1258 1200
1259 std::error_code ImportDirectoryEntryRef::getImportLookupEntry( 1201 std::error_code ImportDirectoryEntryRef::getImportLookupEntry(
1260 const import_lookup_table_entry32 *&Result) const { 1202 const import_lookup_table_entry32 *&Result) const {
1261 uintptr_t IntPtr = 0; 1203 uintptr_t IntPtr = 0;
1262 uint32_t RVA = ImportTable[Index].ImportLookupTableRVA; 1204 uint32_t RVA = ImportTable[Index].ImportLookupTableRVA;
1263 if (std::error_code EC = OwningObject->getRvaPtr(RVA, IntPtr)) 1205 if (std::error_code EC = OwningObject->getRvaPtr(RVA, IntPtr))
1264 return EC; 1206 return EC;
1265 Result = reinterpret_cast<const import_lookup_table_entry32 *>(IntPtr); 1207 Result = reinterpret_cast<const import_lookup_table_entry32 *>(IntPtr);
1266 return object_error::success; 1208 return std::error_code();
1267 } 1209 }
1268 1210
1269 bool DelayImportDirectoryEntryRef:: 1211 bool DelayImportDirectoryEntryRef::
1270 operator==(const DelayImportDirectoryEntryRef &Other) const { 1212 operator==(const DelayImportDirectoryEntryRef &Other) const {
1271 return Table == Other.Table && Index == Other.Index; 1213 return Table == Other.Table && Index == Other.Index;
1295 std::error_code DelayImportDirectoryEntryRef::getName(StringRef &Result) const { 1237 std::error_code DelayImportDirectoryEntryRef::getName(StringRef &Result) const {
1296 uintptr_t IntPtr = 0; 1238 uintptr_t IntPtr = 0;
1297 if (std::error_code EC = OwningObject->getRvaPtr(Table[Index].Name, IntPtr)) 1239 if (std::error_code EC = OwningObject->getRvaPtr(Table[Index].Name, IntPtr))
1298 return EC; 1240 return EC;
1299 Result = StringRef(reinterpret_cast<const char *>(IntPtr)); 1241 Result = StringRef(reinterpret_cast<const char *>(IntPtr));
1300 return object_error::success; 1242 return std::error_code();
1301 } 1243 }
1302 1244
1303 std::error_code DelayImportDirectoryEntryRef:: 1245 std::error_code DelayImportDirectoryEntryRef::
1304 getDelayImportTable(const delay_import_directory_table_entry *&Result) const { 1246 getDelayImportTable(const delay_import_directory_table_entry *&Result) const {
1305 Result = Table; 1247 Result = Table;
1306 return object_error::success; 1248 return std::error_code();
1307 } 1249 }
1308 1250
1309 std::error_code DelayImportDirectoryEntryRef:: 1251 std::error_code DelayImportDirectoryEntryRef::
1310 getImportAddress(int AddrIndex, uint64_t &Result) const { 1252 getImportAddress(int AddrIndex, uint64_t &Result) const {
1311 uint32_t RVA = Table[Index].DelayImportAddressTable + 1253 uint32_t RVA = Table[Index].DelayImportAddressTable +
1315 return EC; 1257 return EC;
1316 if (OwningObject->is64()) 1258 if (OwningObject->is64())
1317 Result = *reinterpret_cast<const ulittle64_t *>(IntPtr); 1259 Result = *reinterpret_cast<const ulittle64_t *>(IntPtr);
1318 else 1260 else
1319 Result = *reinterpret_cast<const ulittle32_t *>(IntPtr); 1261 Result = *reinterpret_cast<const ulittle32_t *>(IntPtr);
1320 return object_error::success; 1262 return std::error_code();
1321 } 1263 }
1322 1264
1323 bool ExportDirectoryEntryRef:: 1265 bool ExportDirectoryEntryRef::
1324 operator==(const ExportDirectoryEntryRef &Other) const { 1266 operator==(const ExportDirectoryEntryRef &Other) const {
1325 return ExportTable == Other.ExportTable && Index == Other.Index; 1267 return ExportTable == Other.ExportTable && Index == Other.Index;
1335 uintptr_t IntPtr = 0; 1277 uintptr_t IntPtr = 0;
1336 if (std::error_code EC = 1278 if (std::error_code EC =
1337 OwningObject->getRvaPtr(ExportTable->NameRVA, IntPtr)) 1279 OwningObject->getRvaPtr(ExportTable->NameRVA, IntPtr))
1338 return EC; 1280 return EC;
1339 Result = StringRef(reinterpret_cast<const char *>(IntPtr)); 1281 Result = StringRef(reinterpret_cast<const char *>(IntPtr));
1340 return object_error::success; 1282 return std::error_code();
1341 } 1283 }
1342 1284
1343 // Returns the starting ordinal number. 1285 // Returns the starting ordinal number.
1344 std::error_code 1286 std::error_code
1345 ExportDirectoryEntryRef::getOrdinalBase(uint32_t &Result) const { 1287 ExportDirectoryEntryRef::getOrdinalBase(uint32_t &Result) const {
1346 Result = ExportTable->OrdinalBase; 1288 Result = ExportTable->OrdinalBase;
1347 return object_error::success; 1289 return std::error_code();
1348 } 1290 }
1349 1291
1350 // Returns the export ordinal of the current export symbol. 1292 // Returns the export ordinal of the current export symbol.
1351 std::error_code ExportDirectoryEntryRef::getOrdinal(uint32_t &Result) const { 1293 std::error_code ExportDirectoryEntryRef::getOrdinal(uint32_t &Result) const {
1352 Result = ExportTable->OrdinalBase + Index; 1294 Result = ExportTable->OrdinalBase + Index;
1353 return object_error::success; 1295 return std::error_code();
1354 } 1296 }
1355 1297
1356 // Returns the address of the current export symbol. 1298 // Returns the address of the current export symbol.
1357 std::error_code ExportDirectoryEntryRef::getExportRVA(uint32_t &Result) const { 1299 std::error_code ExportDirectoryEntryRef::getExportRVA(uint32_t &Result) const {
1358 uintptr_t IntPtr = 0; 1300 uintptr_t IntPtr = 0;
1360 OwningObject->getRvaPtr(ExportTable->ExportAddressTableRVA, IntPtr)) 1302 OwningObject->getRvaPtr(ExportTable->ExportAddressTableRVA, IntPtr))
1361 return EC; 1303 return EC;
1362 const export_address_table_entry *entry = 1304 const export_address_table_entry *entry =
1363 reinterpret_cast<const export_address_table_entry *>(IntPtr); 1305 reinterpret_cast<const export_address_table_entry *>(IntPtr);
1364 Result = entry[Index].ExportRVA; 1306 Result = entry[Index].ExportRVA;
1365 return object_error::success; 1307 return std::error_code();
1366 } 1308 }
1367 1309
1368 // Returns the name of the current export symbol. If the symbol is exported only 1310 // Returns the name of the current export symbol. If the symbol is exported only
1369 // by ordinal, the empty string is set as a result. 1311 // by ordinal, the empty string is set as a result.
1370 std::error_code 1312 std::error_code
1386 return EC; 1328 return EC;
1387 const ulittle32_t *NamePtr = reinterpret_cast<const ulittle32_t *>(IntPtr); 1329 const ulittle32_t *NamePtr = reinterpret_cast<const ulittle32_t *>(IntPtr);
1388 if (std::error_code EC = OwningObject->getRvaPtr(NamePtr[Offset], IntPtr)) 1330 if (std::error_code EC = OwningObject->getRvaPtr(NamePtr[Offset], IntPtr))
1389 return EC; 1331 return EC;
1390 Result = StringRef(reinterpret_cast<const char *>(IntPtr)); 1332 Result = StringRef(reinterpret_cast<const char *>(IntPtr));
1391 return object_error::success; 1333 return std::error_code();
1392 } 1334 }
1393 Result = ""; 1335 Result = "";
1394 return object_error::success; 1336 return std::error_code();
1395 } 1337 }
1396 1338
1397 bool ImportedSymbolRef:: 1339 bool ImportedSymbolRef::
1398 operator==(const ImportedSymbolRef &Other) const { 1340 operator==(const ImportedSymbolRef &Other) const {
1399 return Entry32 == Other.Entry32 && Entry64 == Other.Entry64 1341 return Entry32 == Other.Entry32 && Entry64 == Other.Entry64
1408 ImportedSymbolRef::getSymbolName(StringRef &Result) const { 1350 ImportedSymbolRef::getSymbolName(StringRef &Result) const {
1409 uint32_t RVA; 1351 uint32_t RVA;
1410 if (Entry32) { 1352 if (Entry32) {
1411 // If a symbol is imported only by ordinal, it has no name. 1353 // If a symbol is imported only by ordinal, it has no name.
1412 if (Entry32[Index].isOrdinal()) 1354 if (Entry32[Index].isOrdinal())
1413 return object_error::success; 1355 return std::error_code();
1414 RVA = Entry32[Index].getHintNameRVA(); 1356 RVA = Entry32[Index].getHintNameRVA();
1415 } else { 1357 } else {
1416 if (Entry64[Index].isOrdinal()) 1358 if (Entry64[Index].isOrdinal())
1417 return object_error::success; 1359 return std::error_code();
1418 RVA = Entry64[Index].getHintNameRVA(); 1360 RVA = Entry64[Index].getHintNameRVA();
1419 } 1361 }
1420 uintptr_t IntPtr = 0; 1362 uintptr_t IntPtr = 0;
1421 if (std::error_code EC = OwningObject->getRvaPtr(RVA, IntPtr)) 1363 if (std::error_code EC = OwningObject->getRvaPtr(RVA, IntPtr))
1422 return EC; 1364 return EC;
1423 // +2 because the first two bytes is hint. 1365 // +2 because the first two bytes is hint.
1424 Result = StringRef(reinterpret_cast<const char *>(IntPtr + 2)); 1366 Result = StringRef(reinterpret_cast<const char *>(IntPtr + 2));
1425 return object_error::success; 1367 return std::error_code();
1426 } 1368 }
1427 1369
1428 std::error_code ImportedSymbolRef::getOrdinal(uint16_t &Result) const { 1370 std::error_code ImportedSymbolRef::getOrdinal(uint16_t &Result) const {
1429 uint32_t RVA; 1371 uint32_t RVA;
1430 if (Entry32) { 1372 if (Entry32) {
1431 if (Entry32[Index].isOrdinal()) { 1373 if (Entry32[Index].isOrdinal()) {
1432 Result = Entry32[Index].getOrdinal(); 1374 Result = Entry32[Index].getOrdinal();
1433 return object_error::success; 1375 return std::error_code();
1434 } 1376 }
1435 RVA = Entry32[Index].getHintNameRVA(); 1377 RVA = Entry32[Index].getHintNameRVA();
1436 } else { 1378 } else {
1437 if (Entry64[Index].isOrdinal()) { 1379 if (Entry64[Index].isOrdinal()) {
1438 Result = Entry64[Index].getOrdinal(); 1380 Result = Entry64[Index].getOrdinal();
1439 return object_error::success; 1381 return std::error_code();
1440 } 1382 }
1441 RVA = Entry64[Index].getHintNameRVA(); 1383 RVA = Entry64[Index].getHintNameRVA();
1442 } 1384 }
1443 uintptr_t IntPtr = 0; 1385 uintptr_t IntPtr = 0;
1444 if (std::error_code EC = OwningObject->getRvaPtr(RVA, IntPtr)) 1386 if (std::error_code EC = OwningObject->getRvaPtr(RVA, IntPtr))
1445 return EC; 1387 return EC;
1446 Result = *reinterpret_cast<const ulittle16_t *>(IntPtr); 1388 Result = *reinterpret_cast<const ulittle16_t *>(IntPtr);
1447 return object_error::success; 1389 return std::error_code();
1448 } 1390 }
1449 1391
1450 ErrorOr<std::unique_ptr<COFFObjectFile>> 1392 ErrorOr<std::unique_ptr<COFFObjectFile>>
1451 ObjectFile::createCOFFObjectFile(MemoryBufferRef Object) { 1393 ObjectFile::createCOFFObjectFile(MemoryBufferRef Object) {
1452 std::error_code EC; 1394 std::error_code EC;
1479 } 1421 }
1480 1422
1481 std::error_code BaseRelocRef::getType(uint8_t &Type) const { 1423 std::error_code BaseRelocRef::getType(uint8_t &Type) const {
1482 auto *Entry = reinterpret_cast<const coff_base_reloc_block_entry *>(Header + 1); 1424 auto *Entry = reinterpret_cast<const coff_base_reloc_block_entry *>(Header + 1);
1483 Type = Entry[Index].getType(); 1425 Type = Entry[Index].getType();
1484 return object_error::success; 1426 return std::error_code();
1485 } 1427 }
1486 1428
1487 std::error_code BaseRelocRef::getRVA(uint32_t &Result) const { 1429 std::error_code BaseRelocRef::getRVA(uint32_t &Result) const {
1488 auto *Entry = reinterpret_cast<const coff_base_reloc_block_entry *>(Header + 1); 1430 auto *Entry = reinterpret_cast<const coff_base_reloc_block_entry *>(Header + 1);
1489 Result = Header->PageRVA + Entry[Index].getOffset(); 1431 Result = Header->PageRVA + Entry[Index].getOffset();
1490 return object_error::success; 1432 return std::error_code();
1491 } 1433 }