@@ -153,11 +153,12 @@ Optional<MemoryBufferRef> macho::readFile(StringRef path) {
153
153
InputFile::InputFile (Kind kind, const InterfaceFile &interface)
154
154
: id(idCount++), fileKind(kind), name(saver.save(interface.getPath())) {}
155
155
156
- void ObjFile::parseSections (ArrayRef<section_64> sections) {
156
+ template <class Section >
157
+ void ObjFile::parseSections (ArrayRef<Section> sections) {
157
158
subsections.reserve (sections.size ());
158
159
auto *buf = reinterpret_cast <const uint8_t *>(mb.getBufferStart ());
159
160
160
- for (const section_64 &sec : sections) {
161
+ for (const Section &sec : sections) {
161
162
InputSection *isec = make<InputSection>();
162
163
isec->file = this ;
163
164
isec->name =
@@ -204,7 +205,8 @@ static InputSection *findContainingSubsection(SubsectionMapping &map,
204
205
return it->isec ;
205
206
}
206
207
207
- static bool validateRelocationInfo (InputFile *file, const section_64 &sec,
208
+ template <class Section >
209
+ static bool validateRelocationInfo (InputFile *file, const Section &sec,
208
210
relocation_info rel) {
209
211
const RelocAttrs &relocAttrs = target->getRelocAttrs (rel.r_type );
210
212
bool valid = true ;
@@ -235,7 +237,9 @@ static bool validateRelocationInfo(InputFile *file, const section_64 &sec,
235
237
return valid;
236
238
}
237
239
238
- void ObjFile::parseRelocations (const section_64 &sec,
240
+ template <class Section >
241
+ void ObjFile::parseRelocations (ArrayRef<Section> sectionHeaders,
242
+ const Section &sec,
239
243
SubsectionMapping &subsecMap) {
240
244
auto *buf = reinterpret_cast <const uint8_t *>(mb.getBufferStart ());
241
245
ArrayRef<relocation_info> relInfos (
@@ -279,7 +283,7 @@ void ObjFile::parseRelocations(const section_64 &sec,
279
283
if (relInfo.r_address & R_SCATTERED)
280
284
fatal (" TODO: Scattered relocations not supported" );
281
285
282
- int64_t embeddedAddend = target->getEmbeddedAddend (mb, sec, relInfo);
286
+ int64_t embeddedAddend = target->getEmbeddedAddend (mb, sec. offset , relInfo);
283
287
assert (!(embeddedAddend && pairedAddend));
284
288
int64_t totalAddend = pairedAddend + embeddedAddend;
285
289
Reloc r;
@@ -293,7 +297,7 @@ void ObjFile::parseRelocations(const section_64 &sec,
293
297
} else {
294
298
SubsectionMapping &referentSubsecMap =
295
299
subsections[relInfo.r_symbolnum - 1 ];
296
- const section_64 &referentSec = sectionHeaders[relInfo.r_symbolnum - 1 ];
300
+ const Section &referentSec = sectionHeaders[relInfo.r_symbolnum - 1 ];
297
301
uint64_t referentOffset;
298
302
if (relInfo.r_pcrel ) {
299
303
// The implicit addend for pcrel section relocations is the pcrel offset
@@ -330,9 +334,10 @@ void ObjFile::parseRelocations(const section_64 &sec,
330
334
}
331
335
}
332
336
333
- static macho::Symbol *createDefined (const structs::nlist_64 &sym,
334
- StringRef name, InputSection *isec,
335
- uint64_t value, uint64_t size) {
337
+ template <class NList >
338
+ static macho::Symbol *createDefined (const NList &sym, StringRef name,
339
+ InputSection *isec, uint64_t value,
340
+ uint64_t size) {
336
341
// Symbol scope is determined by sym.n_type & (N_EXT | N_PEXT):
337
342
// N_EXT: Global symbols
338
343
// N_EXT | N_PEXT: Linkage unit (think: dylib) scoped
@@ -378,8 +383,9 @@ static bool hasCompatVersion(const InputFile *input,
378
383
379
384
// Absolute symbols are defined symbols that do not have an associated
380
385
// InputSection. They cannot be weak.
381
- static macho::Symbol *createAbsolute (const structs::nlist_64 &sym,
382
- InputFile *file, StringRef name) {
386
+ template <class NList >
387
+ static macho::Symbol *createAbsolute (const NList &sym, InputFile *file,
388
+ StringRef name) {
383
389
if (sym.n_type & (N_EXT | N_PEXT)) {
384
390
assert ((sym.n_type & N_EXT) && " invalid input" );
385
391
return symtab->addDefined (name, file, nullptr , sym.n_value , /* size=*/ 0 ,
@@ -390,7 +396,8 @@ static macho::Symbol *createAbsolute(const structs::nlist_64 &sym,
390
396
/* isExternal=*/ false , /* isPrivateExtern=*/ false );
391
397
}
392
398
393
- macho::Symbol *ObjFile::parseNonSectionSymbol (const structs::nlist_64 &sym,
399
+ template <class NList >
400
+ macho::Symbol *ObjFile::parseNonSectionSymbol (const NList &sym,
394
401
StringRef name) {
395
402
uint8_t type = sym.n_type & N_TYPE;
396
403
switch (type) {
@@ -414,14 +421,18 @@ macho::Symbol *ObjFile::parseNonSectionSymbol(const structs::nlist_64 &sym,
414
421
}
415
422
}
416
423
417
- void ObjFile::parseSymbols (ArrayRef<structs::nlist_64> nList,
424
+ template <class LP >
425
+ void ObjFile::parseSymbols (ArrayRef<typename LP::section> sectionHeaders,
426
+ ArrayRef<typename LP::nlist> nList,
418
427
const char *strtab, bool subsectionsViaSymbols) {
428
+ using Section = typename LP::section;
429
+ using NList = typename LP::nlist;
430
+
419
431
// Precompute the boundaries of symbols within a section.
420
432
// If subsectionsViaSymbols is True then the corresponding subsections will be
421
433
// created, otherwise these boundaries are used for the calculation of symbols
422
434
// sizes only.
423
-
424
- for (const structs::nlist_64 &sym : nList) {
435
+ for (const NList &sym : nList) {
425
436
if ((sym.n_type & N_TYPE) == N_SECT && !(sym.n_desc & N_ALT_ENTRY) &&
426
437
!subsections[sym.n_sect - 1 ].empty ()) {
427
438
SubsectionMapping &subsectionMapping = subsections[sym.n_sect - 1 ];
@@ -462,15 +473,15 @@ void ObjFile::parseSymbols(ArrayRef<structs::nlist_64> nList,
462
473
463
474
symbols.resize (nList.size ());
464
475
for (size_t i = 0 , n = nList.size (); i < n; ++i) {
465
- const structs::nlist_64 &sym = nList[i];
476
+ const NList &sym = nList[i];
466
477
StringRef name = strtab + sym.n_strx ;
467
478
468
479
if ((sym.n_type & N_TYPE) != N_SECT) {
469
480
symbols[i] = parseNonSectionSymbol (sym, name);
470
481
continue ;
471
482
}
472
483
473
- const section_64 &sec = sectionHeaders[sym.n_sect - 1 ];
484
+ const Section &sec = sectionHeaders[sym.n_sect - 1 ];
474
485
SubsectionMapping &subsecMap = subsections[sym.n_sect - 1 ];
475
486
476
487
// parseSections() may have chosen not to parse this section.
@@ -521,9 +532,20 @@ OpaqueFile::OpaqueFile(MemoryBufferRef mb, StringRef segName,
521
532
ObjFile::ObjFile (MemoryBufferRef mb, uint32_t modTime, StringRef archiveName)
522
533
: InputFile(ObjKind, mb), modTime(modTime) {
523
534
this ->archiveName = std::string (archiveName);
535
+ if (target->wordSize == 8 )
536
+ parse<LP64>();
537
+ else
538
+ parse<ILP32>();
539
+ }
540
+
541
+ template <class LP > void ObjFile::parse () {
542
+ using Header = typename LP::mach_header;
543
+ using SegmentCommand = typename LP::segment_command;
544
+ using Section = typename LP::section;
545
+ using NList = typename LP::nlist;
524
546
525
547
auto *buf = reinterpret_cast <const uint8_t *>(mb.getBufferStart ());
526
- auto *hdr = reinterpret_cast <const mach_header_64 *>(mb.getBufferStart ());
548
+ auto *hdr = reinterpret_cast <const Header *>(mb.getBufferStart ());
527
549
528
550
Architecture arch = getArchitectureFromCpuType (hdr->cputype , hdr->cpusubtype );
529
551
if (arch != config->target .Arch ) {
@@ -546,28 +568,29 @@ ObjFile::ObjFile(MemoryBufferRef mb, uint32_t modTime, StringRef archiveName)
546
568
parseLCLinkerOption (this , c->count , data);
547
569
}
548
570
549
- if (const load_command *cmd = findCommand (hdr, LC_SEGMENT_64)) {
550
- auto *c = reinterpret_cast <const segment_command_64 *>(cmd);
551
- sectionHeaders = ArrayRef<section_64>{
552
- reinterpret_cast <const section_64 *>(c + 1 ), c->nsects };
571
+ ArrayRef<Section> sectionHeaders;
572
+ if (const load_command *cmd = findCommand (hdr, LP::segmentLCType)) {
573
+ auto *c = reinterpret_cast <const SegmentCommand *>(cmd);
574
+ sectionHeaders =
575
+ ArrayRef<Section>{reinterpret_cast <const Section *>(c + 1 ), c->nsects };
553
576
parseSections (sectionHeaders);
554
577
}
555
578
556
579
// TODO: Error on missing LC_SYMTAB?
557
580
if (const load_command *cmd = findCommand (hdr, LC_SYMTAB)) {
558
581
auto *c = reinterpret_cast <const symtab_command *>(cmd);
559
- ArrayRef<structs::nlist_64 > nList (
560
- reinterpret_cast < const structs::nlist_64 *>(buf + c-> symoff ), c->nsyms );
582
+ ArrayRef<NList > nList (reinterpret_cast < const NList *>(buf + c-> symoff ),
583
+ c->nsyms );
561
584
const char *strtab = reinterpret_cast <const char *>(buf) + c->stroff ;
562
585
bool subsectionsViaSymbols = hdr->flags & MH_SUBSECTIONS_VIA_SYMBOLS;
563
- parseSymbols ( nList, strtab, subsectionsViaSymbols);
586
+ parseSymbols<LP>(sectionHeaders, nList, strtab, subsectionsViaSymbols);
564
587
}
565
588
566
589
// The relocations may refer to the symbols, so we parse them after we have
567
590
// parsed all the symbols.
568
591
for (size_t i = 0 , n = subsections.size (); i < n; ++i)
569
592
if (!subsections[i].empty ())
570
- parseRelocations (sectionHeaders[i], subsections[i]);
593
+ parseRelocations (sectionHeaders, sectionHeaders [i], subsections[i]);
571
594
572
595
parseDebugInfo ();
573
596
}
@@ -678,8 +701,16 @@ DylibFile::DylibFile(MemoryBufferRef mb, DylibFile *umbrella,
678
701
if (umbrella == nullptr )
679
702
umbrella = this ;
680
703
704
+ if (target->wordSize == 8 )
705
+ parse<LP64>(umbrella);
706
+ else
707
+ parse<ILP32>(umbrella);
708
+ }
709
+
710
+ template <class LP > void DylibFile::parse (DylibFile *umbrella) {
711
+ using Header = typename LP::mach_header;
681
712
auto *buf = reinterpret_cast <const uint8_t *>(mb.getBufferStart ());
682
- auto *hdr = reinterpret_cast <const mach_header_64 *>(mb.getBufferStart ());
713
+ auto *hdr = reinterpret_cast <const Header *>(mb.getBufferStart ());
683
714
684
715
// Initialize dylibName.
685
716
if (const load_command *cmd = findCommand (hdr, LC_ID_DYLIB)) {
@@ -716,8 +747,7 @@ DylibFile::DylibFile(MemoryBufferRef mb, DylibFile *umbrella,
716
747
return ;
717
748
}
718
749
719
- const uint8_t *p =
720
- reinterpret_cast <const uint8_t *>(hdr) + sizeof (mach_header_64);
750
+ const uint8_t *p = reinterpret_cast <const uint8_t *>(hdr) + sizeof (Header);
721
751
for (uint32_t i = 0 , n = hdr->ncmds ; i < n; ++i) {
722
752
auto *cmd = reinterpret_cast <const load_command *>(p);
723
753
p += cmd->cmdsize ;
@@ -888,3 +918,6 @@ BitcodeFile::BitcodeFile(MemoryBufferRef mbref)
888
918
for (const lto::InputFile::Symbol &objSym : obj->symbols ())
889
919
symbols.push_back (createBitcodeSymbol (objSym, *this ));
890
920
}
921
+
922
+ template void ObjFile::parse<LP64>();
923
+ template void DylibFile::parse<LP64>(DylibFile *umbrella);
0 commit comments