comparison tools/llvm-readobj/ARMEHABIPrinter.h @ 147:c2174574ed3a

LLVM 10
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Wed, 14 Aug 2019 16:55:33 +0900
parents 3a76565eade5
children
comparison
equal deleted inserted replaced
134:3a76565eade5 147:c2174574ed3a
1 //===--- ARMEHABIPrinter.h - ARM EHABI Unwind Information Printer ----------===// 1 //===--- ARMEHABIPrinter.h - ARM EHABI Unwind Information Printer ----------===//
2 // 2 //
3 // The LLVM Compiler Infrastructure 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // 4 // See https://llvm.org/LICENSE.txt for license information.
5 // This file is distributed under the University of Illinois Open Source 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 // License. See LICENSE.TXT for details.
7 // 6 //
8 //===----------------------------------------------------------------------===// 7 //===----------------------------------------------------------------------===//
9 8
10 #ifndef LLVM_TOOLS_LLVM_READOBJ_ARMEHABIPRINTER_H 9 #ifndef LLVM_TOOLS_LLVM_READOBJ_ARMEHABIPRINTER_H
11 #define LLVM_TOOLS_LLVM_READOBJ_ARMEHABIPRINTER_H 10 #define LLVM_TOOLS_LLVM_READOBJ_ARMEHABIPRINTER_H
328 typedef typename ET::Rel Elf_Rel; 327 typedef typename ET::Rel Elf_Rel;
329 typedef typename ET::Word Elf_Word; 328 typedef typename ET::Word Elf_Word;
330 329
331 ScopedPrinter &SW; 330 ScopedPrinter &SW;
332 const object::ELFFile<ET> *ELF; 331 const object::ELFFile<ET> *ELF;
332 StringRef FileName;
333 const Elf_Shdr *Symtab; 333 const Elf_Shdr *Symtab;
334 ArrayRef<Elf_Word> ShndxTable; 334 ArrayRef<Elf_Word> ShndxTable;
335 335
336 static const size_t IndexTableEntrySize; 336 static const size_t IndexTableEntrySize;
337 337
351 uint64_t TableEntryOffset) const; 351 uint64_t TableEntryOffset) const;
352 void PrintOpcodes(const uint8_t *Entry, size_t Length, off_t Offset) const; 352 void PrintOpcodes(const uint8_t *Entry, size_t Length, off_t Offset) const;
353 353
354 public: 354 public:
355 PrinterContext(ScopedPrinter &SW, const object::ELFFile<ET> *ELF, 355 PrinterContext(ScopedPrinter &SW, const object::ELFFile<ET> *ELF,
356 const Elf_Shdr *Symtab) 356 StringRef FileName, const Elf_Shdr *Symtab)
357 : SW(SW), ELF(ELF), Symtab(Symtab) {} 357 : SW(SW), ELF(ELF), FileName(FileName), Symtab(Symtab) {}
358 358
359 void PrintUnwindInformation() const; 359 void PrintUnwindInformation() const;
360 }; 360 };
361 361
362 template <typename ET> 362 template <typename ET>
364 364
365 template <typename ET> 365 template <typename ET>
366 ErrorOr<StringRef> 366 ErrorOr<StringRef>
367 PrinterContext<ET>::FunctionAtAddress(unsigned Section, 367 PrinterContext<ET>::FunctionAtAddress(unsigned Section,
368 uint64_t Address) const { 368 uint64_t Address) const {
369 if (!Symtab)
370 return readobj_error::unknown_symbol;
369 auto StrTableOrErr = ELF->getStringTableForSymtab(*Symtab); 371 auto StrTableOrErr = ELF->getStringTableForSymtab(*Symtab);
370 if (!StrTableOrErr) 372 if (!StrTableOrErr)
371 error(StrTableOrErr.takeError()); 373 reportError(StrTableOrErr.takeError(), FileName);
372 StringRef StrTable = *StrTableOrErr; 374 StringRef StrTable = *StrTableOrErr;
373 375
374 for (const Elf_Sym &Sym : unwrapOrError(ELF->symbols(Symtab))) 376 for (const Elf_Sym &Sym : unwrapOrError(FileName, ELF->symbols(Symtab)))
375 if (Sym.st_shndx == Section && Sym.st_value == Address && 377 if (Sym.st_shndx == Section && Sym.st_value == Address &&
376 Sym.getType() == ELF::STT_FUNC) { 378 Sym.getType() == ELF::STT_FUNC) {
377 auto NameOrErr = Sym.getName(StrTable); 379 auto NameOrErr = Sym.getName(StrTable);
378 if (!NameOrErr) { 380 if (!NameOrErr) {
379 // TODO: Actually report errors helpfully. 381 // TODO: Actually report errors helpfully.
395 /// relocation associated with the index table entry specified by 397 /// relocation associated with the index table entry specified by
396 /// IndexTableOffset. The symbol is the section symbol for the exception 398 /// IndexTableOffset. The symbol is the section symbol for the exception
397 /// handling table. Use this symbol to recover the actual exception handling 399 /// handling table. Use this symbol to recover the actual exception handling
398 /// table. 400 /// table.
399 401
400 for (const Elf_Shdr &Sec : unwrapOrError(ELF->sections())) { 402 for (const Elf_Shdr &Sec : unwrapOrError(FileName, ELF->sections())) {
401 if (Sec.sh_type != ELF::SHT_REL || Sec.sh_info != IndexSectionIndex) 403 if (Sec.sh_type != ELF::SHT_REL || Sec.sh_info != IndexSectionIndex)
402 continue; 404 continue;
403 405
404 auto SymTabOrErr = ELF->getSection(Sec.sh_link); 406 auto SymTabOrErr = ELF->getSection(Sec.sh_link);
405 if (!SymTabOrErr) 407 if (!SymTabOrErr)
406 error(SymTabOrErr.takeError()); 408 reportError(SymTabOrErr.takeError(), FileName);
407 const Elf_Shdr *SymTab = *SymTabOrErr; 409 const Elf_Shdr *SymTab = *SymTabOrErr;
408 410
409 for (const Elf_Rel &R : unwrapOrError(ELF->rels(&Sec))) { 411 for (const Elf_Rel &R : unwrapOrError(FileName, ELF->rels(&Sec))) {
410 if (R.r_offset != static_cast<unsigned>(IndexTableOffset)) 412 if (R.r_offset != static_cast<unsigned>(IndexTableOffset))
411 continue; 413 continue;
412 414
413 typename ET::Rela RelA; 415 typename ET::Rela RelA;
414 RelA.r_offset = R.r_offset; 416 RelA.r_offset = R.r_offset;
415 RelA.r_info = R.r_info; 417 RelA.r_info = R.r_info;
416 RelA.r_addend = 0; 418 RelA.r_addend = 0;
417 419
418 const Elf_Sym *Symbol = 420 const Elf_Sym *Symbol =
419 unwrapOrError(ELF->getRelocationSymbol(&RelA, SymTab)); 421 unwrapOrError(FileName, ELF->getRelocationSymbol(&RelA, SymTab));
420 422
421 auto Ret = ELF->getSection(Symbol, SymTab, ShndxTable); 423 auto Ret = ELF->getSection(Symbol, SymTab, ShndxTable);
422 if (!Ret) 424 if (!Ret)
423 report_fatal_error(errorToErrorCode(Ret.takeError()).message()); 425 report_fatal_error(errorToErrorCode(Ret.takeError()).message());
424 return *Ret; 426 return *Ret;
549 PrintOpcodes(Contents->data() + Entry * IndexTableEntrySize + 4, 3, 1); 551 PrintOpcodes(Contents->data() + Entry * IndexTableEntrySize + 4, 3, 1);
550 } else { 552 } else {
551 const Elf_Shdr *EHT = 553 const Elf_Shdr *EHT =
552 FindExceptionTable(SectionIndex, Entry * IndexTableEntrySize + 4); 554 FindExceptionTable(SectionIndex, Entry * IndexTableEntrySize + 4);
553 555
554 if (auto Name = ELF->getSectionName(EHT)) 556 if (EHT)
555 SW.printString("ExceptionHandlingTable", *Name); 557 if (auto Name = ELF->getSectionName(EHT))
558 SW.printString("ExceptionHandlingTable", *Name);
556 559
557 uint64_t TableEntryOffset = PREL31(Word1, IT->sh_addr); 560 uint64_t TableEntryOffset = PREL31(Word1, IT->sh_addr);
558 SW.printHex("TableEntryOffset", TableEntryOffset); 561 SW.printHex("TableEntryOffset", TableEntryOffset);
559 562
560 PrintExceptionTable(IT, EHT, TableEntryOffset); 563 if (EHT)
564 PrintExceptionTable(IT, EHT, TableEntryOffset);
561 } 565 }
562 } 566 }
563 } 567 }
564 568
565 template <typename ET> 569 template <typename ET>
566 void PrinterContext<ET>::PrintUnwindInformation() const { 570 void PrinterContext<ET>::PrintUnwindInformation() const {
567 DictScope UI(SW, "UnwindInformation"); 571 DictScope UI(SW, "UnwindInformation");
568 572
569 int SectionIndex = 0; 573 int SectionIndex = 0;
570 for (const Elf_Shdr &Sec : unwrapOrError(ELF->sections())) { 574 for (const Elf_Shdr &Sec : unwrapOrError(FileName, ELF->sections())) {
571 if (Sec.sh_type == ELF::SHT_ARM_EXIDX) { 575 if (Sec.sh_type == ELF::SHT_ARM_EXIDX) {
572 DictScope UIT(SW, "UnwindIndexTable"); 576 DictScope UIT(SW, "UnwindIndexTable");
573 577
574 SW.printNumber("SectionIndex", SectionIndex); 578 SW.printNumber("SectionIndex", SectionIndex);
575 if (auto SectionName = ELF->getSectionName(&Sec)) 579 if (auto SectionName = ELF->getSectionName(&Sec))