elflib
Version:
ELF file reader and writer
86 lines (85 loc) • 3.97 kB
JavaScript
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;
}
}