elflib
Version:
ELF file reader and writer
68 lines (67 loc) • 3.45 kB
JavaScript
import assert from 'assert';
import { Structs } from './structs.js';
/** A relocation as found in a relocation section.
* @summary if the section is a REL section, addend will be undefined.
* If the section is a RELA section, addend will be set. */
export class Relocation extends Structs.Relocation {
constructor() { super(); }
/**
* The location at which to apply the relocation action.
* @summary This member gives the location at which to apply the relocation action.
* For a relocatable file, the value is the byte offset from the beginning of the section
* to the storage unit affected by the relocation. For an executable file or a shared object,
* the value is the virtual address of the storage unit affected by the relocation. */
get addr() { return this._addr; }
;
/** The symbol table index with respect to which the
* relocation must be made, and the type of relocation to apply.
* @summary This member gives both the symbol table index with respect to which the
* relocation must be made, and the type of relocation to apply. For example,
* a call instruction's relocation entry would hold the symbol table index of
* the function being called. If the index is STN_UNDEF, the undefined symbol
* index, the relocation uses 0 as the symbol value. Relocation types are
* processor-specific; descriptions of their behavior appear in the processor
* supplement. When the text in the processor supplement refers to a
* relocation entry's relocation type or symbol table index, it means the result
* of applying ELF32_R_TYPE or ELF32_R_SYM, respectively, to the entry's r_info member. */
get info() { return this._info; }
;
/** A constant addend used to compute the value to be stored into the relocatable field. */
get addend() { return this._addend; }
;
/** The symbol index for this relocation.
* @summary The symbol for this relocation is found in the section identified
* by the info field in the section this relocation is found in.
* The symbol index is taken from the info field. */
get symbolIndex() { return this._info >> 8; }
;
/** The type of this relocation.
* @summary Relocation types are processor specific so the raw number is given here.
* The relocation type is take from the info field */
get type() { return this._info & 0xFF; }
;
set addr(addr) {
assert(addr >= 0x00 && 0xFFFFFFFF >= addr, `${addr} does not fit inside a uint32.`);
this._addr = addr;
}
set info(info) {
if (typeof info === 'object')
info = (info.symbolIndex << 8) + info.type;
assert(info >= 0x00 && 0xFFFFFFFF >= info, `${info} does not fit inside a uint32.`);
this._info = info;
}
set addend(addend) {
if (addend === undefined)
return;
assert(addend >= -0x80000000 && 0x7FFFFFFF >= addend, `${addend} does not fit inside a sint32.`);
this._addend = addend;
}
set symbolIndex(symbolIndex) {
assert(symbolIndex >= 0x00 && 0xFFFFFF >= symbolIndex, `${symbolIndex} does not fit inside a 24-bit value.`);
this._info = (symbolIndex << 8) + (this._info & 0xFF);
}
set type(type) {
assert(type >= 0x00 && 0xFF >= type, `${type} does not fit inside a uint8.`);
this._info = (this._info & 0xFFFFFF00) + type;
}
}