static int section_match(const struct pt_section *lhs, const struct pt_section *rhs) { const char *lfilename, *rfilename; if (!lhs || !rhs) return -pte_internal; if (pt_section_offset(lhs) != pt_section_offset(rhs)) return 0; if (pt_section_size(lhs) != pt_section_size(rhs)) return 0; lfilename = pt_section_filename(lhs); rfilename = pt_section_filename(rhs); if (!lfilename || !rfilename) return -pte_internal; if (strcmp(lfilename, rfilename) != 0) return 0; return 1; }
int pt_section_clone(struct pt_section **pclone, const struct pt_section *section, uint64_t offset, uint64_t size) { struct pt_section *clone; uint64_t begin, end, sbegin, send; if (!pclone || !section) return -pte_internal; begin = offset; end = begin + size; sbegin = pt_section_offset(section); send = sbegin + pt_section_size(section); if (begin < sbegin || send < end) return -pte_internal; clone = pt_mk_section(pt_section_filename(section), offset, size); if (!clone) return -pte_nomem; *pclone = clone; return 0; }
static int pt_image_clone(struct pt_section_list **list, const struct pt_mapped_section *msec, uint64_t begin, uint64_t end, int isid) { const struct pt_asid *masid; struct pt_section_list *next; struct pt_section *section, *sec; uint64_t mbegin, sbegin, offset, size; int errcode; if (!list || !msec) return -pte_internal; sec = pt_msec_section(msec); masid = pt_msec_asid(msec); mbegin = pt_msec_begin(msec); sbegin = pt_section_offset(sec); if (end <= begin) return -pte_internal; if (begin < mbegin) return -pte_internal; offset = begin - mbegin; size = end - begin; errcode = pt_section_clone(§ion, sec, sbegin + offset, size); if (errcode < 0) return errcode; next = pt_mk_section_list(section, masid, begin, isid); if (!next) { (void) pt_section_put(section); return -pte_nomem; } /* The image list got its own reference; let's drop ours. */ errcode = pt_section_put(section); if (errcode < 0) { pt_section_list_free(next); return errcode; } /* Add the new section. */ next->next = *list; *list = next; return 0; }
static int pt_iscache_find_locked(struct pt_image_section_cache *iscache, const char *filename, uint64_t offset, uint64_t size, uint64_t laddr) { uint16_t idx, end; if (!iscache || !filename) return -pte_internal; end = iscache->size; for (idx = 0; idx < end; ++idx) { const struct pt_iscache_entry *entry; const struct pt_section *section; const char *sec_filename; uint64_t sec_offset, sec_size; entry = &iscache->entries[idx]; /* We do not zero-initialize the array - a NULL check is * pointless. */ section = entry->section; sec_filename = pt_section_filename(section); sec_offset = pt_section_offset(section); sec_size = pt_section_size(section); if (entry->laddr != laddr) continue; if (sec_offset != offset) continue; if (sec_size != size) continue; /* We should not have a section without a filename. */ if (!sec_filename) return -pte_internal; if (strcmp(sec_filename, filename) != 0) continue; return isid_from_index(idx); } return 0; }