static struct ptunit_result read_offset(struct section_fixture *sfix) { uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 }; uint8_t buffer[] = { 0xcc, 0xcc, 0xcc }; int status; sfix_write(sfix, bytes); sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull); ptu_ptr(sfix->section); status = pt_section_map(sfix->section); ptu_int_eq(status, 0); status = pt_section_read(sfix->section, buffer, 2, 0x1ull); ptu_int_eq(status, 2); ptu_uint_eq(buffer[0], bytes[2]); ptu_uint_eq(buffer[1], bytes[3]); ptu_uint_eq(buffer[2], 0xcc); status = pt_section_unmap(sfix->section); ptu_int_eq(status, 0); return ptu_passed(); }
int pt_msec_read_mapped(const struct pt_mapped_section *msec, uint8_t *buffer, uint16_t size, const struct pt_asid *asid, uint64_t addr) { struct pt_section *sec; int errcode, status; if (!msec || !asid) return -pte_internal; errcode = pt_msec_matches_asid(msec, asid); if (errcode < 0) return errcode; if (!errcode) return -pte_nomap; if (addr < msec->vaddr) return -pte_nomap; addr -= msec->vaddr; sec = msec->section; status = pt_section_read(sec, buffer, size, addr); return status; }
/* Read memory from a mapped section. * * @msec's section must be mapped. * * Returns the number of bytes read on success. * Returns a negative error code otherwise. */ static int pt_image_read_msec(uint8_t *buffer, uint16_t size, const struct pt_mapped_section *msec, uint64_t addr) { struct pt_section *section; uint64_t offset; if (!msec) return -pte_internal; section = pt_msec_section(msec); offset = pt_msec_unmap(msec, addr); return pt_section_read(section, buffer, size, offset); }
static int pt_image_read_from(struct pt_image *image, struct pt_section *section, uint8_t *buffer, uint16_t size, uint64_t addr) { int status; if (!buffer || !image || !section) return -pte_invalid; status = pt_section_read(section, buffer, size, addr); if (status >= 0) image->cache = section; return status; }
static struct ptunit_result read_nomap(struct section_fixture *sfix) { uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 }, buffer[] = { 0xcc }; int status; sfix_write(sfix, bytes); sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull); ptu_ptr(sfix->section); status = pt_section_read(sfix->section, buffer, 1, 0x0ull); ptu_int_eq(status, -pte_nomap); ptu_uint_eq(buffer[0], 0xcc); return ptu_passed(); }
static int worker(void *arg) { struct section_fixture *sfix; int it, errcode; sfix = arg; if (!sfix) return -pte_internal; for (it = 0; it < num_work; ++it) { uint8_t buffer[] = { 0xcc, 0xcc, 0xcc }; int read; errcode = pt_section_get(sfix->section); if (errcode < 0) return errcode; errcode = pt_section_map(sfix->section); if (errcode < 0) goto out_put; read = pt_section_read(sfix->section, buffer, 2, 0x0ull); if (read < 0) goto out_unmap; errcode = -pte_invalid; if ((read != 2) || (buffer[0] != 0x2) || (buffer[1] != 0x4)) goto out_unmap; errcode = pt_section_unmap(sfix->section); if (errcode < 0) goto out_put; errcode = pt_section_put(sfix->section); if (errcode < 0) return errcode; } return 0; out_unmap: (void) pt_section_unmap(sfix->section); out_put: (void) pt_section_put(sfix->section); return errcode; }
int pt_iscache_read(struct pt_image_section_cache *iscache, uint8_t *buffer, uint64_t size, int isid, uint64_t vaddr) { struct pt_section *section; uint64_t laddr; int errcode, status; if (!iscache || !buffer || !size) return -pte_invalid; errcode = pt_iscache_lookup(iscache, §ion, &laddr, isid); if (errcode < 0) return errcode; if (vaddr < laddr) { (void) pt_section_put(section); return -pte_nomap; } vaddr -= laddr; errcode = pt_section_map(section); if (errcode < 0) { (void) pt_section_put(section); return errcode; } /* We truncate the read if it gets too big. The user is expected to * issue further reads for the remaining part. */ if (UINT16_MAX < size) size = UINT16_MAX; status = pt_section_read(section, buffer, (uint16_t) size, vaddr); errcode = pt_section_unmap(section); if (errcode < 0) { (void) pt_section_put(section); return errcode; } errcode = pt_section_put(section); if (errcode < 0) return errcode; return status; }