5
const ELF_MAGIC = 0x464C457F;
7
let types = DataView.prototype;
8
let U8 = { size: 1, get: types.getUint8, set: types.setUint8, };
9
let U16 = { size: 2, get: types.getUint16, set: types.setUint16, };
10
let U32 = { size: 4, get: types.getUint32, set: types.setUint32, };
11
let pad = function(size)
19
let Header = create_struct([
46
console.assert(Header.reduce((a, entry) => a + entry.size, 0) === 52);
48
let ProgramHeader = create_struct([
58
console.assert(ProgramHeader.reduce((a, entry) => a + entry.size, 0) === 32);
60
let SectionHeader = create_struct([
72
console.assert(SectionHeader.reduce((a, entry) => a + entry.size, 0) === 40);
76
function create_struct(struct)
78
return struct.map(function(entry)
80
let keys = Object.keys(entry);
81
console.assert(keys.length === 1);
83
let type = entry[name];
85
console.assert(type.size > 0);
98
function read_elf(buffer)
100
let view = new DataView(buffer);
102
let [header, offset] = read_struct(view, Header);
103
console.assert(offset === 52);
107
for(let key of Object.keys(header))
109
dbg_log(key + ": 0x" + header[key].toString(16));
114
console.assert(header.magic === ELF_MAGIC, "Bad magic");
115
console.assert(header.class === 1, "Unimplemented: 64 bit elf");
116
console.assert(header.data === 1, "Unimplemented: big endian");
117
console.assert(header.version0 === 1, "Bad version0");
121
console.assert(header.type === 2, "Unimplemented type");
123
console.assert(header.version1 === 1, "Bad version1");
126
console.assert(header.ehsize === 52, "Bad header size");
127
console.assert(header.phentsize === 32, "Bad program header size");
128
console.assert(header.shentsize === 40, "Bad section header size");
130
let [program_headers, ph_offset] = read_structs(
131
view_slice(view, header.phoff, header.phentsize * header.phnum),
135
let [sections_headers, sh_offset] = read_structs(
136
view_slice(view, header.shoff, header.shentsize * header.shnum),
140
if(DEBUG && LOG_LEVEL)
142
console.log("%d program headers:", program_headers.length);
143
for(let program of program_headers)
146
"type=%s offset=%s vaddr=%s paddr=%s " +
147
"filesz=%s memsz=%s flags=%s align=%s",
148
program.type.toString(16),
149
program.offset.toString(16),
150
program.vaddr.toString(16),
151
program.paddr.toString(16),
152
program.filesz.toString(16),
153
program.memsz.toString(16),
154
program.flags.toString(16),
155
program.align.toString(16)
159
console.log("%d program headers:", sections_headers.length);
160
for(let section of sections_headers)
163
"name=%s type=%s flags=%s addr=%s offset=%s " +
164
"size=%s link=%s info=%s addralign=%s entsize=%s",
165
section.name.toString(16),
166
section.type.toString(16),
167
section.flags.toString(16),
168
section.addr.toString(16),
169
section.offset.toString(16),
170
section.size.toString(16),
171
section.link.toString(16),
172
section.info.toString(16),
173
section.addralign.toString(16),
174
section.entsize.toString(16)
186
function read_struct(view, Struct)
190
const LITTLE_ENDIAN = true;
192
for(let entry of Struct)
194
let value = entry.get.call(view, offset, LITTLE_ENDIAN);
195
console.assert(result[entry.name] === undefined);
196
result[entry.name] = value;
197
offset += entry.size;
200
return [result, offset];
203
function read_structs(view, Struct, count)
208
for(var i = 0; i < count; i++)
210
let [s, size] = read_struct(view_slice(view, offset), Struct);
215
return [result, offset];
219
function view_slice(view, offset, length)
221
return new DataView(view.buffer, view.byteOffset + offset, length);