136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//===--- ARMEHABIPrinter.h - ARM EHABI Unwind Information Printer ----------===// 236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// 336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// The LLVM Compiler Infrastructure 436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// 536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// This file is distributed under the University of Illinois Open Source 636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// License. See LICENSE.TXT for details. 736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// 836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//===----------------------------------------------------------------------===// 936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 1037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#ifndef LLVM_TOOLS_LLVM_READOBJ_ARMEHABIPRINTER_H 1137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#define LLVM_TOOLS_LLVM_READOBJ_ARMEHABIPRINTER_H 1236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 1336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "Error.h" 14de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#include "llvm-readobj.h" 15dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "llvm/ADT/STLExtras.h" 1636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Object/ELF.h" 1736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Object/ELFTypes.h" 1836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Support/ARMEHABI.h" 1936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Support/Debug.h" 2036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Support/Endian.h" 2136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Support/Format.h" 22de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#include "llvm/Support/ScopedPrinter.h" 2336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Support/type_traits.h" 2436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 2536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesnamespace llvm { 2636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesnamespace ARM { 2736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesnamespace EHABI { 2836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 2936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesclass OpcodeDecoder { 30de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ScopedPrinter &SW; 3136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines raw_ostream &OS; 3236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 3336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines struct RingEntry { 3436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint8_t Mask; 3536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint8_t Value; 3636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void (OpcodeDecoder::*Routine)(const uint8_t *Opcodes, unsigned &OI); 3736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines }; 3836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines static const RingEntry Ring[]; 3936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 4036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void Decode_00xxxxxx(const uint8_t *Opcodes, unsigned &OI); 4136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void Decode_01xxxxxx(const uint8_t *Opcodes, unsigned &OI); 4236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void Decode_1000iiii_iiiiiiii(const uint8_t *Opcodes, unsigned &OI); 4336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void Decode_10011101(const uint8_t *Opcodes, unsigned &OI); 4436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void Decode_10011111(const uint8_t *Opcodes, unsigned &OI); 4536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void Decode_1001nnnn(const uint8_t *Opcodes, unsigned &OI); 4636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void Decode_10100nnn(const uint8_t *Opcodes, unsigned &OI); 4736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void Decode_10101nnn(const uint8_t *Opcodes, unsigned &OI); 4836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void Decode_10110000(const uint8_t *Opcodes, unsigned &OI); 4936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void Decode_10110001_0000iiii(const uint8_t *Opcodes, unsigned &OI); 5036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void Decode_10110010_uleb128(const uint8_t *Opcodes, unsigned &OI); 5136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void Decode_10110011_sssscccc(const uint8_t *Opcodes, unsigned &OI); 5236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void Decode_101101nn(const uint8_t *Opcodes, unsigned &OI); 5336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void Decode_10111nnn(const uint8_t *Opcodes, unsigned &OI); 5436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void Decode_11000110_sssscccc(const uint8_t *Opcodes, unsigned &OI); 5536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void Decode_11000111_0000iiii(const uint8_t *Opcodes, unsigned &OI); 5636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void Decode_11001000_sssscccc(const uint8_t *Opcodes, unsigned &OI); 5736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void Decode_11001001_sssscccc(const uint8_t *Opcodes, unsigned &OI); 5836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void Decode_11001yyy(const uint8_t *Opcodes, unsigned &OI); 5936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void Decode_11000nnn(const uint8_t *Opcodes, unsigned &OI); 6036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void Decode_11010nnn(const uint8_t *Opcodes, unsigned &OI); 6136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void Decode_11xxxyyy(const uint8_t *Opcodes, unsigned &OI); 6236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 6336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void PrintGPR(uint16_t GPRMask); 6436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void PrintRegisters(uint32_t Mask, StringRef Prefix); 6536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 6636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinespublic: 67de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar OpcodeDecoder(ScopedPrinter &SW) : SW(SW), OS(SW.getOStream()) {} 6836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void Decode(const uint8_t *Opcodes, off_t Offset, size_t Length); 6936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}; 7036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 7136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesconst OpcodeDecoder::RingEntry OpcodeDecoder::Ring[] = { 7236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines { 0xc0, 0x00, &OpcodeDecoder::Decode_00xxxxxx }, 7336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines { 0xc0, 0x40, &OpcodeDecoder::Decode_01xxxxxx }, 7436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines { 0xf0, 0x80, &OpcodeDecoder::Decode_1000iiii_iiiiiiii }, 7536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines { 0xff, 0x9d, &OpcodeDecoder::Decode_10011101 }, 7636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines { 0xff, 0x9f, &OpcodeDecoder::Decode_10011111 }, 7736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines { 0xf0, 0x90, &OpcodeDecoder::Decode_1001nnnn }, 7836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines { 0xf8, 0xa0, &OpcodeDecoder::Decode_10100nnn }, 7936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines { 0xf8, 0xa8, &OpcodeDecoder::Decode_10101nnn }, 8036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines { 0xff, 0xb0, &OpcodeDecoder::Decode_10110000 }, 8136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines { 0xff, 0xb1, &OpcodeDecoder::Decode_10110001_0000iiii }, 8236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines { 0xff, 0xb2, &OpcodeDecoder::Decode_10110010_uleb128 }, 8336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines { 0xff, 0xb3, &OpcodeDecoder::Decode_10110011_sssscccc }, 8436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines { 0xfc, 0xb4, &OpcodeDecoder::Decode_101101nn }, 8536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines { 0xf8, 0xb8, &OpcodeDecoder::Decode_10111nnn }, 8636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines { 0xff, 0xc6, &OpcodeDecoder::Decode_11000110_sssscccc }, 8736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines { 0xff, 0xc7, &OpcodeDecoder::Decode_11000111_0000iiii }, 8836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines { 0xff, 0xc8, &OpcodeDecoder::Decode_11001000_sssscccc }, 8936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines { 0xff, 0xc9, &OpcodeDecoder::Decode_11001001_sssscccc }, 9036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines { 0xc8, 0xc8, &OpcodeDecoder::Decode_11001yyy }, 9136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines { 0xf8, 0xc0, &OpcodeDecoder::Decode_11000nnn }, 9236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines { 0xf8, 0xd0, &OpcodeDecoder::Decode_11010nnn }, 9336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines { 0xc0, 0xc0, &OpcodeDecoder::Decode_11xxxyyy }, 9436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}; 9536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 9636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid OpcodeDecoder::Decode_00xxxxxx(const uint8_t *Opcodes, unsigned &OI) { 9736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint8_t Opcode = Opcodes[OI++ ^ 3]; 9836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SW.startLine() << format("0x%02X ; vsp = vsp + %u\n", Opcode, 9936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ((Opcode & 0x3f) << 2) + 4); 10036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 10136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid OpcodeDecoder::Decode_01xxxxxx(const uint8_t *Opcodes, unsigned &OI) { 10236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint8_t Opcode = Opcodes[OI++ ^ 3]; 10336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SW.startLine() << format("0x%02X ; vsp = vsp - %u\n", Opcode, 10436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ((Opcode & 0x3f) << 2) + 4); 10536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 10636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid OpcodeDecoder::Decode_1000iiii_iiiiiiii(const uint8_t *Opcodes, 10736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned &OI) { 10836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint8_t Opcode0 = Opcodes[OI++ ^ 3]; 10936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint8_t Opcode1 = Opcodes[OI++ ^ 3]; 11036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 11136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint16_t GPRMask = (Opcode1 << 4) | ((Opcode0 & 0x0f) << 12); 11236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SW.startLine() 11336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines << format("0x%02X 0x%02X ; %s", 11436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Opcode0, Opcode1, GPRMask ? "pop " : "refuse to unwind"); 11536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (GPRMask) 11636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines PrintGPR(GPRMask); 11736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OS << '\n'; 11836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 11936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid OpcodeDecoder::Decode_10011101(const uint8_t *Opcodes, unsigned &OI) { 12036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint8_t Opcode = Opcodes[OI++ ^ 3]; 12136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SW.startLine() << format("0x%02X ; reserved (ARM MOVrr)\n", Opcode); 12236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 12336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid OpcodeDecoder::Decode_10011111(const uint8_t *Opcodes, unsigned &OI) { 12436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint8_t Opcode = Opcodes[OI++ ^ 3]; 12536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SW.startLine() << format("0x%02X ; reserved (WiMMX MOVrr)\n", Opcode); 12636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 12736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid OpcodeDecoder::Decode_1001nnnn(const uint8_t *Opcodes, unsigned &OI) { 12836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint8_t Opcode = Opcodes[OI++ ^ 3]; 12936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SW.startLine() << format("0x%02X ; vsp = r%u\n", Opcode, (Opcode & 0x0f)); 13036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 13136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid OpcodeDecoder::Decode_10100nnn(const uint8_t *Opcodes, unsigned &OI) { 13236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint8_t Opcode = Opcodes[OI++ ^ 3]; 13336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SW.startLine() << format("0x%02X ; pop ", Opcode); 13436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines PrintGPR((((1 << ((Opcode & 0x7) + 1)) - 1) << 4)); 13536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OS << '\n'; 13636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 13736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid OpcodeDecoder::Decode_10101nnn(const uint8_t *Opcodes, unsigned &OI) { 13836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint8_t Opcode = Opcodes[OI++ ^ 3]; 13936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SW.startLine() << format("0x%02X ; pop ", Opcode); 14036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines PrintGPR((((1 << ((Opcode & 0x7) + 1)) - 1) << 4) | (1 << 14)); 14136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OS << '\n'; 14236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 14336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid OpcodeDecoder::Decode_10110000(const uint8_t *Opcodes, unsigned &OI) { 14436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint8_t Opcode = Opcodes[OI++ ^ 3]; 14536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SW.startLine() << format("0x%02X ; finish\n", Opcode); 14636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 14736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid OpcodeDecoder::Decode_10110001_0000iiii(const uint8_t *Opcodes, 14836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned &OI) { 14936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint8_t Opcode0 = Opcodes[OI++ ^ 3]; 15036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint8_t Opcode1 = Opcodes[OI++ ^ 3]; 15136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 15236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SW.startLine() 15336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines << format("0x%02X 0x%02X ; %s", Opcode0, Opcode1, 15436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ((Opcode1 & 0xf0) || Opcode1 == 0x00) ? "spare" : "pop "); 15536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (((Opcode1 & 0xf0) == 0x00) && Opcode1) 15636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines PrintGPR((Opcode1 & 0x0f)); 15736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OS << '\n'; 15836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 15936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid OpcodeDecoder::Decode_10110010_uleb128(const uint8_t *Opcodes, 16036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned &OI) { 16136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint8_t Opcode = Opcodes[OI++ ^ 3]; 16236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SW.startLine() << format("0x%02X ", Opcode); 16336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 16436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVector<uint8_t, 4> ULEB; 16536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines do { ULEB.push_back(Opcodes[OI ^ 3]); } while (Opcodes[OI++ ^ 3] & 0x80); 16636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 16736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (unsigned BI = 0, BE = ULEB.size(); BI != BE; ++BI) 16836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OS << format("0x%02X ", ULEB[BI]); 16936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 17036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t Value = 0; 17136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (unsigned BI = 0, BE = ULEB.size(); BI != BE; ++BI) 17236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Value = Value | ((ULEB[BI] & 0x7f) << (7 * BI)); 17336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 17436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OS << format("; vsp = vsp + %" PRIu64 "\n", 0x204 + (Value << 2)); 17536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 17636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid OpcodeDecoder::Decode_10110011_sssscccc(const uint8_t *Opcodes, 17736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned &OI) { 17836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint8_t Opcode0 = Opcodes[OI++ ^ 3]; 17936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint8_t Opcode1 = Opcodes[OI++ ^ 3]; 18036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SW.startLine() << format("0x%02X 0x%02X ; pop ", Opcode0, Opcode1); 18136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint8_t Start = ((Opcode1 & 0xf0) >> 4); 18236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint8_t Count = ((Opcode1 & 0x0f) >> 0); 18336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines PrintRegisters((((1 << (Count + 1)) - 1) << Start), "d"); 18436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OS << '\n'; 18536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 18636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid OpcodeDecoder::Decode_101101nn(const uint8_t *Opcodes, unsigned &OI) { 18736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint8_t Opcode = Opcodes[OI++ ^ 3]; 18836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SW.startLine() << format("0x%02X ; spare\n", Opcode); 18936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 19036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid OpcodeDecoder::Decode_10111nnn(const uint8_t *Opcodes, unsigned &OI) { 19136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint8_t Opcode = Opcodes[OI++ ^ 3]; 19236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SW.startLine() << format("0x%02X ; pop ", Opcode); 19336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines PrintRegisters((((1 << ((Opcode & 0x07) + 1)) - 1) << 8), "d"); 19436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OS << '\n'; 19536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 19636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid OpcodeDecoder::Decode_11000110_sssscccc(const uint8_t *Opcodes, 19736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned &OI) { 19836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint8_t Opcode0 = Opcodes[OI++ ^ 3]; 19936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint8_t Opcode1 = Opcodes[OI++ ^ 3]; 20036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SW.startLine() << format("0x%02X 0x%02X ; pop ", Opcode0, Opcode1); 20136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint8_t Start = ((Opcode1 & 0xf0) >> 4); 20236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint8_t Count = ((Opcode1 & 0x0f) >> 0); 20336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines PrintRegisters((((1 << (Count + 1)) - 1) << Start), "wR"); 20436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OS << '\n'; 20536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 20636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid OpcodeDecoder::Decode_11000111_0000iiii(const uint8_t *Opcodes, 20736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned &OI) { 20836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint8_t Opcode0 = Opcodes[OI++ ^ 3]; 20936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint8_t Opcode1 = Opcodes[OI++ ^ 3]; 21036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SW.startLine() 21136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines << format("0x%02X 0x%02X ; %s", Opcode0, Opcode1, 21236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ((Opcode1 & 0xf0) || Opcode1 == 0x00) ? "spare" : "pop "); 21336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if ((Opcode1 & 0xf0) == 0x00 && Opcode1) 21436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines PrintRegisters(Opcode1 & 0x0f, "wCGR"); 21536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OS << '\n'; 21636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 21736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid OpcodeDecoder::Decode_11001000_sssscccc(const uint8_t *Opcodes, 21836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned &OI) { 21936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint8_t Opcode0 = Opcodes[OI++ ^ 3]; 22036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint8_t Opcode1 = Opcodes[OI++ ^ 3]; 22136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SW.startLine() << format("0x%02X 0x%02X ; pop ", Opcode0, Opcode1); 22236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint8_t Start = 16 + ((Opcode1 & 0xf0) >> 4); 22336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint8_t Count = ((Opcode1 & 0x0f) >> 0); 22436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines PrintRegisters((((1 << (Count + 1)) - 1) << Start), "d"); 22536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OS << '\n'; 22636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 22736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid OpcodeDecoder::Decode_11001001_sssscccc(const uint8_t *Opcodes, 22836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned &OI) { 22936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint8_t Opcode0 = Opcodes[OI++ ^ 3]; 23036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint8_t Opcode1 = Opcodes[OI++ ^ 3]; 23136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SW.startLine() << format("0x%02X 0x%02X ; pop ", Opcode0, Opcode1); 23236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint8_t Start = ((Opcode1 & 0xf0) >> 4); 23336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint8_t Count = ((Opcode1 & 0x0f) >> 0); 23436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines PrintRegisters((((1 << (Count + 1)) - 1) << Start), "d"); 23536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OS << '\n'; 23636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 23736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid OpcodeDecoder::Decode_11001yyy(const uint8_t *Opcodes, unsigned &OI) { 23836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint8_t Opcode = Opcodes[OI++ ^ 3]; 23936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SW.startLine() << format("0x%02X ; spare\n", Opcode); 24036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 24136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid OpcodeDecoder::Decode_11000nnn(const uint8_t *Opcodes, unsigned &OI) { 24236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint8_t Opcode = Opcodes[OI++ ^ 3]; 24336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SW.startLine() << format("0x%02X ; pop ", Opcode); 24436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines PrintRegisters((((1 << ((Opcode & 0x07) + 1)) - 1) << 10), "wR"); 24536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OS << '\n'; 24636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 24736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid OpcodeDecoder::Decode_11010nnn(const uint8_t *Opcodes, unsigned &OI) { 24836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint8_t Opcode = Opcodes[OI++ ^ 3]; 24936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SW.startLine() << format("0x%02X ; pop ", Opcode); 25036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines PrintRegisters((((1 << ((Opcode & 0x07) + 1)) - 1) << 8), "d"); 25136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OS << '\n'; 25236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 25336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid OpcodeDecoder::Decode_11xxxyyy(const uint8_t *Opcodes, unsigned &OI) { 25436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint8_t Opcode = Opcodes[OI++ ^ 3]; 25536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SW.startLine() << format("0x%02X ; spare\n", Opcode); 25636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 25736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 25836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid OpcodeDecoder::PrintGPR(uint16_t GPRMask) { 25936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines static const char *GPRRegisterNames[16] = { 26036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", 26136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines "fp", "ip", "sp", "lr", "pc" 26236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines }; 26336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 26436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OS << '{'; 26536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool Comma = false; 26636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (unsigned RI = 0, RE = 17; RI < RE; ++RI) { 26736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (GPRMask & (1 << RI)) { 26836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Comma) 26936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OS << ", "; 27036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OS << GPRRegisterNames[RI]; 27136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Comma = true; 27236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 27336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 27436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OS << '}'; 27536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 27636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 27736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid OpcodeDecoder::PrintRegisters(uint32_t VFPMask, StringRef Prefix) { 27836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OS << '{'; 27936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool Comma = false; 28036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (unsigned RI = 0, RE = 32; RI < RE; ++RI) { 28136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (VFPMask & (1 << RI)) { 28236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Comma) 28336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OS << ", "; 28436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OS << Prefix << RI; 28536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Comma = true; 28636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 28736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 28836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OS << '}'; 28936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 29036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 29136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid OpcodeDecoder::Decode(const uint8_t *Opcodes, off_t Offset, size_t Length) { 29236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (unsigned OCI = Offset; OCI < Length + Offset; ) { 29336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool Decoded = false; 294dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines for (unsigned REI = 0, REE = array_lengthof(Ring); 295dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines REI != REE && !Decoded; ++REI) { 29636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if ((Opcodes[OCI ^ 3] & Ring[REI].Mask) == Ring[REI].Value) { 29736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines (this->*Ring[REI].Routine)(Opcodes, OCI); 29836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Decoded = true; 29936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 30036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 30136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 30236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!Decoded) 30336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SW.startLine() << format("0x%02X ; reserved\n", Opcodes[OCI++ ^ 3]); 30436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 30536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 30636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 30736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinestemplate <typename ET> 30836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesclass PrinterContext { 30936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines typedef typename object::ELFFile<ET>::Elf_Sym Elf_Sym; 31036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines typedef typename object::ELFFile<ET>::Elf_Shdr Elf_Shdr; 311f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar typedef typename object::ELFFile<ET>::Elf_Rel Elf_Rel; 312f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar typedef typename object::ELFFile<ET>::Elf_Word Elf_Word; 31336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 314de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ScopedPrinter &SW; 315f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar const object::ELFFile<ET> *ELF; 316f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar const Elf_Shdr *Symtab; 317f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar ArrayRef<Elf_Word> ShndxTable; 31836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 31936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines static const size_t IndexTableEntrySize; 32036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 32136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines static uint64_t PREL31(uint32_t Address, uint32_t Place) { 32236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t Location = Address & 0x7fffffff; 32336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Location & 0x04000000) 32436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Location |= (uint64_t) ~0x7fffffff; 32536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return Location + Place; 32636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 32736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 32836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ErrorOr<StringRef> FunctionAtAddress(unsigned Section, uint64_t Address) const; 32936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const Elf_Shdr *FindExceptionTable(unsigned IndexTableIndex, 33036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines off_t IndexTableOffset) const; 33136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 33236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void PrintIndexTable(unsigned SectionIndex, const Elf_Shdr *IT) const; 33336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void PrintExceptionTable(const Elf_Shdr *IT, const Elf_Shdr *EHT, 33436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t TableEntryOffset) const; 33536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void PrintOpcodes(const uint8_t *Entry, size_t Length, off_t Offset) const; 33636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 33736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinespublic: 338de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar PrinterContext(ScopedPrinter &SW, const object::ELFFile<ET> *ELF, 339f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar const Elf_Shdr *Symtab) 340f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar : SW(SW), ELF(ELF), Symtab(Symtab) {} 34136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 34236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void PrintUnwindInformation() const; 34336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}; 34436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 34536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinestemplate <typename ET> 34636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesconst size_t PrinterContext<ET>::IndexTableEntrySize = 8; 34736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 34836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinestemplate <typename ET> 349f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga NainarErrorOr<StringRef> 350f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga NainarPrinterContext<ET>::FunctionAtAddress(unsigned Section, 351f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar uint64_t Address) const { 352f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar ErrorOr<StringRef> StrTableOrErr = ELF->getStringTableForSymtab(*Symtab); 353f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar error(StrTableOrErr.getError()); 354f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar StringRef StrTable = *StrTableOrErr; 355f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 356f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar for (const Elf_Sym &Sym : ELF->symbols(Symtab)) 357f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (Sym.st_shndx == Section && Sym.st_value == Address && 358de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Sym.getType() == ELF::STT_FUNC) { 359de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto NameOrErr = Sym.getName(StrTable); 360de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (!NameOrErr) { 361de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // TODO: Actually report errors helpfully. 362de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar consumeError(NameOrErr.takeError()); 363de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return readobj_error::unknown_symbol; 364de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 365de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return *NameOrErr; 366de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 36736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return readobj_error::unknown_symbol; 36836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 36936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 37036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinestemplate <typename ET> 37136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesconst typename object::ELFFile<ET>::Elf_Shdr * 37236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesPrinterContext<ET>::FindExceptionTable(unsigned IndexSectionIndex, 37336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines off_t IndexTableOffset) const { 37436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// Iterate through the sections, searching for the relocation section 37536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// associated with the unwind index table section specified by 37636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// IndexSectionIndex. Iterate the associated section searching for the 37736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// relocation associated with the index table entry specified by 37836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// IndexTableOffset. The symbol is the section symbol for the exception 37936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// handling table. Use this symbol to recover the actual exception handling 38036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// table. 38136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 382f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar for (const Elf_Shdr &Sec : ELF->sections()) { 383f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (Sec.sh_type != ELF::SHT_REL || Sec.sh_info != IndexSectionIndex) 384f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar continue; 385f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 386f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar ErrorOr<const Elf_Shdr *> SymTabOrErr = ELF->getSection(Sec.sh_link); 387f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar error(SymTabOrErr.getError()); 388f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar const Elf_Shdr *SymTab = *SymTabOrErr; 389f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 390f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar for (const Elf_Rel &R : ELF->rels(&Sec)) { 391f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (R.r_offset != static_cast<unsigned>(IndexTableOffset)) 392f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar continue; 393f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 394f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar typename object::ELFFile<ET>::Elf_Rela RelA; 395f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar RelA.r_offset = R.r_offset; 396f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar RelA.r_info = R.r_info; 397f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar RelA.r_addend = 0; 398f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 399f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar const Elf_Sym *Symbol = ELF->getRelocationSymbol(&RelA, SymTab); 400f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 401f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar ErrorOr<const Elf_Shdr *> Ret = 402f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar ELF->getSection(Symbol, SymTab, ShndxTable); 403f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (std::error_code EC = Ret.getError()) 404f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar report_fatal_error(EC.message()); 405f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return *Ret; 40636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 40736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 408dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return nullptr; 40936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 41036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 41136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinestemplate <typename ET> 41236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid PrinterContext<ET>::PrintExceptionTable(const Elf_Shdr *IT, 41336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const Elf_Shdr *EHT, 41436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t TableEntryOffset) const { 41536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ErrorOr<ArrayRef<uint8_t> > Contents = ELF->getSectionContents(EHT); 41636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!Contents) 41736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return; 41836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 41936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// ARM EHABI Section 6.2 - The generic model 42036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// 42136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// An exception-handling table entry for the generic model is laid out as: 42236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// 42336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// 3 3 42436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// 1 0 0 42536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// +-+------------------------------+ 42636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// |0| personality routine offset | 42736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// +-+------------------------------+ 42836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// | personality routine data ... | 42936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// 43036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// 43136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// ARM EHABI Section 6.3 - The ARM-defined compact model 43236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// 43336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// An exception-handling table entry for the compact model looks like: 43436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// 43536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// 3 3 2 2 2 2 43636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// 1 0 8 7 4 3 0 43736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// +-+---+----+-----------------------+ 43836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// |1| 0 | Ix | data for pers routine | 43936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// +-+---+----+-----------------------+ 44036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// | more personality routine data | 44136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 44236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const support::ulittle32_t Word = 44336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines *reinterpret_cast<const support::ulittle32_t *>(Contents->data() + TableEntryOffset); 44436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 44536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Word & 0x80000000) { 44636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SW.printString("Model", StringRef("Compact")); 44736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 44836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned PersonalityIndex = (Word & 0x0f000000) >> 24; 44936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SW.printNumber("PersonalityIndex", PersonalityIndex); 45036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 45136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines switch (PersonalityIndex) { 45236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case AEABI_UNWIND_CPP_PR0: 45336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines PrintOpcodes(Contents->data() + TableEntryOffset, 3, 1); 45436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 45536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case AEABI_UNWIND_CPP_PR1: 45636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case AEABI_UNWIND_CPP_PR2: 45736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned AdditionalWords = (Word & 0x00ff0000) >> 16; 45836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines PrintOpcodes(Contents->data() + TableEntryOffset, 2 + 4 * AdditionalWords, 45936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 2); 46036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 46136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 46236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else { 46336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SW.printString("Model", StringRef("Generic")); 46436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 46536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t Address = PREL31(Word, EHT->sh_addr); 46636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SW.printHex("PersonalityRoutineAddress", Address); 46736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (ErrorOr<StringRef> Name = FunctionAtAddress(EHT->sh_link, Address)) 46836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SW.printString("PersonalityRoutineName", *Name); 46936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 47036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 47136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 47236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinestemplate <typename ET> 47336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid PrinterContext<ET>::PrintOpcodes(const uint8_t *Entry, 47436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines size_t Length, off_t Offset) const { 47536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ListScope OCC(SW, "Opcodes"); 47636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OpcodeDecoder(OCC.W).Decode(Entry, Offset, Length); 47736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 47836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 47936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinestemplate <typename ET> 48036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid PrinterContext<ET>::PrintIndexTable(unsigned SectionIndex, 48136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const Elf_Shdr *IT) const { 48236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ErrorOr<ArrayRef<uint8_t> > Contents = ELF->getSectionContents(IT); 48336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!Contents) 48436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return; 48536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 48636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// ARM EHABI Section 5 - Index Table Entries 48736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// * The first word contains a PREL31 offset to the start of a function with 48836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// bit 31 clear 48936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// * The second word contains one of: 49036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// - The PREL31 offset of the start of the table entry for the function, 49136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// with bit 31 clear 49236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// - The exception-handling table entry itself with bit 31 set 49336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// - The special bit pattern EXIDX_CANTUNWIND, indicating that associated 49436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// frames cannot be unwound 49536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 49636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const support::ulittle32_t *Data = 49736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines reinterpret_cast<const support::ulittle32_t *>(Contents->data()); 49836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const unsigned Entries = IT->sh_size / IndexTableEntrySize; 49936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 50036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ListScope E(SW, "Entries"); 50136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (unsigned Entry = 0; Entry < Entries; ++Entry) { 50236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DictScope E(SW, "Entry"); 50336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 50436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const support::ulittle32_t Word0 = 50536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Data[Entry * (IndexTableEntrySize / sizeof(*Data)) + 0]; 50636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const support::ulittle32_t Word1 = 50736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Data[Entry * (IndexTableEntrySize / sizeof(*Data)) + 1]; 50836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 50936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Word0 & 0x80000000) { 51036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines errs() << "corrupt unwind data in section " << SectionIndex << "\n"; 51136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines continue; 51236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 51336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 51436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const uint64_t Offset = PREL31(Word0, IT->sh_addr); 51536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SW.printHex("FunctionAddress", Offset); 51636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (ErrorOr<StringRef> Name = FunctionAtAddress(IT->sh_link, Offset)) 51736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SW.printString("FunctionName", *Name); 51836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 51936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Word1 == EXIDX_CANTUNWIND) { 52036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SW.printString("Model", StringRef("CantUnwind")); 52136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines continue; 52236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 52336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 52436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Word1 & 0x80000000) { 52536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SW.printString("Model", StringRef("Compact (Inline)")); 52636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 52736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned PersonalityIndex = (Word1 & 0x0f000000) >> 24; 52836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SW.printNumber("PersonalityIndex", PersonalityIndex); 52936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 53036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines PrintOpcodes(Contents->data() + Entry * IndexTableEntrySize + 4, 3, 1); 53136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else { 53236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const Elf_Shdr *EHT = 53336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines FindExceptionTable(SectionIndex, Entry * IndexTableEntrySize + 4); 53436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 53536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (ErrorOr<StringRef> Name = ELF->getSectionName(EHT)) 53636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SW.printString("ExceptionHandlingTable", *Name); 53736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 53836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t TableEntryOffset = PREL31(Word1, IT->sh_addr); 53936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SW.printHex("TableEntryOffset", TableEntryOffset); 54036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 54136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines PrintExceptionTable(IT, EHT, TableEntryOffset); 54236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 54336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 54436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 54536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 54636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinestemplate <typename ET> 54736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid PrinterContext<ET>::PrintUnwindInformation() const { 54836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DictScope UI(SW, "UnwindInformation"); 54936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 55036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines int SectionIndex = 0; 551f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar for (const Elf_Shdr &Sec : ELF->sections()) { 552f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (Sec.sh_type == ELF::SHT_ARM_EXIDX) { 55336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DictScope UIT(SW, "UnwindIndexTable"); 55436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 55536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SW.printNumber("SectionIndex", SectionIndex); 556f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (ErrorOr<StringRef> SectionName = ELF->getSectionName(&Sec)) 55736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SW.printString("SectionName", *SectionName); 558f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar SW.printHex("SectionOffset", Sec.sh_offset); 55936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 560f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar PrintIndexTable(SectionIndex, &Sec); 56136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 562f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar ++SectionIndex; 56336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 56436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 56536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 56636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 56736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 56836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 56936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#endif 57036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 571