UNPKG

elflib

Version:
86 lines (85 loc) 3.97 kB
import assert from 'assert'; import * as Enums from './enums.js'; import { Structs } from './structs.js'; import { getString } from '../sections.js'; /** A symbol, parsed from a symbol table. */ export class Symbol extends Structs.Symbol { constructor(symbolSection) { super(); this.symSection = symbolSection; } /** The section index of the symbol section this symbol is from */ symSection; /** Get the symbol's name. */ getName(elf) { let symSection = elf.sections[this.symSection]; let strSection = elf.sections[symSection.link]; return getString(strSection.strings, this.nameOffset) || ''; } /** The calculated virtual address for the symbol, if possible. */ virtualAddress; /** The data for the symbol, if any and only if it was specified to be loaded. */ data; /** The binding type of this symbol */ get binding() { return this._info >> 4; } /** The type of this symbol */ get type() { return this._info & 0xF; } /** The visibility of the symbol. */ get visibility() { return this._other & 0x3; } ; /** Offset from the start of the {@link Section.link linked string table section} of * this symbol's section, to the address of this symbol's name in said table, if any. */ get nameOffset() { return this._nameOffset; } /** The value of this symbol. The interpretation of the value is dependent on a few things but is generally an offset or address. */ get value() { return this._value; } /** The size of this symbol, if applicable. */ get size() { return this._size; } /** Symbol type specific information. */ get info() { return this._info; } /** Other symbol information. */ get other() { return this._other; } /** Section index for this symbol. * @summary This is the index of the section for this symbol. There * are also special values such as 0xFFF1 for an absolute index symbol * in a relocatable ELF file (object file). */ get shndx() { return this._shndx; } set binding(binding) { this._info = (binding << 4) + (this._info & 0xF); } set type(type) { assert(type in Enums.SymbolType, `${type} is not a valid ELF.SymbolType value.`); this._info = (0x2C >> 4 << 4) + type; } set visibility(visibility) { assert(visibility in Enums.SymbolVisibility, `${visibility} is not a valid ELF.SymbolVisibility value.`); this._other = (this._other >> 4 << 4) + visibility; } ; set nameOffset(nameOffset) { assert(nameOffset >= 0x00 && 0xFFFFFFFF >= nameOffset, `${nameOffset} does not fit inside a uint32.`); this._nameOffset = nameOffset; } set value(value) { assert(value >= 0x00 && 0xFFFFFFFF >= value, `${value} does not fit inside a uint32.`); this._value = value; } set size(size) { assert(size >= 0x00 && 0xFFFFFFFF >= size, `${size} does not fit inside a uint32.`); this._size = size; } set info(info) { if (typeof info === 'object') info = (info.binding << 4) + info.type; assert(info >= 0x00 && 0xFF >= info, `${info} does not fit inside a uint8.`); let [bind, type] = info.toString(16).padStart(2, '0').split(''); assert(bind in Enums.SymbolBinding, `${bind} (From ${info} >> 4) is not a valid ELF.SymbolBinding value.`); assert(type in Enums.SymbolType, `${type} (From ${info} & 0xF) is not a valid ELF.SymbolType value.`); this._info = info; } set other(other) { assert(other >= 0x00 && 0xFF >= other, `${other} does not fit inside a uint8.`); assert((other & 0x3) in Enums.SymbolVisibility, `${other & 0x3} (From ${other} & 0x3) is not a valid ELF.SymbolVisibility value.`); this._other = other; } set shndx(shndx) { assert(shndx >= 0x00 && 0xFFFF >= shndx, `${shndx} does not fit inside a uint16.`); this._shndx = shndx; } }