llvm.org GIT mirror llvm / b08c6df
Template MachOObjectFile over endianness too. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179179 91177308-0d34-0410-b5e6-96231b3b80d8 Rafael Espindola 7 years ago
3 changed file(s) with 148 addition(s) and 137 deletion(s). Raw diff Collapse all Expand all
288288 const SymtabLoadCommand *SymtabLoadCmd) const;
289289 };
290290
291 template
292 struct MachOObjectFileHelperCommon {
293 typedef MachOFormat::SegmentLoadCommand >
291 template>
292 struct MachOObjectFileHelperCommon;
293
294 template
295 struct MachOObjectFileHelperCommon > {
296 typedef
297 MachOFormat::SegmentLoadCommand >
294298 SegmentLoadCommand;
295 typedef MachOFormat::SymbolTableEntrysupport::little, is64Bits> >
299 typedef MachOFormat::SymbolTableEntryTargetEndianness, Is64Bits> >
296300 SymbolTableEntry;
297 typedef MachOFormat::Sectionsupport::little, is64Bits> > Section;
301 typedef MachOFormat::SectionTargetEndianness, Is64Bits> > Section;
298302 };
299303
300 template<bool is64Bits>
304 template<class MachOT>
301305 struct MachOObjectFileHelper;
302306
303 template<>
304 struct MachOObjectFileHelper :
305 public MachOObjectFileHelperCommon {
307 template
308 struct MachOObjectFileHelper > :
309 public MachOObjectFileHelperCommon > {
306310 static const macho::LoadCommandType SegmentLoadType = macho::LCT_Segment;
307311 };
308312
309 template<>
310 struct MachOObjectFileHelper :
311 public MachOObjectFileHelperCommon {
313 template
314 struct MachOObjectFileHelper > :
315 public MachOObjectFileHelperCommon > {
312316 static const macho::LoadCommandType SegmentLoadType = macho::LCT_Segment64;
313317 };
314318
315 template<bool is64Bits>
319 template<class MachOT>
316320 class MachOObjectFile : public MachOObjectFileBase {
317321 public:
318 typedef MachOObjectFileHelper Helper;
322 static const endianness TargetEndianness = MachOT::TargetEndianness;
323 static const bool Is64Bits = MachOT::Is64Bits;
324
325 typedef MachOObjectFileHelper Helper;
319326 static const macho::LoadCommandType SegmentLoadType = Helper::SegmentLoadType;
320327 typedef typename Helper::SegmentLoadCommand SegmentLoadCommand;
321328 typedef typename Helper::SymbolTableEntry SymbolTableEntry;
356363 void moveToNextSection(DataRefImpl &DRI) const;
357364 };
358365
359 template
360 MachOObjectFile::MachOObjectFile(MemoryBuffer *Object,
361 error_code &ec) :
362 MachOObjectFileBase(Object, is64Bits, ec) {
366 template
367 MachOObjectFile::MachOObjectFile(MemoryBuffer *Object,
368 error_code &ec) :
369 MachOObjectFileBase(Object, Is64Bits, ec) {
363370 DataRefImpl DRI;
364371 moveToNextSection(DRI);
365372 uint32_t LoadCommandCount = getHeader()->NumLoadCommands;
370377 }
371378 }
372379
373 template
374 bool MachOObjectFile::classof(const Binary *v) {
375 return v->getType() == getMachOType(true, is64Bits);
376 }
377
378 template
379 const typename MachOObjectFile::Section *
380 MachOObjectFile::getSection(DataRefImpl DRI) const {
380 template
381 bool MachOObjectFile::classof(const Binary *v) {
382 return v->getType() == getMachOType(true, Is64Bits);
383 }
384
385 template
386 const typename MachOObjectFile::Section *
387 MachOObjectFile::getSection(DataRefImpl DRI) const {
381388 const SectionBase *Addr = getSectionBase(DRI);
382389 return reinterpret_cast(Addr);
383390 }
384391
385 template
386 const typename MachOObjectFile::SymbolTableEntry *
387 MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI) const {
392 template
393 const typename MachOObjectFile::SymbolTableEntry *
394 MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI) const {
388395 const SymbolTableEntryBase *Base = getSymbolTableEntryBase(DRI);
389396 return reinterpret_cast(Base);
390397 }
391398
392 template
393 const typename MachOObjectFile::RelocationEntry *
394 MachOObjectFile::getRelocation(DataRefImpl Rel) const {
399 template
400 const typename MachOObjectFile::RelocationEntry *
401 MachOObjectFile::getRelocation(DataRefImpl Rel) const {
395402 const Section *Sect = getSection(Sections[Rel.d.b]);
396403 uint32_t RelOffset = Sect->RelocationTableOffset;
397404 uint64_t Offset = RelOffset + Rel.d.a * sizeof(RelocationEntry);
399406 return reinterpret_cast(Data.data());
400407 }
401408
402 template
403 error_code
404 MachOObjectFile::getSectionAddress(DataRefImpl Sec,
409 template
410 error_code
411 MachOObjectFile::getSectionAddress(DataRefImpl Sec,
412 uint64_t &Res) const {
413 const Section *Sect = getSection(Sec);
414 Res = Sect->Address;
415 return object_error::success;
416 }
417
418 template
419 error_code
420 MachOObjectFile::getSectionSize(DataRefImpl Sec,
421 uint64_t &Res) const {
422 const Section *Sect = getSection(Sec);
423 Res = Sect->Size;
424 return object_error::success;
425 }
426
427 template
428 error_code
429 MachOObjectFile::getSectionContents(DataRefImpl Sec,
430 StringRef &Res) const {
431 const Section *Sect = getSection(Sec);
432 Res = getData(Sect->Offset, Sect->Size);
433 return object_error::success;
434 }
435
436 template
437 error_code
438 MachOObjectFile::getSectionAlignment(DataRefImpl Sec,
405439 uint64_t &Res) const {
406440 const Section *Sect = getSection(Sec);
407 Res = Sect->Address;
408 return object_error::success;
409 }
410
411 template
412 error_code
413 MachOObjectFile::getSectionSize(DataRefImpl Sec,
414 uint64_t &Res) const {
415 const Section *Sect = getSection(Sec);
416 Res = Sect->Size;
417 return object_error::success;
418 }
419
420 template
421 error_code
422 MachOObjectFile::getSectionContents(DataRefImpl Sec,
423 StringRef &Res) const {
424 const Section *Sect = getSection(Sec);
425 Res = getData(Sect->Offset, Sect->Size);
426 return object_error::success;
427 }
428
429 template
430 error_code
431 MachOObjectFile::getSectionAlignment(DataRefImpl Sec,
432 uint64_t &Res) const {
433 const Section *Sect = getSection(Sec);
434441 Res = uint64_t(1) << Sect->Align;
435442 return object_error::success;
436443 }
437444
438 template
439 error_code
440 MachOObjectFile::isSectionText(DataRefImpl Sec, bool &Res) const {
445 template
446 error_code
447 MachOObjectFile::isSectionText(DataRefImpl Sec, bool &Res) const {
441448 const Section *Sect = getSection(Sec);
442449 Res = Sect->Flags & macho::SF_PureInstructions;
443450 return object_error::success;
444451 }
445452
446 template
447 error_code
448 MachOObjectFile::isSectionZeroInit(DataRefImpl Sec, bool &Res) const {
453 template
454 error_code
455 MachOObjectFile::isSectionZeroInit(DataRefImpl Sec, bool &Res) const {
449456 const Section *Sect = getSection(Sec);
450457 unsigned SectionType = Sect->Flags & MachO::SectionFlagMaskSectionType;
451458 Res = SectionType == MachO::SectionTypeZeroFill ||
453460 return object_error::success;
454461 }
455462
456 template<bool is64Bits>
463 template<class MachOT>
457464 relocation_iterator
458 MachOObjectFile<is64Bits>::getSectionRelEnd(DataRefImpl Sec) const {
465 MachOObjectFile<MachOT>::getSectionRelEnd(DataRefImpl Sec) const {
459466 const Section *Sect = getSection(Sec);
460467 uint32_t LastReloc = Sect->NumRelocationTableEntries;
461468 DataRefImpl Ret;
464471 return relocation_iterator(RelocationRef(Ret, this));
465472 }
466473
467 template
468 error_code
469 MachOObjectFile::getRelocationAddress(DataRefImpl Rel,
470 uint64_t &Res) const {
474 template
475 error_code
476 MachOObjectFile::getRelocationAddress(DataRefImpl Rel,
477 uint64_t &Res) const {
471478 const Section *Sect = getSection(Sections[Rel.d.b]);
472479 uint64_t SectAddress = Sect->Address;
473480 const RelocationEntry *RE = getRelocation(Rel);
485492 return object_error::success;
486493 }
487494
488 template
489 error_code
490 MachOObjectFile::getRelocationOffset(DataRefImpl Rel,
491 uint64_t &Res) const {
495 template
496 error_code
497 MachOObjectFile::getRelocationOffset(DataRefImpl Rel,
498 uint64_t &Res) const {
492499 const RelocationEntry *RE = getRelocation(Rel);
493500
494501 unsigned Arch = getArch();
501508 return object_error::success;
502509 }
503510
504 template
505 error_code
506 MachOObjectFile::getRelocationSymbol(DataRefImpl Rel,
507 SymbolRef &Res) const {
511 template
512 error_code
513 MachOObjectFile::getRelocationSymbol(DataRefImpl Rel,
514 SymbolRef &Res) const {
508515 const RelocationEntry *RE = getRelocation(Rel);
509516 uint32_t SymbolIdx = RE->Word1 & 0xffffff;
510517 bool isExtern = (RE->Word1 >> 27) & 1;
523530 return object_error::success;
524531 }
525532
526 template
527 error_code
528 MachOObjectFile::getRelocationAdditionalInfo(DataRefImpl Rel,
529 int64_t &Res) const {
533 template
534 error_code
535 MachOObjectFile::getRelocationAdditionalInfo(DataRefImpl Rel,
536 int64_t &Res) const {
530537 const RelocationEntry *RE = getRelocation(Rel);
531538 bool isExtern = (RE->Word1 >> 27) & 1;
532539 Res = 0;
539546 return object_error::success;
540547 }
541548
542 template
543 error_code MachOObjectFile::getRelocationType(DataRefImpl Rel,
544 uint64_t &Res) const {
549 template
550 error_code MachOObjectFile::getRelocationType(DataRefImpl Rel,
551 uint64_t &Res) const {
545552 const RelocationEntry *RE = getRelocation(Rel);
546553 Res = RE->Word0;
547554 Res <<= 32;
549556 return object_error::success;
550557 }
551558
552 template
553 error_code
554 MachOObjectFile::getRelocationTypeName(DataRefImpl Rel,
559 template
560 error_code
561 MachOObjectFile::getRelocationTypeName(DataRefImpl Rel,
555562 SmallVectorImpl &Result) const {
556563 // TODO: Support scattered relocations.
557564 StringRef res;
651658 return object_error::success;
652659 }
653660
654 template
655 error_code
656 MachOObjectFile::getRelocationValueString(DataRefImpl Rel,
661 template
662 error_code
663 MachOObjectFile::getRelocationValueString(DataRefImpl Rel,
657664 SmallVectorImpl &Result) const {
658665 const RelocationEntry *RE = getRelocation(Rel);
659666
863870 return object_error::success;
864871 }
865872
866 template
867 error_code
868 MachOObjectFile::getRelocationHidden(DataRefImpl Rel,
869 bool &Result) const {
873 template
874 error_code
875 MachOObjectFile::getRelocationHidden(DataRefImpl Rel,
876 bool &Result) const {
870877 const RelocationEntry *RE = getRelocation(Rel);
871878
872879 unsigned Arch = getArch();
901908 return object_error::success;
902909 }
903910
904 template
905 error_code
906 MachOObjectFile::getSymbolFileOffset(DataRefImpl Symb,
907 uint64_t &Res) const {
911 template
912 error_code
913 MachOObjectFile::getSymbolFileOffset(DataRefImpl Symb,
914 uint64_t &Res) const {
908915 const SymbolTableEntry *Entry = getSymbolTableEntry(Symb);
909916 Res = Entry->Value;
910917 if (Entry->SectionIndex) {
915922 return object_error::success;
916923 }
917924
918 template
919 error_code
920 MachOObjectFile::sectionContainsSymbol(DataRefImpl Sec,
921 DataRefImpl Symb,
922 bool &Result) const {
925 template
926 error_code
927 MachOObjectFile::sectionContainsSymbol(DataRefImpl Sec,
928 DataRefImpl Symb,
929 bool &Result) const {
923930 SymbolRef::Type ST;
924931 getSymbolType(Symb, ST);
925932 if (ST == SymbolRef::ST_Unknown) {
939946 return object_error::success;
940947 }
941948
942 template
943 error_code MachOObjectFile::getSymbolAddress(DataRefImpl Symb,
944 uint64_t &Res) const {
949 template
950 error_code MachOObjectFile::getSymbolAddress(DataRefImpl Symb,
951 uint64_t &Res) const {
945952 const SymbolTableEntry *Entry = getSymbolTableEntry(Symb);
946953 Res = Entry->Value;
947954 return object_error::success;
948955 }
949956
950 template
951 error_code MachOObjectFile::getSymbolSize(DataRefImpl DRI,
957 template
958 error_code MachOObjectFile::getSymbolSize(DataRefImpl DRI,
952959 uint64_t &Result) const {
953960 uint32_t LoadCommandCount = getHeader()->NumLoadCommands;
954961 uint64_t BeginOffset;
991998 return object_error::success;
992999 }
9931000
994 template
995 error_code MachOObjectFile::getSectionNext(DataRefImpl Sec,
996 SectionRef &Res) const {
1001 template
1002 error_code MachOObjectFile::getSectionNext(DataRefImpl Sec,
1003 SectionRef &Res) const {
9971004 Sec.d.b++;
9981005 moveToNextSection(Sec);
9991006 Res = SectionRef(Sec, this);
10001007 return object_error::success;
10011008 }
10021009
1003 template
1004 section_iterator MachOObjectFile::begin_sections() const {
1010 template
1011 section_iterator MachOObjectFile::begin_sections() const {
10051012 DataRefImpl DRI;
10061013 moveToNextSection(DRI);
10071014 return section_iterator(SectionRef(DRI, this));
10081015 }
10091016
1010 template
1011 void MachOObjectFile::moveToNextSection(DataRefImpl &DRI) const {
1017 template
1018 void MachOObjectFile::moveToNextSection(DataRefImpl &DRI) const {
10121019 uint32_t LoadCommandCount = getHeader()->NumLoadCommands;
10131020 while (DRI.d.a < LoadCommandCount) {
10141021 const LoadCommand *Command = getLoadCommandInfo(DRI.d.a);
10241031 }
10251032 }
10261033
1034 typedef MachOObjectFile >
1035 MachOObjectFile32Le;
1036 typedef MachOObjectFile >
1037 MachOObjectFile64Le;
10271038 }
10281039 }
10291040
3434 }
3535
3636 bool MachOObjectFileBase::is64Bit() const {
37 return isa >(this);
37 return isa64Le>(this);
3838 }
3939
4040 const MachOObjectFileBase::LoadCommand *
8585 bool Is64Bits = Magic == "\xFE\xED\xFA\xCF" || Magic == "\xCF\xFA\xED\xFE";
8686 ObjectFile *Ret;
8787 if (Is64Bits)
88 Ret = new MachOObjectFile(Buffer, ec);
88 Ret = new MachOObjectFile64Le(Buffer, ec);
8989 else
90 Ret = new MachOObjectFile(Buffer, ec);
90 Ret = new MachOObjectFile32Le(Buffer, ec);
9191 if (ec)
9292 return NULL;
9393 return Ret;
126126 unsigned Index = DRI.d.b;
127127
128128 unsigned SymbolTableEntrySize = is64Bit() ?
129 sizeof(MachOObjectFile::SymbolTableEntry) :
130 sizeof(MachOObjectFile::SymbolTableEntry);
129 sizeof(MachOObjectFile64Le::SymbolTableEntry) :
130 sizeof(MachOObjectFile32Le::SymbolTableEntry);
131131
132132 uint64_t Offset = SymbolTableOffset + Index * SymbolTableEntrySize;
133133 StringRef Data = getData(Offset, SymbolTableEntrySize);
313313
314314 bool Is64 = is64Bit();
315315 unsigned SegmentLoadSize =
316 Is64 ? sizeof(MachOObjectFile::SegmentLoadCommand) :
317 sizeof(MachOObjectFile::SegmentLoadCommand);
318 unsigned SectionSize = Is64 ? sizeof(MachOObjectFile::Section) :
319 sizeof(MachOObjectFile::Section);
316 Is64 ? sizeof(MachOObjectFile64Le::SegmentLoadCommand) :
317 sizeof(MachOObjectFile32Le::SegmentLoadCommand);
318 unsigned SectionSize = Is64 ? sizeof(MachOObjectFile64Le::Section) :
319 sizeof(MachOObjectFile32Le::Section);
320320
321321 uintptr_t SectionAddr = CommandAddr + SegmentLoadSize + DRI.d.b * SectionSize;
322322 return reinterpret_cast(SectionAddr);
159159 static void getSection(const MachOObjectFileBase *Obj,
160160 DataRefImpl DRI,
161161 MachOSection &Section) {
162 if (const MachOObjectFile *O = dyn_cast >(Obj)) {
163 const MachOObjectFile::Section *Sect = O->getSection(DRI);
162 if (const MachOObjectFile64Le *O = dyn_cast(Obj)) {
163 const MachOObjectFile64Le::Section *Sect = O->getSection(DRI);
164164
165165 Section.Address = Sect->Address;
166166 Section.Size = Sect->Size;
172172 Section.Reserved1 = Sect->Reserved1;
173173 Section.Reserved2 = Sect->Reserved2;
174174 } else {
175 const MachOObjectFile *O2 = cast >(Obj);
176 const MachOObjectFile::Section *Sect = O2->getSection(DRI);
175 const MachOObjectFile32Le *O2 = cast(Obj);
176 const MachOObjectFile32Le::Section *Sect = O2->getSection(DRI);
177177
178178 Section.Address = Sect->Address;
179179 Section.Size = Sect->Size;
190190 static void getSymbol(const MachOObjectFileBase *Obj,
191191 DataRefImpl DRI,
192192 MachOSymbol &Symbol) {
193 if (const MachOObjectFile *O = dyn_cast >(Obj)) {
194 const MachOObjectFile::SymbolTableEntry *Entry =
193 if (const MachOObjectFile64Le *O = dyn_cast(Obj)) {
194 const MachOObjectFile64Le::SymbolTableEntry *Entry =
195195 O->getSymbolTableEntry(DRI);
196196 Symbol.StringIndex = Entry->StringIndex;
197197 Symbol.Type = Entry->Type;
199199 Symbol.Flags = Entry->Flags;
200200 Symbol.Value = Entry->Value;
201201 } else {
202 const MachOObjectFile *O2 = cast >(Obj);
203 const MachOObjectFile::SymbolTableEntry *Entry =
202 const MachOObjectFile32Le *O2 = cast(Obj);
203 const MachOObjectFile32Le::SymbolTableEntry *Entry =
204204 O2->getSymbolTableEntry(DRI);
205205 Symbol.StringIndex = Entry->StringIndex;
206206 Symbol.Type = Entry->Type;