@@ -228,6 +228,12 @@ void RelocationSection<ELFT>::writeSection(llvm::FileOutputBuffer &Out) const {
228
228
writeRel (reinterpret_cast <Elf_Rela *>(Buf));
229
229
}
230
230
231
+ bool SectionWithStrTab::classof (const SectionBase *S) {
232
+ return isa<DynamicSymbolTableSection>(S) || isa<DynamicSection>(S);
233
+ }
234
+
235
+ void SectionWithStrTab::finalize () { this ->Link = StrTab->Index ; }
236
+
231
237
// Returns true IFF a section is wholly inside the range of a segment
232
238
static bool sectionWithinSegment (const SectionBase &Section,
233
239
const Segment &Segment) {
@@ -308,23 +314,20 @@ void Object<ELFT>::initSymbolTable(const llvm::object::ELFFile<ELFT> &ElfFile,
308
314
SymbolTableSection *SymTab) {
309
315
310
316
SymTab->Size = 0 ;
311
- if (SymbolTable->Link - 1 >= Sections.size ())
312
- error (" Symbol table has link index of " + Twine (SymbolTable->Link ) +
313
- " which is not a valid index" );
314
-
315
- if (auto StrTab =
316
- dyn_cast<StringTableSection>(Sections[SymbolTable->Link - 1 ].get ()))
317
- SymTab->setStrTab (StrTab);
318
- else
319
- error (" Symbol table has link index of " + Twine (SymbolTable->Link ) +
320
- " which is not a string table" );
317
+ SymTab->setStrTab (getSectionOfType<StringTableSection>(
318
+ SymbolTable->Link ,
319
+ " Symbol table has link index of " + Twine (SymTab->Link ) +
320
+ " which is not a valid index" ,
321
+ " Symbol table has link index of " + Twine (SymTab->Link ) +
322
+ " which is not a string table" ));
321
323
322
324
const Elf_Shdr &Shdr = *unwrapOrError (ElfFile.getSection (SymTab->Index ));
323
325
StringRef StrTabData = unwrapOrError (ElfFile.getStringTableForSymtab (Shdr));
324
326
325
327
for (const auto &Sym : unwrapOrError (ElfFile.symbols (&Shdr))) {
326
328
SectionBase *DefSection = nullptr ;
327
329
StringRef Name = unwrapOrError (Sym.getName (StrTabData));
330
+
328
331
if (Sym.st_shndx >= SHN_LORESERVE) {
329
332
if (!isValidReservedSectionIndex (Sym.st_shndx , Machine)) {
330
333
error (
@@ -333,12 +336,12 @@ void Object<ELFT>::initSymbolTable(const llvm::object::ELFFile<ELFT> &ElfFile,
333
336
Twine (Sym.st_shndx ));
334
337
}
335
338
} else if (Sym.st_shndx != SHN_UNDEF) {
336
- if (Sym. st_shndx >= Sections. size ())
337
- error ( " Symbol ' " + Name +
338
- " ' is defined in invalid section with index " +
339
+ DefSection = getSection (
340
+ Sym. st_shndx ,
341
+ " Symbol ' " + Name + " ' is defined in invalid section with index " +
339
342
Twine (Sym.st_shndx ));
340
- DefSection = Sections[Sym.st_shndx - 1 ].get ();
341
343
}
344
+
342
345
SymTab->addSymbol (Name, Sym.getBinding (), Sym.getType (), DefSection,
343
346
Sym.getValue (), Sym.st_shndx , Sym.st_size );
344
347
}
@@ -365,6 +368,22 @@ void initRelocations(RelocationSection<ELFT> *Relocs,
365
368
}
366
369
}
367
370
371
+ template <class ELFT >
372
+ SectionBase *Object<ELFT>::getSection(uint16_t Index, Twine ErrMsg) {
373
+ if (Index == SHN_UNDEF || Index > Sections.size ())
374
+ error (ErrMsg);
375
+ return Sections[Index - 1 ].get ();
376
+ }
377
+
378
+ template <class ELFT >
379
+ template <class T >
380
+ T *Object<ELFT>::getSectionOfType(uint16_t Index, Twine IndexErrMsg,
381
+ Twine TypeErrMsg) {
382
+ if (T *TSec = llvm::dyn_cast<T>(getSection (Index, IndexErrMsg)))
383
+ return TSec;
384
+ error (TypeErrMsg);
385
+ }
386
+
368
387
template <class ELFT >
369
388
std::unique_ptr<SectionBase>
370
389
Object<ELFT>::makeSection(const llvm::object::ELFFile<ELFT> &ElfFile,
@@ -375,7 +394,26 @@ Object<ELFT>::makeSection(const llvm::object::ELFFile<ELFT> &ElfFile,
375
394
case SHT_RELA:
376
395
return llvm::make_unique<RelocationSection<ELFT>>();
377
396
case SHT_STRTAB:
397
+ // If a string table is allocated we don't want to mess with it. That would
398
+ // mean altering the memory image. There are no special link types or
399
+ // anything so we can just use a Section.
400
+ if (Shdr.sh_flags & SHF_ALLOC) {
401
+ Data = unwrapOrError (ElfFile.getSectionContents (&Shdr));
402
+ return llvm::make_unique<Section>(Data);
403
+ }
378
404
return llvm::make_unique<StringTableSection>();
405
+ case SHT_HASH:
406
+ case SHT_GNU_HASH:
407
+ // Hash tables should refer to SHT_DYNSYM which we're not going to change.
408
+ // Because of this we don't need to mess with the hash tables either.
409
+ Data = unwrapOrError (ElfFile.getSectionContents (&Shdr));
410
+ return llvm::make_unique<Section>(Data);
411
+ case SHT_DYNSYM:
412
+ Data = unwrapOrError (ElfFile.getSectionContents (&Shdr));
413
+ return llvm::make_unique<DynamicSymbolTableSection>(Data);
414
+ case SHT_DYNAMIC:
415
+ Data = unwrapOrError (ElfFile.getSectionContents (&Shdr));
416
+ return llvm::make_unique<DynamicSection>(Data);
379
417
case SHT_SYMTAB: {
380
418
auto SymTab = llvm::make_unique<SymbolTableSectionImpl<ELFT>>();
381
419
SymbolTable = SymTab.get ();
@@ -423,28 +461,35 @@ void Object<ELFT>::readSectionHeaders(const ELFFile<ELFT> &ElfFile) {
423
461
// relocation sections.
424
462
for (auto &Section : Sections) {
425
463
if (auto RelSec = dyn_cast<RelocationSection<ELFT>>(Section.get ())) {
426
- if (RelSec->Link - 1 >= Sections.size () || RelSec->Link == 0 ) {
427
- error (" Link field value " + Twine (RelSec->Link ) + " in section " +
428
- RelSec->Name + " is invalid" );
429
- }
430
- if (RelSec->Info - 1 >= Sections.size () || RelSec->Info == 0 ) {
431
- error (" Info field value " + Twine (RelSec->Link ) + " in section " +
432
- RelSec->Name + " is invalid" );
433
- }
434
- auto SymTab =
435
- dyn_cast<SymbolTableSection>(Sections[RelSec->Link - 1 ].get ());
436
- if (SymTab == nullptr ) {
437
- error (" Link field of relocation section " + RelSec->Name +
438
- " is not a symbol table" );
439
- }
464
+
465
+ auto SymTab = getSectionOfType<SymbolTableSection>(
466
+ RelSec->Link ,
467
+ " Link field value " + Twine (RelSec->Link ) + " in section " +
468
+ RelSec->Name + " is invalid" ,
469
+ " Link field value " + Twine (RelSec->Link ) + " in section " +
470
+ RelSec->Name + " is not a symbol table" );
440
471
RelSec->setSymTab (SymTab);
441
- RelSec->setSection (Sections[RelSec->Info - 1 ].get ());
472
+
473
+ RelSec->setSection (getSection (RelSec->Info ,
474
+ " Info field value " + Twine (RelSec->Link ) +
475
+ " in section " + RelSec->Name +
476
+ " is invalid" ));
477
+
442
478
auto Shdr = unwrapOrError (ElfFile.sections ()).begin () + RelSec->Index ;
443
479
if (RelSec->Type == SHT_REL)
444
480
initRelocations (RelSec, SymTab, unwrapOrError (ElfFile.rels (Shdr)));
445
481
else
446
482
initRelocations (RelSec, SymTab, unwrapOrError (ElfFile.relas (Shdr)));
447
483
}
484
+
485
+ if (auto Sec = dyn_cast<SectionWithStrTab>(Section.get ())) {
486
+ Sec->setStrTab (getSectionOfType<StringTableSection>(
487
+ Sec->Link ,
488
+ " Link field value " + Twine (Sec->Link ) + " in section " + Sec->Name +
489
+ " is invalid" ,
490
+ " Link field value " + Twine (Sec->Link ) + " in section " + Sec->Name +
491
+ " is not a string table" ));
492
+ }
448
493
}
449
494
}
450
495
@@ -462,8 +507,12 @@ template <class ELFT> Object<ELFT>::Object(const ELFObjectFile<ELFT> &Obj) {
462
507
readSectionHeaders (ElfFile);
463
508
readProgramHeaders (ElfFile);
464
509
465
- SectionNames =
466
- dyn_cast<StringTableSection>(Sections[Ehdr.e_shstrndx - 1 ].get ());
510
+ SectionNames = getSectionOfType<StringTableSection>(
511
+ Ehdr.e_shstrndx ,
512
+ " e_shstrndx field value " + Twine (Ehdr.e_shstrndx ) + " in elf header " +
513
+ " is invalid" ,
514
+ " e_shstrndx field value " + Twine (Ehdr.e_shstrndx ) + " in elf header " +
515
+ " is not a string table" );
467
516
}
468
517
469
518
template <class ELFT >
0 commit comments