Mercurial > hg > CbC > CbC_llvm
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 } |