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