* Make one or more memory reads and update values. For the caller, it should look like a single * memory read but, if one read fails, all reads are considered as failed. * * @param startAddr The start address of the memory region. Everything else is relative to `startAddr` * @pa
(
session: vscode.DebugSession, startAddr: number, specs: AddrRange[], storeTo: number[])
| 13 | * @param storeTo This is where read-results go. The first element represents item at `startAddr` |
| 14 | */ |
| 15 | public static readMemoryChunks( |
| 16 | session: vscode.DebugSession, startAddr: number, specs: AddrRange[], storeTo: number[]): Promise<boolean> { |
| 17 | const promises = specs.map((r) => { |
| 18 | return new Promise((resolve, reject) => { |
| 19 | const addr = '0x' + r.base.toString(16); |
| 20 | session.customRequest('read-memory', { address: addr, length: r.length }).then((data) => { |
| 21 | let dst = r.base - startAddr; |
| 22 | const bytes: number[] = data.bytes; |
| 23 | for (const byte of bytes) { |
| 24 | storeTo[dst++] = byte; |
| 25 | } |
| 26 | resolve(true); |
| 27 | }, (e) => { |
| 28 | let dst = r.base - startAddr; |
| 29 | // tslint:disable-next-line: prefer-for-of |
| 30 | for (let ix = 0; ix < r.length; ix++) { |
| 31 | storeTo[dst++] = 0xff; |
| 32 | } |
| 33 | reject(e); |
| 34 | }); |
| 35 | }); |
| 36 | }); |
| 37 | |
| 38 | return new Promise(async (resolve, reject) => { |
| 39 | const results = await Promise.all(promises.map((p) => p.catch((e) => e))); |
| 40 | const errs: string[] = []; |
| 41 | results.map((e) => { |
| 42 | if (e instanceof Error) { |
| 43 | errs.push(e.message); |
| 44 | } |
| 45 | }); |
| 46 | if (errs.length !== 0) { |
| 47 | reject(new Error(errs.join('\n'))); |
| 48 | } else { |
| 49 | resolve(true); |
| 50 | } |
| 51 | }); |
| 52 | } |
| 53 | |
| 54 | public static readMemory( |
| 55 | session: vscode.DebugSession, startAddr: number, length: number, storeTo: number[]): Promise<boolean> { |
no test coverage detected