@asmlift/core 0.8.1 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +36 -31
- package/package.json +1 -1
- package/src/aggregate.ts +397 -0
- package/src/backend/c.ts +6 -2
- package/src/backend/cfamily.ts +370 -56
- package/src/backend/cpp.ts +116 -10
- package/src/backend/pascal.ts +69 -11
- package/src/cdecl/constant.ts +59 -0
- package/src/cdecl/lex.ts +209 -0
- package/src/cdecl/parse.ts +975 -0
- package/src/cdecl/spell.ts +69 -0
- package/src/codegen-flags.ts +38 -6
- package/src/compiler-diagnostics.ts +194 -0
- package/src/contracts.ts +777 -84
- package/src/declare.ts +132 -13
- package/src/frontend/asmdata.ts +26 -6
- package/src/frontend/call-plan.ts +1590 -0
- package/src/frontend/dead-reads.ts +628 -0
- package/src/frontend/device-pins.ts +296 -0
- package/src/frontend/emit.ts +4 -3
- package/src/frontend/errors.ts +5 -0
- package/src/frontend/flags-edge.ts +101 -0
- package/src/frontend/fpu.ts +374 -0
- package/src/frontend/frame-objects.ts +3171 -0
- package/src/frontend/frontend.ts +64 -3
- package/src/frontend/high-half.ts +55 -5
- package/src/frontend/jump-table.ts +530 -0
- package/src/frontend/local-object.ts +616 -0
- package/src/frontend/mips.ts +2392 -208
- package/src/frontend/opaque.ts +97 -18
- package/src/frontend/own-struct-return.ts +500 -0
- package/src/frontend/ppc.ts +3137 -267
- package/src/frontend/register-struct-call.ts +484 -0
- package/src/frontend/reloc-symbol.ts +109 -13
- package/src/frontend/splat.ts +108 -5
- package/src/frontend/ssa.ts +2098 -89
- package/src/frontend/stackargs.ts +172 -42
- package/src/frontend/thumb.ts +4563 -2091
- package/src/ir/alias.ts +71 -0
- package/src/ir/bits.ts +681 -1
- package/src/ir/core.ts +199 -6
- package/src/ir/discipline.ts +313 -0
- package/src/ir/entry.ts +159 -0
- package/src/ir/float-bits.ts +47 -0
- package/src/{structure → ir}/loops.ts +6 -2
- package/src/ir/opcodes.ts +193 -121
- package/src/ir/parse.ts +1 -0
- package/src/ir/types.ts +202 -2
- package/src/ir/verify.ts +219 -3
- package/src/l3/address.ts +5 -0
- package/src/l3/argcopy.ts +38 -6
- package/src/l3/ast.ts +467 -23
- package/src/l3/basecse.ts +33 -5
- package/src/l3/coalesce.ts +21 -13
- package/src/l3/constinit.ts +382 -0
- package/src/l3/dce.ts +34 -12
- package/src/l3/gates.ts +9 -3
- package/src/l3/hoist.ts +8 -7
- package/src/l3/initfirst.ts +68 -19
- package/src/l3/intcell.ts +98 -0
- package/src/l3/mentions.ts +10 -4
- package/src/l3/narrowdecl.ts +259 -0
- package/src/l3/nearbase.ts +10 -5
- package/src/l3/parkfirst.ts +8 -5
- package/src/l3/pollguard.ts +11 -4
- package/src/l3/ptrcell.ts +354 -0
- package/src/l3/ptrfield.ts +123 -8
- package/src/l3/regspell.ts +26 -7
- package/src/l3/reindex.ts +293 -103
- package/src/l3/storage.ts +98 -1
- package/src/l3/symbol-refs.ts +182 -23
- package/src/l3/tailmerge.ts +9 -20
- package/src/l3/typing.ts +237 -32
- package/src/l3/unreduce.ts +10 -9
- package/src/l3/volatileptr.ts +17 -54
- package/src/l3/volstore.ts +96 -7
- package/src/mangle.ts +41 -1
- package/src/pattern/engine.ts +373 -82
- package/src/pipeline.ts +589 -27
- package/src/proto-context.ts +1648 -0
- package/src/proto.ts +1203 -49
- package/src/raise/aggmembers.ts +290 -0
- package/src/raise/arrays.ts +8 -3
- package/src/raise/declared-volatile.ts +307 -0
- package/src/raise/divpow2.ts +2 -2
- package/src/raise/errors.ts +17 -0
- package/src/raise/floathelpers.ts +464 -0
- package/src/raise/globalshape.ts +11 -5
- package/src/raise/gvn.ts +29 -8
- package/src/raise/latch.ts +162 -6
- package/src/raise/memberarrays.ts +10 -4
- package/src/raise/narrow.ts +29 -2
- package/src/raise/narrowlocal.ts +11 -6
- package/src/raise/offsetnames.ts +494 -0
- package/src/raise/pairparams.ts +114 -0
- package/src/raise/paramwidth.ts +203 -6
- package/src/raise/pre-recovery.ts +174 -17
- package/src/raise/pre-structure.ts +54 -0
- package/src/raise/recover.ts +26 -15
- package/src/raise/reroll.ts +694 -0
- package/src/raise/retsink.ts +1 -1
- package/src/raise/shortcircuit.ts +66 -30
- package/src/raise/softdiv.ts +21 -23
- package/src/raise/storesign.ts +153 -0
- package/src/raise/struct-arrays.ts +34 -14
- package/src/raise/structs.ts +674 -98
- package/src/raise/truncload.ts +367 -0
- package/src/raise/unthread.ts +400 -0
- package/src/raise/widehelpers.ts +106 -0
- package/src/rank-declare.ts +143 -12
- package/src/rank-variations.ts +117 -31
- package/src/rank.ts +563 -122
- package/src/runtime-helpers.ts +405 -0
- package/src/stillborn.ts +289 -0
- package/src/structure/analysis.ts +1449 -449
- package/src/structure/arith-ops.ts +23 -0
- package/src/structure/globalaccess.ts +111 -9
- package/src/structure/hazards.ts +641 -114
- package/src/structure/local-statics.ts +517 -0
- package/src/structure/namecoalesce.ts +2 -2
- package/src/structure/pointer-spelling.ts +1106 -0
- package/src/structure/redundant-test.ts +99 -0
- package/src/structure/structure.ts +3478 -975
- package/src/structure/switch-recover.ts +403 -178
- package/src/symbols.ts +44 -3
- package/src/target.ts +1387 -71
- package/src/trace.ts +66 -28
- package/src/variation-definitions.ts +243 -13
- package/src/variation-gates.ts +2 -0
- package/src/variation-tokens.ts +25 -7
package/src/declare.ts
CHANGED
|
@@ -19,8 +19,10 @@
|
|
|
19
19
|
// ldrb+lsl+asr where u8 is ldrb alone, so a guessed signedness is a wrong-bytes decl;
|
|
20
20
|
// • `volatile` is load-bearing (a non-volatile MMIO decl lets the compiler fold/reorder
|
|
21
21
|
// accesses), `const` is the ROM-table spelling;
|
|
22
|
-
// • code symbols get `void Name(void);`
|
|
23
|
-
//
|
|
22
|
+
// • code symbols get `void Name(void);` when value-referenced, and a CALL TARGET gets its own
|
|
23
|
+
// prototype re-spelled from the project's `FnProto` — only where that states both a typed
|
|
24
|
+
// parameter list and a `returns`, because `void Name(void);` over a call that passes
|
|
25
|
+
// arguments is C89 poison (core decides it: `spellableProto`);
|
|
24
26
|
// • nothing guesses, with TWO documented exceptions: a SHAPED symbol without the facts to
|
|
25
27
|
// declare faithfully is SKIPPED — the candidate then fails to compile LOUDLY and is
|
|
26
28
|
// dropped by rankBy. Exception one is the 4-byte signless-non-pointer cell (see
|
|
@@ -51,6 +53,7 @@
|
|
|
51
53
|
import { type StructFieldDecl, renderStructDecl } from './backend/cfamily';
|
|
52
54
|
import { T } from './ir/types';
|
|
53
55
|
import type { SymbolRef } from './l3/symbol-refs';
|
|
56
|
+
import { type AggregateLayout, type AggregateMember, declaredWidth, spellableType } from './proto';
|
|
54
57
|
import {
|
|
55
58
|
ENUM_IS_SIGNED,
|
|
56
59
|
type SymbolInfo,
|
|
@@ -134,6 +137,43 @@ function structDecl(tag: string, layout: SymbolStructField[] | undefined, size:
|
|
|
134
137
|
return renderStructDecl(tag, fields);
|
|
135
138
|
}
|
|
136
139
|
|
|
140
|
+
/** A struct the project's headers define, transcribed from their declaration so the compiler lays
|
|
141
|
+
* it out as it lays out theirs: each member in order with its extents and bit width, a nested
|
|
142
|
+
* struct or union inline, and every type spelled so that it needs nothing else declared — a
|
|
143
|
+
* pointer as `void *`, an enum as an inline enum of its own, a scalar the prelude does not name
|
|
144
|
+
* as the prelude's type of its width and signedness. Its members are what size it, not what is
|
|
145
|
+
* read of it: no emitted expression names one (aggregate.ts `aggregateType`). */
|
|
146
|
+
function declaredStructDecl(tag: string, layout: AggregateLayout): string {
|
|
147
|
+
let enums = 0;
|
|
148
|
+
const scalar = (spelling: string): string => {
|
|
149
|
+
const s = spelling
|
|
150
|
+
.replace(/\b(?:const|volatile)\b/g, ' ')
|
|
151
|
+
.trim()
|
|
152
|
+
.replace(/\s+/g, ' ');
|
|
153
|
+
if (s.endsWith('*')) {
|
|
154
|
+
return 'void *';
|
|
155
|
+
}
|
|
156
|
+
if (/^enum\b/.test(s)) {
|
|
157
|
+
return `enum { asmlift_${tag}_enum${enums++} }`;
|
|
158
|
+
}
|
|
159
|
+
if (s === 'float' || s === 'double' || spellableType(s)) {
|
|
160
|
+
return s;
|
|
161
|
+
}
|
|
162
|
+
const bits = declaredWidth(s);
|
|
163
|
+
return `${/^u\d|\bunsigned\b/.test(s) ? 'u' : 's'}${bits}`;
|
|
164
|
+
};
|
|
165
|
+
const body = (members: readonly AggregateMember[]): string =>
|
|
166
|
+
members
|
|
167
|
+
.map((m) => {
|
|
168
|
+
const type = typeof m.type === 'string' ? scalar(m.type) : `${m.type.kind} { ${body(m.type.members!)} }`;
|
|
169
|
+
const declarator = `${m.name}${(m.dims ?? []).map((n) => `[${n}]`).join('')}`;
|
|
170
|
+
const bits = m.bits !== undefined ? ` : ${m.bits}` : '';
|
|
171
|
+
return `${type}${type.endsWith('*') || declarator === '' ? '' : ' '}${declarator}${bits};`;
|
|
172
|
+
})
|
|
173
|
+
.join(' ');
|
|
174
|
+
return `struct ${tag} { ${body(layout.members!)} };`;
|
|
175
|
+
}
|
|
176
|
+
|
|
137
177
|
/**
|
|
138
178
|
* Render the declaration block for a candidate's recorded symbol references. Deterministic
|
|
139
179
|
* (refs arrive name-sorted from core; struct decls dedupe by tag). The block is prepended by
|
|
@@ -144,7 +184,37 @@ function structDecl(tag: string, layout: SymbolStructField[] | undefined, size:
|
|
|
144
184
|
export function renderDeclarations(refs: SymbolRef[]): string {
|
|
145
185
|
const lines: string[] = [];
|
|
146
186
|
const declaredTags = new Set<string>();
|
|
147
|
-
|
|
187
|
+
const declaredTypedefs = new Set<string>();
|
|
188
|
+
const defineStruct = (s: { readonly name: string; readonly declared: string; readonly layout: AggregateLayout }) => {
|
|
189
|
+
if (!declaredTags.has(s.name)) {
|
|
190
|
+
declaredTags.add(s.name);
|
|
191
|
+
lines.push(declaredStructDecl(s.name, s.layout));
|
|
192
|
+
}
|
|
193
|
+
if (!/^(?:struct|union)\s/.test(s.declared) && !declaredTypedefs.has(s.declared)) {
|
|
194
|
+
declaredTypedefs.add(s.declared);
|
|
195
|
+
lines.push(`typedef struct ${s.name} ${s.declared};`);
|
|
196
|
+
}
|
|
197
|
+
};
|
|
198
|
+
for (const {
|
|
199
|
+
name,
|
|
200
|
+
info,
|
|
201
|
+
access,
|
|
202
|
+
proto,
|
|
203
|
+
returned,
|
|
204
|
+
passed,
|
|
205
|
+
passedAs,
|
|
206
|
+
holdsPointer,
|
|
207
|
+
implicitCall,
|
|
208
|
+
definesReturn,
|
|
209
|
+
} of refs) {
|
|
210
|
+
// THE FUNCTION'S OWN STRUCT RETURN, defined as a callee's is; the function itself is declared
|
|
211
|
+
// by its definition
|
|
212
|
+
if (definesReturn) {
|
|
213
|
+
if (returned !== undefined) {
|
|
214
|
+
defineStruct(returned);
|
|
215
|
+
}
|
|
216
|
+
continue;
|
|
217
|
+
}
|
|
148
218
|
// An address-cast macro declares itself: the header's own body, verbatim. It must NOT become
|
|
149
219
|
// an `extern` — that is the whole point of the fact (an extern emits a relocated pool word
|
|
150
220
|
// where the macro emits the numeric one the target shows).
|
|
@@ -152,10 +222,42 @@ export function renderDeclarations(refs: SymbolRef[]): string {
|
|
|
152
222
|
lines.push(`#define ${name} ${info.macroBody}`);
|
|
153
223
|
continue;
|
|
154
224
|
}
|
|
225
|
+
// A GLOBAL REGISTER VARIABLE declares itself in its register (SymbolInfo.globalRegister), typed
|
|
226
|
+
// as a name-only global is: a pointer where the body stores or meets one, else the word the
|
|
227
|
+
// body accesses.
|
|
228
|
+
if (info.globalRegister !== undefined) {
|
|
229
|
+
const t = holdsPointer ? 'void *' : `${intType(access?.width ?? 4, access?.signed ?? true) ?? 's32'} `;
|
|
230
|
+
lines.push(`register ${t}${name} __asm__("${info.globalRegister}");`);
|
|
231
|
+
continue;
|
|
232
|
+
}
|
|
233
|
+
// A CALL TARGET the project declared completely — its own prototype, re-spelled from the
|
|
234
|
+
// parameter and return type texts the project wrote. This is the one declaration here that
|
|
235
|
+
// is load-bearing for the CALL and not only for the name: an implicit declaration is `int`,
|
|
236
|
+
// which narrows a 64-bit return and adds the sign-extension the target does not have. A
|
|
237
|
+
// parameterless list is spelled `(void)`, never `()`, because `()` declares nothing about
|
|
238
|
+
// the arguments and gcc-2.9 then promotes them.
|
|
239
|
+
if (proto !== undefined) {
|
|
240
|
+
// A STRUCT IT RETURNS THROUGH MEMORY is the headers' type, spelled as they spell it, so it is
|
|
241
|
+
// defined here with the rest of what they own: by its tag, once, whoever else declares that
|
|
242
|
+
// tag — and a typedef name is bound to it on top.
|
|
243
|
+
// …and so is a struct it is passed by value, the same way.
|
|
244
|
+
for (const s of [...(returned?.declared !== undefined ? [returned] : []), ...(passed ?? [])]) {
|
|
245
|
+
defineStruct(s);
|
|
246
|
+
}
|
|
247
|
+
lines.push(`${proto.returns} ${name}(${proto.params.length > 0 ? proto.params.join(', ') : 'void'});`);
|
|
248
|
+
continue;
|
|
249
|
+
}
|
|
250
|
+
// A CALL TARGET no prototype spells, named ahead of its first call by an initializer — C's
|
|
251
|
+
// implicit declaration, `int F();`, written where the initializer can see it. No parameter
|
|
252
|
+
// list, so the call binds to it exactly as it bound to the implicit one (see collectSymbolRefs).
|
|
253
|
+
if (implicitCall) {
|
|
254
|
+
lines.push(`int ${name}();`);
|
|
255
|
+
continue;
|
|
256
|
+
}
|
|
155
257
|
if (info.kind === 'code') {
|
|
156
258
|
// value-referenced code symbol ((u32)Func): any prototype makes the name visible, and
|
|
157
|
-
// the address is arity-independent.
|
|
158
|
-
//
|
|
259
|
+
// the address is arity-independent. A call target reaches here only with a complete
|
|
260
|
+
// prototype or as an initializer's implicit call, which the branches above printed.
|
|
159
261
|
lines.push(`void ${name}(void);`);
|
|
160
262
|
continue;
|
|
161
263
|
}
|
|
@@ -247,6 +349,18 @@ export function renderDeclarations(refs: SymbolRef[]): string {
|
|
|
247
349
|
// argument applies. For a `synthesized` one it does not — the width came from the
|
|
248
350
|
// target's own asm, so this line is a hypothesis fitted to the bytes; see the module
|
|
249
351
|
// note's "WHERE THE ONLY-LOSES-SCORE ARGUMENT STOPS".
|
|
352
|
+
// A global that holds a pointer (ref.holdsPointer) is `void *`, the type every object
|
|
353
|
+
// pointer converts to without a cast; the qualifiers bind to the cell.
|
|
354
|
+
if (holdsPointer) {
|
|
355
|
+
lines.push(`extern void *${info.volatile ? 'volatile ' : ''}${info.const ? 'const ' : ''}${name};`);
|
|
356
|
+
break;
|
|
357
|
+
}
|
|
358
|
+
// A global passed bare as a struct by value is that struct, which its callee's prototype
|
|
359
|
+
// defines (`passed`); a declaration of an incomplete tag is completed by that definition.
|
|
360
|
+
if (passedAs !== undefined) {
|
|
361
|
+
lines.push(`extern ${quals(info)}${passedAs} ${name};`);
|
|
362
|
+
break;
|
|
363
|
+
}
|
|
250
364
|
const t = access ? intType(access.width, access.signed) : null;
|
|
251
365
|
lines.push(`extern ${quals(info)}${t ?? 'u32'} ${name};`);
|
|
252
366
|
break;
|
|
@@ -256,18 +370,23 @@ export function renderDeclarations(refs: SymbolRef[]): string {
|
|
|
256
370
|
return lines.length ? lines.join('\n') + '\n' : '';
|
|
257
371
|
}
|
|
258
372
|
|
|
259
|
-
/**
|
|
373
|
+
/** THE LINES OF A RENDERED DECLARATION BLOCK THAT THE HEADERS WORLD KEEPS: its object-like
|
|
374
|
+
* `#define`s and its global register variables. Everything else there is owned by the injected
|
|
375
|
+
* headers (a duplicate typedef or struct definition is a C89 hard error), and these two are not:
|
|
376
|
+
*
|
|
377
|
+
* - an address-cast macro, because a duplicate `#define` with an identical body is legal — and a
|
|
378
|
+
* PREPROCESSED project context has no macros left at all, so dropping these turns a macro-named
|
|
379
|
+
* candidate into an `undeclared identifier` rather than a spelling choice;
|
|
380
|
+
* - a global register variable (`register T greg_r8 __asm__("r8");`, SymbolInfo.globalRegister),
|
|
381
|
+
* because no header declares the name the lift made up for it.
|
|
260
382
|
*
|
|
261
|
-
*
|
|
262
|
-
*
|
|
263
|
-
|
|
264
|
-
* legal — and a PREPROCESSED project context has no macros left at all, so dropping these turns a
|
|
265
|
-
* macro-named candidate into an `undeclared identifier` rather than a spelling choice. */
|
|
266
|
-
export function macroDefinesOf(declarations: string | undefined): string {
|
|
383
|
+
* Chosen by each line's leading keyword, which `renderDeclarations` prints for these two kinds
|
|
384
|
+
* only: a new kind of line it prints with either keyword rides into the headers world too. */
|
|
385
|
+
export function declarationsKeptWithHeaders(declarations: string | undefined): string {
|
|
267
386
|
if (!declarations) {
|
|
268
387
|
return '';
|
|
269
388
|
}
|
|
270
|
-
const lines = declarations.split('\n').filter((l) => l.startsWith('#define '));
|
|
389
|
+
const lines = declarations.split('\n').filter((l) => l.startsWith('#define ') || l.startsWith('register '));
|
|
271
390
|
return lines.length ? lines.join('\n') + '\n' : '';
|
|
272
391
|
}
|
|
273
392
|
|
package/src/frontend/asmdata.ts
CHANGED
|
@@ -29,17 +29,35 @@ export interface Reloc {
|
|
|
29
29
|
export interface AsmData {
|
|
30
30
|
sections: Map<string, Uint8Array>; // section name → raw bytes (file order)
|
|
31
31
|
relocs: Reloc[];
|
|
32
|
-
symbols: Map<string,
|
|
32
|
+
symbols: Map<string, AsmSymbol>;
|
|
33
|
+
/** how many symbols the `objdump -t` listing printed — the symbol table's entries past its null one */
|
|
34
|
+
symbolCount: number;
|
|
33
35
|
bigEndian: boolean;
|
|
34
36
|
}
|
|
35
37
|
|
|
38
|
+
/** One `objdump -t` symbol: its section, offset in it and size, and `index`, its position in the
|
|
39
|
+
* listing counting from 1 — its symbol-table index, which is what a per-symbol side table in the
|
|
40
|
+
* object (mwcc's `.comment`, frontend/local-object.ts) is indexed by. */
|
|
41
|
+
export interface AsmSymbol {
|
|
42
|
+
section: string;
|
|
43
|
+
value: number;
|
|
44
|
+
size: number;
|
|
45
|
+
index: number;
|
|
46
|
+
}
|
|
47
|
+
|
|
36
48
|
const readU32 = (b: Uint8Array, off: number, big: boolean): number =>
|
|
37
49
|
big
|
|
38
50
|
? ((b[off] << 24) | (b[off + 1] << 16) | (b[off + 2] << 8) | b[off + 3]) >>> 0
|
|
39
51
|
: ((b[off + 3] << 24) | (b[off + 2] << 16) | (b[off + 1] << 8) | b[off]) >>> 0;
|
|
40
52
|
|
|
41
|
-
// Parse an `objdump -r` VALUE field: `sw_jt+0x00000020` / `.text` / `@15` → {sym, addend}.
|
|
53
|
+
// Parse an `objdump -r` VALUE field: `sw_jt+0x00000020` / `.text` / `@15` → {sym, addend}. A
|
|
54
|
+
// negative RELA addend prints as `garr-0x00000004` (mwcc's `&garr[-1]`, compiled), and is kept as
|
|
55
|
+
// the same 32-bit word a positive one is.
|
|
42
56
|
function parseRelocValue(v: string): { sym: string; addend: number } {
|
|
57
|
+
const minus = v.match(/^(.+)-(0x[0-9a-f]+)$/i);
|
|
58
|
+
if (minus) {
|
|
59
|
+
return { sym: minus[1], addend: -parseInt(minus[2], 16) >>> 0 };
|
|
60
|
+
}
|
|
43
61
|
const plus = v.indexOf('+');
|
|
44
62
|
if (plus < 0) {
|
|
45
63
|
return { sym: v, addend: 0 };
|
|
@@ -112,7 +130,8 @@ export function parseAsmData(
|
|
|
112
130
|
}
|
|
113
131
|
|
|
114
132
|
// --- `objdump -t`: `VALUE FLAGS SECTION\tSIZE NAME` (section/size split by TAB) ---
|
|
115
|
-
const symbols = new Map<string,
|
|
133
|
+
const symbols = new Map<string, AsmSymbol>();
|
|
134
|
+
let symbolCount = 0;
|
|
116
135
|
for (const line of symbolsDump.split('\n')) {
|
|
117
136
|
const tab = line.indexOf('\t');
|
|
118
137
|
if (tab < 0) {
|
|
@@ -121,14 +140,15 @@ export function parseAsmData(
|
|
|
121
140
|
const left = line.slice(0, tab),
|
|
122
141
|
right = line.slice(tab + 1);
|
|
123
142
|
const lm = left.match(/^([0-9a-f]+)\s+.{6,8}\s(\S+)\s*$/i); // value … flags(7) section
|
|
124
|
-
const rm = right.match(/^[0-9a-f]
|
|
143
|
+
const rm = right.match(/^([0-9a-f]+)\s+(.+?)\s*$/i); // size name
|
|
125
144
|
if (!lm || !rm) {
|
|
126
145
|
continue;
|
|
127
146
|
}
|
|
128
|
-
|
|
147
|
+
symbolCount++;
|
|
148
|
+
symbols.set(rm[2], { section: lm[2], value: parseInt(lm[1], 16), size: parseInt(rm[1], 16), index: symbolCount });
|
|
129
149
|
}
|
|
130
150
|
|
|
131
|
-
return { sections, relocs, symbols, bigEndian };
|
|
151
|
+
return { sections, relocs, symbols, symbolCount, bigEndian };
|
|
132
152
|
}
|
|
133
153
|
|
|
134
154
|
/** Read a dense jump table's N target `.text` byte-offsets, or `null` if ANYTHING doesn't resolve
|