// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// ignore_for_file: constant_identifier_names

import 'dart:typed_data';

import 'reader.dart';

int _readElfBytes(Reader reader, int bytes, int alignment) {
  final alignOffset = reader.offset % alignment;
  if (alignOffset != 0) {
    // Move the reader to the next aligned position.
    reader.seek(reader.offset - alignOffset + alignment);
  }
  return reader.readBytes(bytes);
}

// Reads an Elf{32,64}_Addr.
int _readElfAddress(Reader reader) =>
    _readElfBytes(reader, reader.wordSize, reader.wordSize);

// Reads an Elf{32,64}_Off.
int _readElfOffset(Reader reader) =>
    _readElfBytes(reader, reader.wordSize, reader.wordSize);

// Reads an Elf{32,64}_Half.
int _readElfHalf(Reader reader) => _readElfBytes(reader, 2, 2);

// Reads an Elf{32,64}_Word.
int _readElfWord(Reader reader) => _readElfBytes(reader, 4, 4);

// Reads an Elf64_Xword.
int _readElfXword(Reader reader) {
  switch (reader.wordSize) {
    case 4:
      throw 'Internal reader error: reading Elf64_Xword in 32-bit ELF file';
    case 8:
      return _readElfBytes(reader, 8, 8);
    default:
      throw 'Unsupported word size ${reader.wordSize}';
  }
}

// Reads an Elf{32,64}_Section.
int _readElfSection(Reader reader) => _readElfBytes(reader, 2, 2);

// Used in cases where the value read for a given field is Elf32_Word on 32-bit
// and Elf64_Xword on 64-bit.
int _readElfNative(Reader reader) {
  switch (reader.wordSize) {
    case 4:
      return _readElfWord(reader);
    case 8:
      return _readElfXword(reader);
    default:
      throw 'Unsupported word size ${reader.wordSize}';
  }
}

/// The header of the ELF file, which includes information necessary to parse
/// the rest of the file.
class ElfHeader {
  final int wordSize;
  final Endian endian;
  final int entry;
  final int flags;
  final int headerSize;
  final int programHeaderOffset;
  final int programHeaderCount;
  final int programHeaderEntrySize;
  final int sectionHeaderOffset;
  final int sectionHeaderCount;
  final int sectionHeaderEntrySize;
  final int sectionHeaderStringsIndex;

  ElfHeader._(
      this.wordSize,
      this.endian,
      this.entry,
      this.flags,
      this.headerSize,
      this.programHeaderOffset,
      this.sectionHeaderOffset,
      this.programHeaderCount,
      this.sectionHeaderCount,
      this.programHeaderEntrySize,
      this.sectionHeaderEntrySize,
      this.sectionHeaderStringsIndex);

  static ElfHeader? fromReader(Reader reader) {
    final fileSize = reader.length;

    for (final sigByte in _ELFMAG.codeUnits) {
      if (reader.readByte() != sigByte) {
        return null;
      }
    }

    int wordSize;
    switch (reader.readByte()) {
      case _ELFCLASS32:
        wordSize = 4;
        break;
      case _ELFCLASS64:
        wordSize = 8;
        break;
      default:
        throw FormatException('Unexpected e_ident[EI_CLASS] value');
    }
    final calculatedHeaderSize = 0x18 + 3 * wordSize + 0x10;

    if (fileSize < calculatedHeaderSize) {
      throw FormatException('ELF file too small for header: '
          'file size $fileSize < '
          'calculated header size $calculatedHeaderSize');
    }

    Endian endian;
    switch (reader.readByte()) {
      case _ELFDATA2LSB:
        endian = Endian.little;
        break;
      case _ELFDATA2MSB:
        endian = Endian.big;
        break;
      default:
        throw FormatException('Unexpected e_indent[EI_DATA] value');
    }

    if (reader.readByte() != 0x01) {
      throw FormatException('Unexpected e_ident[EI_VERSION] value');
    }

    // After this point, we need the reader to be correctly set up re: word
    // size and endianness, since we start reading more than single bytes.
    reader.endian = endian;
    reader.wordSize = wordSize;

    // Skip rest of e_ident/e_type/e_machine, i.e. move to e_version.
    reader.seek(0x14, absolute: true);
    if (_readElfWord(reader) != 0x01) {
      throw FormatException('Unexpected e_version value');
    }

    final entry = _readElfAddress(reader);
    final programHeaderOffset = _readElfOffset(reader);
    final sectionHeaderOffset = _readElfOffset(reader);
    final flags = _readElfWord(reader);
    final headerSize = _readElfHalf(reader);

    final programHeaderEntrySize = _readElfHalf(reader);
    final programHeaderCount = _readElfHalf(reader);
    final programHeaderSize = programHeaderEntrySize * programHeaderCount;

    final sectionHeaderEntrySize = _readElfHalf(reader);
    final sectionHeaderCount = _readElfHalf(reader);
    final sectionHeaderSize = sectionHeaderEntrySize * sectionHeaderCount;

    final sectionHeaderStringsIndex = _readElfHalf(reader);

    if (reader.offset != headerSize) {
      throw FormatException('Only read ${reader.offset} bytes, not the '
          'full header size $headerSize');
    }

    if (headerSize != calculatedHeaderSize) {
      throw FormatException('Stored ELF header size $headerSize != '
          'calculated ELF header size $calculatedHeaderSize');
    }
    if (fileSize < programHeaderOffset) {
      throw FormatException('File is truncated before program header');
    }
    if (fileSize < programHeaderOffset + programHeaderSize) {
      throw FormatException('File is truncated within the program header');
    }
    if (fileSize < sectionHeaderOffset) {
      throw FormatException('File is truncated before section header');
    }
    if (fileSize < sectionHeaderOffset + sectionHeaderSize) {
      throw FormatException('File is truncated within the section header');
    }

    return ElfHeader._(
        wordSize,
        endian,
        entry,
        flags,
        headerSize,
        programHeaderOffset,
        sectionHeaderOffset,
        programHeaderCount,
        sectionHeaderCount,
        programHeaderEntrySize,
        sectionHeaderEntrySize,
        sectionHeaderStringsIndex);
  }

  int get programHeaderSize => programHeaderCount * programHeaderEntrySize;
  int get sectionHeaderSize => sectionHeaderCount * sectionHeaderEntrySize;

  // Constants used within the ELF specification.
  static const _ELFMAG = '\x7fELF';
  static const _ELFCLASS32 = 0x01;
  static const _ELFCLASS64 = 0x02;
  static const _ELFDATA2LSB = 0x01;
  static const _ELFDATA2MSB = 0x02;

  void writeToStringBuffer(StringBuffer buffer) {
    buffer
      ..write('Format is ')
      ..write(wordSize * 8)
      ..write(' bits');
    switch (endian) {
      case Endian.little:
        buffer.writeln(' and little-endian');
        break;
      case Endian.big:
        buffer.writeln(' and big-endian');
        break;
    }
    buffer
      ..write('Entry point: 0x')
      ..writeln(paddedHex(entry, wordSize))
      ..write('Flags: 0x')
      ..writeln(paddedHex(flags, 4))
      ..write('Program header offset: 0x')
      ..writeln(paddedHex(programHeaderOffset, wordSize))
      ..write('Program header entry size: ')
      ..writeln(programHeaderEntrySize)
      ..write('Program header entry count: ')
      ..writeln(programHeaderCount)
      ..write('Section header offset: 0x')
      ..writeln(paddedHex(sectionHeaderOffset, wordSize))
      ..write('Section header entry size: ')
      ..writeln(sectionHeaderEntrySize)
      ..write('Section header entry count: ')
      ..writeln(sectionHeaderCount)
      ..write('Section header strings index: ')
      ..write(sectionHeaderStringsIndex);
  }

  @override
  String toString() {
    var buffer = StringBuffer();
    writeToStringBuffer(buffer);
    return buffer.toString();
  }
}

/// An entry in the [ProgramHeader] describing a memory segment loaded into
/// memory and used during runtime.
class ProgramHeaderEntry {
  final int type;
  final int flags;
  final int offset;
  final int vaddr;
  final int paddr;
  final int filesz;
  final int memsz;
  final int align;
  final int wordSize;

  // p_type constants from ELF specification.
  static const _PT_NULL = 0;
  static const _PT_LOAD = 1;
  static const _PT_DYNAMIC = 2;
  static const _PT_PHDR = 6;

  ProgramHeaderEntry._(this.type, this.flags, this.offset, this.vaddr,
      this.paddr, this.filesz, this.memsz, this.align, this.wordSize);

  static ProgramHeaderEntry fromReader(Reader reader) {
    var wordSize = reader.wordSize;
    assert(wordSize == 4 || wordSize == 8);
    final type = _readElfWord(reader);
    late int flags;
    if (wordSize == 8) {
      flags = _readElfWord(reader);
    }
    final offset = _readElfOffset(reader);
    final vaddr = _readElfAddress(reader);
    final paddr = _readElfAddress(reader);
    final filesz = _readElfNative(reader);
    final memsz = _readElfNative(reader);
    if (wordSize == 4) {
      flags = _readElfWord(reader);
    }
    final align = _readElfNative(reader);
    return ProgramHeaderEntry._(
        type, flags, offset, vaddr, paddr, filesz, memsz, align, wordSize);
  }

  static const _typeStrings = <int, String>{
    _PT_NULL: 'PT_NULL',
    _PT_LOAD: 'PT_LOAD',
    _PT_DYNAMIC: 'PT_DYNAMIC',
    _PT_PHDR: 'PT_PHDR',
  };

  static String _typeToString(int type) =>
      _typeStrings[type] ?? 'unknown (${paddedHex(type, 4)})';

  void writeToStringBuffer(StringBuffer buffer) {
    buffer
      ..write('Type: ')
      ..writeln(_typeToString(type))
      ..write('Flags: 0x')
      ..writeln(paddedHex(flags, 4))
      ..write('Offset: 0x')
      ..writeln(paddedHex(offset, wordSize))
      ..write('Virtual address: 0x')
      ..writeln(paddedHex(vaddr, wordSize))
      ..write('Physical address: 0x')
      ..writeln(paddedHex(paddr, wordSize))
      ..write('Size in file: ')
      ..writeln(filesz)
      ..write('Size in memory: ')
      ..writeln(memsz)
      ..write('Alignment: 0x')
      ..write(paddedHex(align, wordSize));
  }

  @override
  String toString() {
    final buffer = StringBuffer();
    writeToStringBuffer(buffer);
    return buffer.toString();
  }
}

/// A list of [ProgramHeaderEntry]s describing the memory segments loaded at
/// runtime when this file is used.
class ProgramHeader {
  final List<ProgramHeaderEntry> _entries;

  ProgramHeader._(this._entries);

  int get length => _entries.length;
  ProgramHeaderEntry operator [](int index) => _entries[index];

  ProgramHeaderEntry? loadSegmentFor(int address) {
    for (final entry in _entries) {
      if (entry.vaddr <= address && address <= entry.vaddr + entry.memsz) {
        return entry;
      }
    }
    return null;
  }

  static ProgramHeader fromReader(Reader reader, ElfHeader header) {
    final programReader = reader.refocusedCopy(
        header.programHeaderOffset, header.programHeaderSize);
    final entries =
        programReader.readRepeated(ProgramHeaderEntry.fromReader).toList();
    return ProgramHeader._(entries);
  }

  void writeToStringBuffer(StringBuffer buffer) {
    for (var i = 0; i < length; i++) {
      if (i != 0) {
        buffer
          ..writeln()
          ..writeln();
      }
      buffer
        ..write('Entry ')
        ..write(i)
        ..writeln(':');
      _entries[i].writeToStringBuffer(buffer);
    }
  }

  @override
  String toString() {
    final buffer = StringBuffer();
    writeToStringBuffer(buffer);
    return buffer.toString();
  }
}

/// An entry in the [SectionHeader] that describes a single [Section].
class SectionHeaderEntry {
  final int nameIndex;
  final int type;
  final int flags;
  final int addr;
  final int offset;
  final int size;
  final int link;
  final int info;
  final int addrAlign;
  final int entrySize;
  final int wordSize;
  late String name;

  SectionHeaderEntry._(
      this.nameIndex,
      this.type,
      this.flags,
      this.addr,
      this.offset,
      this.size,
      this.link,
      this.info,
      this.addrAlign,
      this.entrySize,
      this.wordSize);

  static SectionHeaderEntry fromReader(Reader reader) {
    final nameIndex = _readElfWord(reader);
    final type = _readElfWord(reader);
    final flags = _readElfNative(reader);
    final addr = _readElfAddress(reader);
    final offset = _readElfOffset(reader);
    final size = _readElfNative(reader);
    final link = _readElfWord(reader);
    final info = _readElfWord(reader);
    final addrAlign = _readElfNative(reader);
    final entrySize = _readElfNative(reader);
    return SectionHeaderEntry._(nameIndex, type, flags, addr, offset, size,
        link, info, addrAlign, entrySize, reader.wordSize);
  }

  // sh_type constants from ELF specification.
  static const _SHT_NULL = 0;
  static const _SHT_PROGBITS = 1;
  static const _SHT_SYMTAB = 2;
  static const _SHT_STRTAB = 3;
  static const _SHT_HASH = 5;
  static const _SHT_DYNAMIC = 6;
  static const _SHT_NOTE = 7;
  static const _SHT_NOBITS = 8;
  static const _SHT_DYNSYM = 11;

  // sh_flags constants from ELF specification.
  static const _SHF_WRITE = 0x1;
  static const _SHF_ALLOC = 0x2;
  static const _SHF_EXECINSTR = 0x4;

  bool get isWritable => flags & _SHF_WRITE != 0;
  bool get isAllocated => flags & _SHF_ALLOC != 0;
  bool get isExecutable => flags & _SHF_EXECINSTR != 0;

  bool get hasBits => type != _SHT_NOBITS;

  void setName(StringTable nameTable) {
    name = nameTable[nameIndex]!;
  }

  static const _typeStrings = <int, String>{
    _SHT_NULL: 'SHT_NULL',
    _SHT_PROGBITS: 'SHT_PROGBITS',
    _SHT_SYMTAB: 'SHT_SYMTAB',
    _SHT_STRTAB: 'SHT_STRTAB',
    _SHT_HASH: 'SHT_HASH',
    _SHT_DYNAMIC: 'SHT_DYNAMIC',
    _SHT_NOTE: 'SHT_NOTE',
    _SHT_NOBITS: 'SHT_NOBITS',
    _SHT_DYNSYM: 'SHT_DYNSYM',
  };

  static String _typeToString(int type) =>
      _typeStrings[type] ?? 'unknown (${paddedHex(type, 4)})';

  void writeToStringBuffer(StringBuffer buffer) {
    buffer.write('Name: ');
    buffer
      ..write('"')
      ..write(name)
      ..write('" (@ ')
      ..write(nameIndex)
      ..writeln(')');
    buffer
      ..write('Type: ')
      ..writeln(_typeToString(type))
      ..write('Flags: 0x')
      ..writeln(paddedHex(flags, wordSize))
      ..write('Address: 0x')
      ..writeln(paddedHex(addr, wordSize))
      ..write('Offset: 0x')
      ..writeln(paddedHex(offset, wordSize))
      ..write('Size: ')
      ..writeln(size)
      ..write('Link: ')
      ..writeln(link)
      ..write('Info: 0x')
      ..writeln(paddedHex(info, 4))
      ..write('Address alignment: 0x')
      ..writeln(paddedHex(addrAlign, wordSize))
      ..write('Entry size: ')
      ..write(entrySize);
  }

  @override
  String toString() {
    final buffer = StringBuffer();
    writeToStringBuffer(buffer);
    return buffer.toString();
  }
}

/// A list of [SectionHeaderEntry]s describing the [Section]s in the ELF file.
class SectionHeader {
  final List<SectionHeaderEntry> entries;

  SectionHeader._(this.entries);

  static SectionHeader fromReader(Reader reader, ElfHeader header) {
    final headerReader = reader.refocusedCopy(
        header.sectionHeaderOffset, header.sectionHeaderSize);
    final entries =
        headerReader.readRepeated(SectionHeaderEntry.fromReader).toList();
    final nameTableEntry = entries[header.sectionHeaderStringsIndex];
    assert(nameTableEntry.type == SectionHeaderEntry._SHT_STRTAB);
    return SectionHeader._(entries);
  }

  void writeToStringBuffer(StringBuffer buffer) {
    for (var i = 0; i < entries.length; i++) {
      if (i != 0) {
        buffer
          ..writeln()
          ..writeln();
      }
      buffer
        ..write('Entry ')
        ..write(i)
        ..writeln(':');
      entries[i].writeToStringBuffer(buffer);
    }
  }

  @override
  String toString() {
    final buffer = StringBuffer();
    writeToStringBuffer(buffer);
    return buffer.toString();
  }
}

/// A section in an ELF file.
///
/// Some sections correspond to segments from the [ProgramHeader] and contain
/// the information that will be loaded into memory for that segment, whereas
/// others include information, like debugging sections, that are not loaded
/// at runtime.
///
/// Only some sections are currently parsed by the  ELF reader; most are left
/// unparsed as they are not needed for DWARF address translation.
class Section {
  final SectionHeaderEntry headerEntry;

  Section._(this.headerEntry);

  static Section fromReader(Reader reader, SectionHeaderEntry entry) {
    switch (entry.type) {
      case SectionHeaderEntry._SHT_STRTAB:
        return StringTable.fromReader(reader, entry);
      case SectionHeaderEntry._SHT_SYMTAB:
        return SymbolTable.fromReader(reader, entry);
      case SectionHeaderEntry._SHT_DYNSYM:
        return SymbolTable.fromReader(reader, entry);
      case SectionHeaderEntry._SHT_NOTE:
        return Note.fromReader(reader, entry);
      case SectionHeaderEntry._SHT_DYNAMIC:
        return DynamicTable.fromReader(reader, entry);
      default:
        return Section._(entry);
    }
  }

  int get offset => headerEntry.offset;
  int get virtualAddress => headerEntry.addr;
  int get length => headerEntry.size;

  // Convenience function for preparing a reader to read a particular section.
  Reader refocusedCopy(Reader reader) => reader.refocusedCopy(offset, length);

  void writeToStringBuffer(StringBuffer buffer) {
    buffer
      ..write('Section "')
      ..write(headerEntry.name)
      ..write('" is unparsed and ')
      ..write(length)
      ..writeln(' bytes long.');
  }

  @override
  String toString() {
    final buffer = StringBuffer();
    writeToStringBuffer(buffer);
    return buffer.toString();
  }
}

/// A section that contains a single note.
class Note extends Section {
  final int type;
  final String name;
  final Uint8List description;

  Note._(entry, this.type, this.name, this.description) : super._(entry);

  static Note fromReader(Reader originalReader, SectionHeaderEntry entry) {
    final reader = originalReader.refocusedCopy(entry.offset, entry.size);
    final nameLength = reader.readBytes(4);
    final descriptionLength = reader.readBytes(4);
    final type = reader.readBytes(4);
    final nameEnd = reader.offset + nameLength;
    final name = reader.readNullTerminatedString();
    assert(reader.offset == nameEnd);
    assert(reader.length - reader.offset == descriptionLength);
    final descriptionStart = reader.offset;
    final descriptionEnd = descriptionStart + descriptionLength;
    final description =
        Uint8List.sublistView(reader.bdata, descriptionStart, descriptionEnd);
    return Note._(entry, type, name, description);
  }

  @override
  void writeToStringBuffer(StringBuffer buffer) {
    buffer
      ..write('Section "')
      ..write(headerEntry.name)
      ..writeln('" is a note:');
    buffer
      ..write('  Type: ')
      ..writeln(type);
    buffer
      ..write('  Name: "')
      ..write(name)
      ..writeln('"');
    buffer
      ..write('  Description: ')
      ..writeln(description);
  }

  @override
  String toString() {
    final buffer = StringBuffer();
    writeToStringBuffer(buffer);
    return buffer.toString();
  }
}

/// A map from table offsets to strings, used to store names of ELF objects.
class StringTable extends Section {
  final Map<int, String> _entries;

  StringTable._(entry, this._entries) : super._(entry);

  static StringTable fromReader(Reader reader, SectionHeaderEntry entry) {
    final sectionReader = reader.refocusedCopy(entry.offset, entry.size);
    final entries = Map.fromEntries(sectionReader
        .readRepeatedWithOffsets((r) => r.readNullTerminatedString()));
    return StringTable._(entry, entries);
  }

  String? operator [](int index) => _entries[index];
  bool containsKey(int index) => _entries.containsKey(index);

  @override
  void writeToStringBuffer(StringBuffer buffer) {
    buffer
      ..write('Section "')
      ..write(headerEntry.name)
      ..writeln('" is a string table:');
    for (var key in _entries.keys) {
      buffer
        ..write('  ')
        ..write(key)
        ..write(' => ')
        ..writeln(_entries[key]);
    }
  }
}

enum SymbolBinding {
  STB_LOCAL,
  STB_GLOBAL,
}

enum SymbolType {
  STT_NOTYPE,
  STT_OBJECT,
  STT_FUNC,
}

enum SymbolVisibility {
  STV_DEFAULT,
  STV_INTERNAL,
  STV_HIDDEN,
  STV_PROTECTED,
}

/// A symbol in an ELF file, which names a portion of the virtual address space.
class Symbol {
  final int nameIndex;
  final int info;
  final int other;
  final int sectionIndex;
  final int value;
  final int size;
  final int _wordSize;
  late String name;

  Symbol._(this.nameIndex, this.info, this.other, this.sectionIndex, this.value,
      this.size, this._wordSize);

  static Symbol fromReader(Reader reader) {
    final wordSize = reader.wordSize;
    final nameIndex = _readElfWord(reader);
    late int info;
    late int other;
    late int sectionIndex;
    if (wordSize == 8) {
      info = reader.readByte();
      other = reader.readByte();
      sectionIndex = _readElfSection(reader);
    }
    final value = _readElfAddress(reader);
    final size = _readElfNative(reader);
    if (wordSize == 4) {
      info = reader.readByte();
      other = reader.readByte();
      sectionIndex = _readElfSection(reader);
    }
    return Symbol._(
        nameIndex, info, other, sectionIndex, value, size, wordSize);
  }

  void _cacheNameFromStringTable(StringTable table) {
    final nameFromTable = table[nameIndex];
    if (nameFromTable == null) {
      throw FormatException('Index $nameIndex not found in string table');
    }
    name = nameFromTable;
  }

  SymbolBinding get bind => SymbolBinding.values[info >> 4];
  SymbolType get type => SymbolType.values[info & 0x0f];
  SymbolVisibility get visibility => SymbolVisibility.values[other & 0x03];

  void writeToStringBuffer(StringBuffer buffer) {
    buffer
      ..write('"')
      ..write(name)
      ..write('" =>');
    switch (bind) {
      case SymbolBinding.STB_GLOBAL:
        buffer.write(' a global');
        break;
      case SymbolBinding.STB_LOCAL:
        buffer.write(' a local');
        break;
    }
    switch (visibility) {
      case SymbolVisibility.STV_DEFAULT:
        break;
      case SymbolVisibility.STV_HIDDEN:
        buffer.write(' hidden');
        break;
      case SymbolVisibility.STV_INTERNAL:
        buffer.write(' internal');
        break;
      case SymbolVisibility.STV_PROTECTED:
        buffer.write(' protected');
        break;
    }
    buffer
      ..write(' symbol that points to ')
      ..write(size)
      ..write(' bytes at location 0x')
      ..write(paddedHex(value, _wordSize))
      ..write(' in section ')
      ..write(sectionIndex);
  }

  @override
  String toString() {
    final buffer = StringBuffer();
    writeToStringBuffer(buffer);
    return buffer.toString();
  }
}

/// A table of (static or dynamic) [Symbol]s.
class SymbolTable extends Section {
  final List<Symbol> _entries;
  final Map<String, Symbol> _nameCache;

  SymbolTable._(SectionHeaderEntry entry, this._entries)
      : _nameCache = {},
        super._(entry);

  static SymbolTable fromReader(Reader reader, SectionHeaderEntry entry) {
    final sectionReader = reader.refocusedCopy(entry.offset, entry.size);
    final entries = sectionReader.readRepeated(Symbol.fromReader).toList();
    return SymbolTable._(entry, entries);
  }

  void _cacheNames(StringTable stringTable) {
    _nameCache.clear();
    for (final symbol in _entries) {
      symbol._cacheNameFromStringTable(stringTable);
      _nameCache[symbol.name] = symbol;
    }
  }

  Iterable<String> get keys => _nameCache.keys;
  Iterable<Symbol> get values => _entries;
  Symbol? operator [](String name) => _nameCache[name];
  bool containsKey(String name) => _nameCache.containsKey(name);

  @override
  void writeToStringBuffer(StringBuffer buffer) {
    buffer
      ..write('Section "')
      ..write(headerEntry.name)
      ..writeln('" is a symbol table:');
    for (var symbol in _entries) {
      buffer.write(' ');
      symbol.writeToStringBuffer(buffer);
      buffer.writeln();
    }
  }
}

/// Represents d_tag constants from ELF specification.
enum DynamicTableTag {
  DT_NULL,
  DT_NEEDED,
  DT_PLTRELSZ,
  DT_PLTGOT,
  DT_HASH,
  DT_STRTAB,
  DT_SYMTAB,
  DT_RELA,
  DT_RELASZ,
  DT_RELAENT,
  DT_STRSZ,
  DT_SYMENT,
  // Later d_tag values are not currently used in Dart ELF files.
}

/// The dynamic table, which contains entries pointing to various relocated
/// addresses.
class DynamicTable extends Section {
  // We don't use DynamicTableTag for the key so that we can handle ELF files
  // that may use unknown (to us) tags.
  final Map<int, int> _entries;
  final int _wordSize;

  DynamicTable._(SectionHeaderEntry entry, this._entries, this._wordSize)
      : super._(entry);

  static DynamicTable fromReader(Reader reader, SectionHeaderEntry entry) {
    final sectionReader = reader.refocusedCopy(entry.offset, entry.size);
    final entries = <int, int>{};
    while (true) {
      // Each entry is a tag and a value, both native word sized.
      final tag = _readElfNative(sectionReader);
      final value = _readElfNative(sectionReader);
      // A DT_NULL entry signfies the end of entries.
      if (tag == DynamicTableTag.DT_NULL.index) break;
      entries[tag] = value;
    }
    return DynamicTable._(entry, entries, sectionReader.wordSize);
  }

  int? operator [](DynamicTableTag tag) => _entries[tag.index];
  bool containsKey(DynamicTableTag tag) => _entries.containsKey(tag.index);

  // To avoid depending on EnumName.name from 2.15.
  static const _tagStrings = {
    DynamicTableTag.DT_NULL: 'DT_NULL',
    DynamicTableTag.DT_NEEDED: 'DT_NEEDED',
    DynamicTableTag.DT_PLTRELSZ: 'DT_PLTRELSZ',
    DynamicTableTag.DT_PLTGOT: 'DT_PLTGOT',
    DynamicTableTag.DT_HASH: 'DT_HASH',
    DynamicTableTag.DT_STRTAB: 'DT_STRTAB',
    DynamicTableTag.DT_SYMTAB: 'DT_SYMTAB',
    DynamicTableTag.DT_RELA: 'DT_RELA',
    DynamicTableTag.DT_RELASZ: 'DT_RELASZ',
    DynamicTableTag.DT_STRSZ: 'DT_STRSZ',
    DynamicTableTag.DT_SYMENT: 'DT_SYMENT',
  };
  static final _maxTagStringLength = (_tagStrings.values.toList()
        ..sort((s1, s2) => s2.length - s1.length))
      .first
      .length;

  @override
  void writeToStringBuffer(StringBuffer buffer) {
    buffer
      ..write('Section "')
      ..write(headerEntry.name)
      ..writeln('" is a dynamic table:');
    for (var kv in _entries.entries) {
      buffer.write(' ');
      if (kv.key < DynamicTableTag.values.length) {
        final tag = DynamicTableTag.values[kv.key];
        buffer
          ..write(_tagStrings[tag]?.padRight(_maxTagStringLength))
          ..write(' => ');
        switch (tag) {
          // These are relocated addresses.
          case DynamicTableTag.DT_HASH:
          case DynamicTableTag.DT_PLTGOT:
          case DynamicTableTag.DT_SYMTAB:
          case DynamicTableTag.DT_STRTAB:
          case DynamicTableTag.DT_RELA:
            buffer
              ..write('0x')
              ..writeln(paddedHex(kv.value, _wordSize));
            break;
          // Other entries are just values or offsets.
          default:
            buffer.writeln(kv.value);
        }
      } else {
        buffer
          ..write('Unknown tag ')
          ..write(kv.key)
          ..write(' => ')
          ..writeln(kv.value);
      }
    }
  }
}

/// Information parsed from an Executable and Linking Format (ELF) file.
class Elf {
  final ElfHeader _header;
  final ProgramHeader _programHeader;
  final SectionHeader _sectionHeader;
  final Map<SectionHeaderEntry, Section> _sections;
  final Map<String, Set<Section>> _sectionsByName;

  Elf._(this._header, this._programHeader, this._sectionHeader, this._sections,
      this._sectionsByName);

  /// Creates an [Elf] from [bytes].
  ///
  /// Returns null if the file does not start with the ELF magic number.
  static Elf? fromBuffer(Uint8List bytes) =>
      Elf.fromReader(Reader.fromTypedData(bytes));

  /// Creates an [Elf] from the file at [path].
  ///
  /// Returns null if the file does not start with the ELF magic number.
  static Elf? fromFile(String path) => Elf.fromReader(Reader.fromFile(path));

  Iterable<Section> namedSections(String name) =>
      _sectionsByName[name] ?? <Section>[];

  /// Checks that the contents of a given section have valid addresses when the
  /// file contents for the corresponding segment is loaded into memory.
  ///
  /// Returns false for sections that are not allocated or where the address
  /// does not correspond to file contents (i.e., NOBITS sections).
  bool sectionHasValidSegmentAddresses(Section section) {
    final headerEntry = section.headerEntry;
    if (!headerEntry.isAllocated || !headerEntry.hasBits) return false;
    final segment = _programHeader.loadSegmentFor(headerEntry.addr);
    if (segment == null) return false;
    return (headerEntry.addr < (segment.vaddr + segment.filesz)) &&
        (headerEntry.addr + headerEntry.size) <=
            (segment.vaddr + segment.filesz);
  }

  /// Lookup of a dynamic symbol by name.
  ///
  /// Returns -1 if there is no dynamic symbol that matches [name].
  Symbol? dynamicSymbolFor(String name) {
    for (final section in namedSections('.dynsym')) {
      final dynsym = section as SymbolTable;
      if (dynsym.containsKey(name)) return dynsym[name];
    }
    return null;
  }

  /// Reverse lookup of the static symbol that contains the given virtual
  /// address. Returns null if no static symbol matching the address is found.
  Symbol? staticSymbolAt(int address) {
    for (final section in namedSections('.symtab')) {
      final table = section as SymbolTable;
      for (final symbol in table.values) {
        final start = symbol.value;
        final end = start + symbol.size;
        if (start <= address && address < end) return symbol;
      }
    }
    return null;
  }

  /// Creates an [Elf] from the data pointed to by [reader].
  ///
  /// After succesful completion, the [endian] and [wordSize] fields of the
  /// reader are set to match the values read from the ELF header. The position
  /// of the reader will be unchanged.
  ///
  /// Returns null if the file does not start with the ELF magic number.
  static Elf? fromReader(Reader elfReader) {
    // ELF files contain absolute offsets from the start of the file, so
    // make sure we have a reader that a) makes no assumptions about the
    // endianness or word size, since we'll read those in the header and b)
    // has an internal offset of 0 so absolute offsets can be used directly.
    final reader = Reader.fromTypedData(ByteData.sublistView(
        elfReader.bdata, elfReader.bdata.offsetInBytes + elfReader.offset));
    final header = ElfHeader.fromReader(reader);
    // Only happens if the file didn't start with the expected magic number.
    if (header == null) return null;
    // At this point, the endianness and wordSize should have been set
    // during ElfHeader.fromReader.
    final programHeader = ProgramHeader.fromReader(reader, header);
    final sectionHeader = SectionHeader.fromReader(reader, header);
    final sections = <SectionHeaderEntry, Section>{};
    for (var i = 0; i < sectionHeader.entries.length; i++) {
      final entry = sectionHeader.entries[i];
      sections[entry] = Section.fromReader(reader, entry);
    }
    // Now set up the by-name section table and cache the names in the section
    // header entries.
    if (header.sectionHeaderStringsIndex < 0 ||
        header.sectionHeaderStringsIndex >= sectionHeader.entries.length) {
      throw FormatException('Section header string table index invalid');
    }
    final sectionHeaderStringTableEntry =
        sectionHeader.entries[header.sectionHeaderStringsIndex];
    final sectionHeaderStringTable =
        sections[sectionHeaderStringTableEntry] as StringTable?;
    if (sectionHeaderStringTable == null) {
      throw FormatException(
          'No section for entry $sectionHeaderStringTableEntry');
    }
    final sectionsByName = <String, Set<Section>>{};
    for (final entry in sectionHeader.entries) {
      final section = sections[entry];
      if (section == null) {
        throw FormatException('No section found for entry $entry');
      }
      entry.setName(sectionHeaderStringTable);
      sectionsByName.putIfAbsent(entry.name, () => {}).add(section);
    }
    void _cacheSymbolNames(String stringTableTag, String symbolTableTag) {
      final stringTables = sectionsByName[stringTableTag]?.cast<StringTable>();
      if (stringTables == null) {
        return;
      }
      final stringTableMap =
          Map.fromEntries(stringTables.map((s) => MapEntry(s.headerEntry, s)));
      final symbolTables = sectionsByName[symbolTableTag]?.cast<SymbolTable>();
      if (symbolTables == null) {
        return;
      }
      for (final symbolTable in symbolTables) {
        final link = symbolTable.headerEntry.link;
        final entry = sectionHeader.entries[link];
        final stringTable = stringTableMap[entry];
        if (stringTable == null) {
          throw FormatException(
              'String table not found at section header entry $link');
        }
        symbolTable._cacheNames(stringTable);
      }
    }

    _cacheSymbolNames('.strtab', '.symtab');
    _cacheSymbolNames('.dynstr', '.dynsym');
    // Set the wordSize and endian of the original reader before returning.
    elfReader.wordSize = reader.wordSize;
    elfReader.endian = reader.endian;
    return Elf._(
        header, programHeader, sectionHeader, sections, sectionsByName);
  }

  void writeToStringBuffer(StringBuffer buffer) {
    buffer
      ..writeln('-----------------------------------------------------')
      ..writeln('             ELF header information')
      ..writeln('-----------------------------------------------------')
      ..writeln();
    _header.writeToStringBuffer(buffer);
    buffer
      ..writeln()
      ..writeln()
      ..writeln('-----------------------------------------------------')
      ..writeln('            Program header information')
      ..writeln('-----------------------------------------------------')
      ..writeln();
    _programHeader.writeToStringBuffer(buffer);
    buffer
      ..writeln()
      ..writeln()
      ..writeln('-----------------------------------------------------')
      ..writeln('            Section header information')
      ..writeln('-----------------------------------------------------')
      ..writeln();
    _sectionHeader.writeToStringBuffer(buffer);
    buffer
      ..writeln()
      ..writeln()
      ..writeln('-----------------------------------------------------')
      ..writeln('                 Section information')
      ..writeln('-----------------------------------------------------')
      ..writeln();
    for (final entry in _sectionHeader.entries) {
      _sections[entry]!.writeToStringBuffer(buffer);
      buffer.writeln();
    }
  }

  @override
  String toString() {
    var buffer = StringBuffer();
    writeToStringBuffer(buffer);
    return buffer.toString();
  }
}
