b8ba90535eaf31a8c5c3422064175eb856072a5d
[oota-llvm.git] / lib / Object / COFFObjectFile.cpp
1 //===- COFFObjectFile.cpp - COFF object file implementation -----*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file declares the COFFObjectFile class.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "llvm/Object/COFF.h"
15 #include "llvm/ADT/ArrayRef.h"
16 #include "llvm/ADT/SmallString.h"
17 #include "llvm/ADT/StringSwitch.h"
18 #include "llvm/ADT/Triple.h"
19
20 using namespace llvm;
21 using namespace object;
22
23 namespace {
24 using support::ulittle8_t;
25 using support::ulittle16_t;
26 using support::ulittle32_t;
27 using support::little16_t;
28 }
29
30 namespace {
31 // Returns false if size is greater than the buffer size. And sets ec.
32 bool checkSize(const MemoryBuffer *m, error_code &ec, uint64_t size) {
33   if (m->getBufferSize() < size) {
34     ec = object_error::unexpected_eof;
35     return false;
36   }
37   return true;
38 }
39
40 // Returns false if any bytes in [addr, addr + size) fall outsize of m.
41 bool checkAddr(const MemoryBuffer *m,
42                error_code &ec,
43                uintptr_t addr,
44                uint64_t size) {
45   if (addr + size < addr ||
46       addr + size < size ||
47       addr + size > uintptr_t(m->getBufferEnd())) {
48     ec = object_error::unexpected_eof;
49     return false;
50   }
51   return true;
52 }
53 }
54
55 const coff_symbol *COFFObjectFile::toSymb(DataRefImpl Symb) const {
56   const coff_symbol *addr = reinterpret_cast<const coff_symbol*>(Symb.p);
57
58 # ifndef NDEBUG
59   // Verify that the symbol points to a valid entry in the symbol table.
60   uintptr_t offset = uintptr_t(addr) - uintptr_t(base());
61   if (offset < Header->PointerToSymbolTable
62       || offset >= Header->PointerToSymbolTable
63          + (Header->NumberOfSymbols * sizeof(coff_symbol)))
64     report_fatal_error("Symbol was outside of symbol table.");
65
66   assert((offset - Header->PointerToSymbolTable) % sizeof(coff_symbol)
67          == 0 && "Symbol did not point to the beginning of a symbol");
68 # endif
69
70   return addr;
71 }
72
73 const coff_section *COFFObjectFile::toSec(DataRefImpl Sec) const {
74   const coff_section *addr = reinterpret_cast<const coff_section*>(Sec.p);
75
76 # ifndef NDEBUG
77   // Verify that the section points to a valid entry in the section table.
78   if (addr < SectionTable
79       || addr >= (SectionTable + Header->NumberOfSections))
80     report_fatal_error("Section was outside of section table.");
81
82   uintptr_t offset = uintptr_t(addr) - uintptr_t(SectionTable);
83   assert(offset % sizeof(coff_section) == 0 &&
84          "Section did not point to the beginning of a section");
85 # endif
86
87   return addr;
88 }
89
90 error_code COFFObjectFile::getSymbolNext(DataRefImpl Symb,
91                                          SymbolRef &Result) const {
92   const coff_symbol *symb = toSymb(Symb);
93   symb += 1 + symb->NumberOfAuxSymbols;
94   Symb.p = reinterpret_cast<uintptr_t>(symb);
95   Result = SymbolRef(Symb, this);
96   return object_error::success;
97 }
98
99  error_code COFFObjectFile::getSymbolName(DataRefImpl Symb,
100                                           StringRef &Result) const {
101   const coff_symbol *symb = toSymb(Symb);
102   return getSymbolName(symb, Result);
103 }
104
105 error_code COFFObjectFile::getSymbolFileOffset(DataRefImpl Symb,
106                                             uint64_t &Result) const {
107   const coff_symbol *symb = toSymb(Symb);
108   const coff_section *Section = NULL;
109   if (error_code ec = getSection(symb->SectionNumber, Section))
110     return ec;
111   char Type;
112   if (error_code ec = getSymbolNMTypeChar(Symb, Type))
113     return ec;
114   if (Type == 'U' || Type == 'w')
115     Result = UnknownAddressOrSize;
116   else if (Section)
117     Result = Section->PointerToRawData + symb->Value;
118   else
119     Result = symb->Value;
120   return object_error::success;
121 }
122
123 error_code COFFObjectFile::getSymbolAddress(DataRefImpl Symb,
124                                             uint64_t &Result) const {
125   const coff_symbol *symb = toSymb(Symb);
126   const coff_section *Section = NULL;
127   if (error_code ec = getSection(symb->SectionNumber, Section))
128     return ec;
129   char Type;
130   if (error_code ec = getSymbolNMTypeChar(Symb, Type))
131     return ec;
132   if (Type == 'U' || Type == 'w')
133     Result = UnknownAddressOrSize;
134   else if (Section)
135     Result = Section->VirtualAddress + symb->Value;
136   else
137     Result = symb->Value;
138   return object_error::success;
139 }
140
141 error_code COFFObjectFile::getSymbolType(DataRefImpl Symb,
142                                          SymbolRef::Type &Result) const {
143   const coff_symbol *symb = toSymb(Symb);
144   Result = SymbolRef::ST_Other;
145   if (symb->StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL &&
146       symb->SectionNumber == COFF::IMAGE_SYM_UNDEFINED) {
147     Result = SymbolRef::ST_Unknown;
148   } else {
149     if (symb->getComplexType() == COFF::IMAGE_SYM_DTYPE_FUNCTION) {
150       Result = SymbolRef::ST_Function;
151     } else {
152       char Type;
153       if (error_code ec = getSymbolNMTypeChar(Symb, Type))
154         return ec;
155       if (Type == 'r' || Type == 'R') {
156         Result = SymbolRef::ST_Data;
157       }
158     }
159   }
160   return object_error::success;
161 }
162
163 error_code COFFObjectFile::getSymbolFlags(DataRefImpl Symb,
164                                           uint32_t &Result) const {
165   const coff_symbol *symb = toSymb(Symb);
166   Result = SymbolRef::SF_None;
167
168   // TODO: Correctly set SF_FormatSpecific, SF_ThreadLocal, SF_Common
169
170   if (symb->StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL &&
171       symb->SectionNumber == COFF::IMAGE_SYM_UNDEFINED)
172     Result |= SymbolRef::SF_Undefined;
173
174   // TODO: This are certainly too restrictive.
175   if (symb->StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL)
176     Result |= SymbolRef::SF_Global;
177
178   if (symb->StorageClass == COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL)
179     Result |= SymbolRef::SF_Weak;
180
181   if (symb->SectionNumber == COFF::IMAGE_SYM_ABSOLUTE)
182     Result |= SymbolRef::SF_Absolute;
183
184   return object_error::success;
185 }
186
187 error_code COFFObjectFile::getSymbolSize(DataRefImpl Symb,
188                                          uint64_t &Result) const {
189   // FIXME: Return the correct size. This requires looking at all the symbols
190   //        in the same section as this symbol, and looking for either the next
191   //        symbol, or the end of the section.
192   const coff_symbol *symb = toSymb(Symb);
193   const coff_section *Section = NULL;
194   if (error_code ec = getSection(symb->SectionNumber, Section))
195     return ec;
196   char Type;
197   if (error_code ec = getSymbolNMTypeChar(Symb, Type))
198     return ec;
199   if (Type == 'U' || Type == 'w')
200     Result = UnknownAddressOrSize;
201   else if (Section)
202     Result = Section->SizeOfRawData - symb->Value;
203   else
204     Result = 0;
205   return object_error::success;
206 }
207
208 error_code COFFObjectFile::getSymbolNMTypeChar(DataRefImpl Symb,
209                                                char &Result) const {
210   const coff_symbol *symb = toSymb(Symb);
211   StringRef name;
212   if (error_code ec = getSymbolName(Symb, name))
213     return ec;
214   char ret = StringSwitch<char>(name)
215     .StartsWith(".debug", 'N')
216     .StartsWith(".sxdata", 'N')
217     .Default('?');
218
219   if (ret != '?') {
220     Result = ret;
221     return object_error::success;
222   }
223
224   uint32_t Characteristics = 0;
225   if (symb->SectionNumber > 0) {
226     const coff_section *Section = NULL;
227     if (error_code ec = getSection(symb->SectionNumber, Section))
228       return ec;
229     Characteristics = Section->Characteristics;
230   }
231
232   switch (symb->SectionNumber) {
233   case COFF::IMAGE_SYM_UNDEFINED:
234     // Check storage classes.
235     if (symb->StorageClass == COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL) {
236       Result = 'w';
237       return object_error::success; // Don't do ::toupper.
238     } else if (symb->Value != 0) // Check for common symbols.
239       ret = 'c';
240     else
241       ret = 'u';
242     break;
243   case COFF::IMAGE_SYM_ABSOLUTE:
244     ret = 'a';
245     break;
246   case COFF::IMAGE_SYM_DEBUG:
247     ret = 'n';
248     break;
249   default:
250     // Check section type.
251     if (Characteristics & COFF::IMAGE_SCN_CNT_CODE)
252       ret = 't';
253     else if (  Characteristics & COFF::IMAGE_SCN_MEM_READ
254             && ~Characteristics & COFF::IMAGE_SCN_MEM_WRITE) // Read only.
255       ret = 'r';
256     else if (Characteristics & COFF::IMAGE_SCN_CNT_INITIALIZED_DATA)
257       ret = 'd';
258     else if (Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA)
259       ret = 'b';
260     else if (Characteristics & COFF::IMAGE_SCN_LNK_INFO)
261       ret = 'i';
262
263     // Check for section symbol.
264     else if (  symb->StorageClass == COFF::IMAGE_SYM_CLASS_STATIC
265             && symb->Value == 0)
266        ret = 's';
267   }
268
269   if (symb->StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL)
270     ret = ::toupper(ret);
271
272   Result = ret;
273   return object_error::success;
274 }
275
276 error_code COFFObjectFile::getSymbolSection(DataRefImpl Symb,
277                                             section_iterator &Result) const {
278   const coff_symbol *symb = toSymb(Symb);
279   if (symb->SectionNumber <= COFF::IMAGE_SYM_UNDEFINED)
280     Result = end_sections();
281   else {
282     const coff_section *sec = 0;
283     if (error_code ec = getSection(symb->SectionNumber, sec)) return ec;
284     DataRefImpl Sec;
285     std::memset(&Sec, 0, sizeof(Sec));
286     Sec.p = reinterpret_cast<uintptr_t>(sec);
287     Result = section_iterator(SectionRef(Sec, this));
288   }
289   return object_error::success;
290 }
291
292 error_code COFFObjectFile::getSectionNext(DataRefImpl Sec,
293                                           SectionRef &Result) const {
294   const coff_section *sec = toSec(Sec);
295   sec += 1;
296   Sec.p = reinterpret_cast<uintptr_t>(sec);
297   Result = SectionRef(Sec, this);
298   return object_error::success;
299 }
300
301 error_code COFFObjectFile::getSectionName(DataRefImpl Sec,
302                                           StringRef &Result) const {
303   const coff_section *sec = toSec(Sec);
304   return getSectionName(sec, Result);
305 }
306
307 error_code COFFObjectFile::getSectionAddress(DataRefImpl Sec,
308                                              uint64_t &Result) const {
309   const coff_section *sec = toSec(Sec);
310   Result = sec->VirtualAddress;
311   return object_error::success;
312 }
313
314 error_code COFFObjectFile::getSectionSize(DataRefImpl Sec,
315                                           uint64_t &Result) const {
316   const coff_section *sec = toSec(Sec);
317   Result = sec->SizeOfRawData;
318   return object_error::success;
319 }
320
321 error_code COFFObjectFile::getSectionContents(DataRefImpl Sec,
322                                               StringRef &Result) const {
323   const coff_section *sec = toSec(Sec);
324   ArrayRef<uint8_t> Res;
325   error_code EC = getSectionContents(sec, Res);
326   Result = StringRef(reinterpret_cast<const char*>(Res.data()), Res.size());
327   return EC;
328 }
329
330 error_code COFFObjectFile::getSectionAlignment(DataRefImpl Sec,
331                                                uint64_t &Res) const {
332   const coff_section *sec = toSec(Sec);
333   if (!sec)
334     return object_error::parse_failed;
335   Res = uint64_t(1) << (((sec->Characteristics & 0x00F00000) >> 20) - 1);
336   return object_error::success;
337 }
338
339 error_code COFFObjectFile::isSectionText(DataRefImpl Sec,
340                                          bool &Result) const {
341   const coff_section *sec = toSec(Sec);
342   Result = sec->Characteristics & COFF::IMAGE_SCN_CNT_CODE;
343   return object_error::success;
344 }
345
346 error_code COFFObjectFile::isSectionData(DataRefImpl Sec,
347                                          bool &Result) const {
348   const coff_section *sec = toSec(Sec);
349   Result = sec->Characteristics & COFF::IMAGE_SCN_CNT_INITIALIZED_DATA;
350   return object_error::success;
351 }
352
353 error_code COFFObjectFile::isSectionBSS(DataRefImpl Sec,
354                                         bool &Result) const {
355   const coff_section *sec = toSec(Sec);
356   Result = sec->Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA;
357   return object_error::success;
358 }
359
360 error_code COFFObjectFile::sectionContainsSymbol(DataRefImpl Sec,
361                                                  DataRefImpl Symb,
362                                                  bool &Result) const {
363   const coff_section *sec = toSec(Sec);
364   const coff_symbol *symb = toSymb(Symb);
365   const coff_section *symb_sec = 0;
366   if (error_code ec = getSection(symb->SectionNumber, symb_sec)) return ec;
367   if (symb_sec == sec)
368     Result = true;
369   else
370     Result = false;
371   return object_error::success;
372 }
373
374 relocation_iterator COFFObjectFile::getSectionRelBegin(DataRefImpl Sec) const {
375   const coff_section *sec = toSec(Sec);
376   DataRefImpl ret;
377   std::memset(&ret, 0, sizeof(ret));
378   if (sec->NumberOfRelocations == 0)
379     ret.p = 0;
380   else
381     ret.p = reinterpret_cast<uintptr_t>(base() + sec->PointerToRelocations);
382
383   return relocation_iterator(RelocationRef(ret, this));
384 }
385
386 relocation_iterator COFFObjectFile::getSectionRelEnd(DataRefImpl Sec) const {
387   const coff_section *sec = toSec(Sec);
388   DataRefImpl ret;
389   std::memset(&ret, 0, sizeof(ret));
390   if (sec->NumberOfRelocations == 0)
391     ret.p = 0;
392   else
393     ret.p = reinterpret_cast<uintptr_t>(
394               reinterpret_cast<const coff_relocation*>(
395                 base() + sec->PointerToRelocations)
396               + sec->NumberOfRelocations);
397
398   return relocation_iterator(RelocationRef(ret, this));
399 }
400
401 COFFObjectFile::COFFObjectFile(MemoryBuffer *Object, error_code &ec)
402   : ObjectFile(Binary::ID_COFF, Object, ec)
403   , Header(0)
404   , SectionTable(0)
405   , SymbolTable(0)
406   , StringTable(0)
407   , StringTableSize(0) {
408   // Check that we at least have enough room for a header.
409   if (!checkSize(Data, ec, sizeof(coff_file_header))) return;
410
411   // The actual starting location of the COFF header in the file. This can be
412   // non-zero in PE/COFF files.
413   uint64_t HeaderStart = 0;
414
415   // Check if this is a PE/COFF file.
416   if (base()[0] == 0x4d && base()[1] == 0x5a) {
417     // PE/COFF, seek through MS-DOS compatibility stub and 4-byte
418     // PE signature to find 'normal' COFF header.
419     if (!checkSize(Data, ec, 0x3c + 8)) return;
420     HeaderStart = *reinterpret_cast<const ulittle16_t *>(base() + 0x3c);
421     // Check the PE header. ("PE\0\0")
422     if (std::memcmp(base() + HeaderStart, "PE\0\0", 4) != 0) {
423       ec = object_error::parse_failed;
424       return;
425     }
426     HeaderStart += 4; // Skip the PE Header.
427   }
428
429   Header = reinterpret_cast<const coff_file_header *>(base() + HeaderStart);
430   if (!checkAddr(Data, ec, uintptr_t(Header), sizeof(coff_file_header)))
431     return;
432
433   SectionTable =
434     reinterpret_cast<const coff_section *>( base()
435                                           + HeaderStart
436                                           + sizeof(coff_file_header)
437                                           + Header->SizeOfOptionalHeader);
438   if (!checkAddr(Data, ec, uintptr_t(SectionTable),
439                  Header->NumberOfSections * sizeof(coff_section)))
440     return;
441
442   if (Header->PointerToSymbolTable != 0) {
443     SymbolTable =
444       reinterpret_cast<const coff_symbol *>(base()
445                                             + Header->PointerToSymbolTable);
446     if (!checkAddr(Data, ec, uintptr_t(SymbolTable),
447                    Header->NumberOfSymbols * sizeof(coff_symbol)))
448       return;
449
450     // Find string table.
451     StringTable = reinterpret_cast<const char *>(base())
452                   + Header->PointerToSymbolTable
453                   + Header->NumberOfSymbols * sizeof(coff_symbol);
454     if (!checkAddr(Data, ec, uintptr_t(StringTable), sizeof(ulittle32_t)))
455       return;
456
457     StringTableSize = *reinterpret_cast<const ulittle32_t *>(StringTable);
458     if (!checkAddr(Data, ec, uintptr_t(StringTable), StringTableSize))
459       return;
460     // Check that the string table is null terminated if has any in it.
461     if (StringTableSize < 4
462         || (StringTableSize > 4 && StringTable[StringTableSize - 1] != 0)) {
463       ec = object_error::parse_failed;
464       return;
465     }
466   }
467
468   ec = object_error::success;
469 }
470
471 symbol_iterator COFFObjectFile::begin_symbols() const {
472   DataRefImpl ret;
473   std::memset(&ret, 0, sizeof(DataRefImpl));
474   ret.p = reinterpret_cast<intptr_t>(SymbolTable);
475   return symbol_iterator(SymbolRef(ret, this));
476 }
477
478 symbol_iterator COFFObjectFile::end_symbols() const {
479   // The symbol table ends where the string table begins.
480   DataRefImpl ret;
481   std::memset(&ret, 0, sizeof(DataRefImpl));
482   ret.p = reinterpret_cast<intptr_t>(StringTable);
483   return symbol_iterator(SymbolRef(ret, this));
484 }
485
486 symbol_iterator COFFObjectFile::begin_dynamic_symbols() const {
487   // TODO: implement
488   report_fatal_error("Dynamic symbols unimplemented in COFFObjectFile");
489 }
490
491 symbol_iterator COFFObjectFile::end_dynamic_symbols() const {
492   // TODO: implement
493   report_fatal_error("Dynamic symbols unimplemented in COFFObjectFile");
494 }
495
496 library_iterator COFFObjectFile::begin_libraries_needed() const {
497   // TODO: implement
498   report_fatal_error("Libraries needed unimplemented in COFFObjectFile");
499 }
500
501 library_iterator COFFObjectFile::end_libraries_needed() const {
502   // TODO: implement
503   report_fatal_error("Libraries needed unimplemented in COFFObjectFile");
504 }
505
506 StringRef COFFObjectFile::getLoadName() const {
507   // COFF does not have this field.
508   return "";
509 }
510
511
512 section_iterator COFFObjectFile::begin_sections() const {
513   DataRefImpl ret;
514   std::memset(&ret, 0, sizeof(DataRefImpl));
515   ret.p = reinterpret_cast<intptr_t>(SectionTable);
516   return section_iterator(SectionRef(ret, this));
517 }
518
519 section_iterator COFFObjectFile::end_sections() const {
520   DataRefImpl ret;
521   std::memset(&ret, 0, sizeof(DataRefImpl));
522   ret.p = reinterpret_cast<intptr_t>(SectionTable + Header->NumberOfSections);
523   return section_iterator(SectionRef(ret, this));
524 }
525
526 uint8_t COFFObjectFile::getBytesInAddress() const {
527   return getArch() == Triple::x86_64 ? 8 : 4;
528 }
529
530 StringRef COFFObjectFile::getFileFormatName() const {
531   switch(Header->Machine) {
532   case COFF::IMAGE_FILE_MACHINE_I386:
533     return "COFF-i386";
534   case COFF::IMAGE_FILE_MACHINE_AMD64:
535     return "COFF-x86-64";
536   default:
537     return "COFF-<unknown arch>";
538   }
539 }
540
541 unsigned COFFObjectFile::getArch() const {
542   switch(Header->Machine) {
543   case COFF::IMAGE_FILE_MACHINE_I386:
544     return Triple::x86;
545   case COFF::IMAGE_FILE_MACHINE_AMD64:
546     return Triple::x86_64;
547   default:
548     return Triple::UnknownArch;
549   }
550 }
551
552 error_code COFFObjectFile::getHeader(const coff_file_header *&Res) const {
553   Res = Header;
554   return object_error::success;
555 }
556
557 error_code COFFObjectFile::getSection(int32_t index,
558                                       const coff_section *&Result) const {
559   // Check for special index values.
560   if (index == COFF::IMAGE_SYM_UNDEFINED ||
561       index == COFF::IMAGE_SYM_ABSOLUTE ||
562       index == COFF::IMAGE_SYM_DEBUG)
563     Result = NULL;
564   else if (index > 0 && index <= Header->NumberOfSections)
565     // We already verified the section table data, so no need to check again.
566     Result = SectionTable + (index - 1);
567   else
568     return object_error::parse_failed;
569   return object_error::success;
570 }
571
572 error_code COFFObjectFile::getString(uint32_t offset,
573                                      StringRef &Result) const {
574   if (StringTableSize <= 4)
575     // Tried to get a string from an empty string table.
576     return object_error::parse_failed;
577   if (offset >= StringTableSize)
578     return object_error::unexpected_eof;
579   Result = StringRef(StringTable + offset);
580   return object_error::success;
581 }
582
583 error_code COFFObjectFile::getSymbol(uint32_t index,
584                                      const coff_symbol *&Result) const {
585   if (index < Header->NumberOfSymbols)
586     Result = SymbolTable + index;
587   else
588     return object_error::parse_failed;
589   return object_error::success;
590 }
591
592 error_code COFFObjectFile::getSymbolName(const coff_symbol *symbol,
593                                          StringRef &Res) const {
594   // Check for string table entry. First 4 bytes are 0.
595   if (symbol->Name.Offset.Zeroes == 0) {
596     uint32_t Offset = symbol->Name.Offset.Offset;
597     if (error_code ec = getString(Offset, Res))
598       return ec;
599     return object_error::success;
600   }
601
602   if (symbol->Name.ShortName[7] == 0)
603     // Null terminated, let ::strlen figure out the length.
604     Res = StringRef(symbol->Name.ShortName);
605   else
606     // Not null terminated, use all 8 bytes.
607     Res = StringRef(symbol->Name.ShortName, 8);
608   return object_error::success;
609 }
610
611 error_code COFFObjectFile::getSectionName(const coff_section *Sec,
612                                           StringRef &Res) const {
613   StringRef Name;
614   if (Sec->Name[7] == 0)
615     // Null terminated, let ::strlen figure out the length.
616     Name = Sec->Name;
617   else
618     // Not null terminated, use all 8 bytes.
619     Name = StringRef(Sec->Name, 8);
620
621   // Check for string table entry. First byte is '/'.
622   if (Name[0] == '/') {
623     uint32_t Offset;
624     if (Name.substr(1).getAsInteger(10, Offset))
625       return object_error::parse_failed;
626     if (error_code ec = getString(Offset, Name))
627       return ec;
628   }
629
630   Res = Name;
631   return object_error::success;
632 }
633
634 error_code COFFObjectFile::getSectionContents(const coff_section *Sec,
635                                               ArrayRef<uint8_t> &Res) const {
636   // The only thing that we need to verify is that the contents is contained
637   // within the file bounds. We don't need to make sure it doesn't cover other
638   // data, as there's nothing that says that is not allowed.
639   uintptr_t ConStart = uintptr_t(base()) + Sec->PointerToRawData;
640   uintptr_t ConEnd = ConStart + Sec->SizeOfRawData;
641   if (ConEnd > uintptr_t(Data->getBufferEnd()))
642     return object_error::parse_failed;
643   Res = ArrayRef<uint8_t>(reinterpret_cast<const unsigned char*>(ConStart),
644                           Sec->SizeOfRawData);
645   return object_error::success;
646 }
647
648 const coff_relocation *COFFObjectFile::toRel(DataRefImpl Rel) const {
649   return reinterpret_cast<const coff_relocation*>(Rel.p);
650 }
651 error_code COFFObjectFile::getRelocationNext(DataRefImpl Rel,
652                                              RelocationRef &Res) const {
653   Rel.p = reinterpret_cast<uintptr_t>(
654             reinterpret_cast<const coff_relocation*>(Rel.p) + 1);
655   Res = RelocationRef(Rel, this);
656   return object_error::success;
657 }
658 error_code COFFObjectFile::getRelocationAddress(DataRefImpl Rel,
659                                                 uint64_t &Res) const {
660   Res = toRel(Rel)->VirtualAddress;
661   return object_error::success;
662 }
663 error_code COFFObjectFile::getRelocationOffset(DataRefImpl Rel,
664                                                uint64_t &Res) const {
665   Res = toRel(Rel)->VirtualAddress;
666   return object_error::success;
667 }
668 error_code COFFObjectFile::getRelocationSymbol(DataRefImpl Rel,
669                                                SymbolRef &Res) const {
670   const coff_relocation* R = toRel(Rel);
671   DataRefImpl Symb;
672   std::memset(&Symb, 0, sizeof(Symb));
673   Symb.p = reinterpret_cast<uintptr_t>(SymbolTable + R->SymbolTableIndex);
674   Res = SymbolRef(Symb, this);
675   return object_error::success;
676 }
677 error_code COFFObjectFile::getRelocationType(DataRefImpl Rel,
678                                              uint64_t &Res) const {
679   const coff_relocation* R = toRel(Rel);
680   Res = R->Type;
681   return object_error::success;
682 }
683
684 #define LLVM_COFF_SWITCH_RELOC_TYPE_NAME(enum) \
685   case COFF::enum: res = #enum; break;
686
687 error_code COFFObjectFile::getRelocationTypeName(DataRefImpl Rel,
688                                           SmallVectorImpl<char> &Result) const {
689   const coff_relocation *reloc = toRel(Rel);
690   StringRef res;
691   switch (Header->Machine) {
692   case COFF::IMAGE_FILE_MACHINE_AMD64:
693     switch (reloc->Type) {
694     LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_ABSOLUTE);
695     LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_ADDR64);
696     LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_ADDR32);
697     LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_ADDR32NB);
698     LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32);
699     LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_1);
700     LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_2);
701     LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_3);
702     LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_4);
703     LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_5);
704     LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SECTION);
705     LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SECREL);
706     LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SECREL7);
707     LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_TOKEN);
708     LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SREL32);
709     LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_PAIR);
710     LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SSPAN32);
711     default:
712       res = "Unknown";
713     }
714     break;
715   case COFF::IMAGE_FILE_MACHINE_I386:
716     switch (reloc->Type) {
717     LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_ABSOLUTE);
718     LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_DIR16);
719     LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_REL16);
720     LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_DIR32);
721     LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_DIR32NB);
722     LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_SEG12);
723     LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_SECTION);
724     LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_SECREL);
725     LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_TOKEN);
726     LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_SECREL7);
727     LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_REL32);
728     default:
729       res = "Unknown";
730     }
731     break;
732   default:
733     res = "Unknown";
734   }
735   Result.append(res.begin(), res.end());
736   return object_error::success;
737 }
738
739 #undef LLVM_COFF_SWITCH_RELOC_TYPE_NAME
740
741 error_code COFFObjectFile::getRelocationAdditionalInfo(DataRefImpl Rel,
742                                                        int64_t &Res) const {
743   Res = 0;
744   return object_error::success;
745 }
746 error_code COFFObjectFile::getRelocationValueString(DataRefImpl Rel,
747                                           SmallVectorImpl<char> &Result) const {
748   const coff_relocation *reloc = toRel(Rel);
749   const coff_symbol *symb = 0;
750   if (error_code ec = getSymbol(reloc->SymbolTableIndex, symb)) return ec;
751   DataRefImpl sym;
752   ::memset(&sym, 0, sizeof(sym));
753   sym.p = reinterpret_cast<uintptr_t>(symb);
754   StringRef symname;
755   if (error_code ec = getSymbolName(sym, symname)) return ec;
756   Result.append(symname.begin(), symname.end());
757   return object_error::success;
758 }
759
760 error_code COFFObjectFile::getLibraryNext(DataRefImpl LibData,
761                                           LibraryRef &Result) const {
762   report_fatal_error("getLibraryNext not implemented in COFFObjectFile");
763 }
764
765 error_code COFFObjectFile::getLibraryPath(DataRefImpl LibData,
766                                           StringRef &Result) const {
767   report_fatal_error("getLibraryPath not implemented in COFFObjectFile");
768 }
769
770 namespace llvm {
771
772   ObjectFile *ObjectFile::createCOFFObjectFile(MemoryBuffer *Object) {
773     error_code ec;
774     return new COFFObjectFile(Object, ec);
775   }
776
777 } // end namespace llvm