int pt_sec_posix_map(struct pt_section *section, int fd) { struct pt_sec_posix_mapping *mapping; uint64_t offset, size, adjustment; uint8_t *base; if (!section) return -pte_internal; offset = section->offset; size = section->size; adjustment = offset % PAGE_SIZE; offset -= adjustment; size += adjustment; /* The section is supposed to fit into the file so we shouldn't * see any overflows, here. */ if (size < section->size) return -pte_internal; base = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, offset); if (base == MAP_FAILED) return -pte_nomem; mapping = malloc(sizeof(*mapping)); if (!mapping) goto out_map; mapping->base = base; mapping->size = size; mapping->begin = base + adjustment; mapping->end = base + size; section->mapping = mapping; section->unmap = pt_sec_posix_unmap; section->read = pt_sec_posix_read; return pt_section_add_bcache(section); out_map: munmap(base, size); return -pte_nomem; }
int pt_sec_file_map(struct pt_section *section, FILE *file) { struct pt_sec_file_mapping *mapping; uint64_t offset, size; long begin, end, fsize; int errcode; if (!section) return -pte_internal; mapping = section->mapping; if (mapping) return -pte_internal; offset = section->offset; size = section->size; begin = (long) offset; end = begin + (long) size; /* Check for overflows. */ if ((uint64_t) begin != offset) return -pte_bad_image; if ((uint64_t) end != (offset + size)) return -pte_bad_image; if (end < begin) return -pte_bad_image; /* Validate that the section lies within the file. */ errcode = fseek(file, 0, SEEK_END); if (errcode) return -pte_bad_image; fsize = ftell(file); if (fsize < 0) return -pte_bad_image; if (fsize < end) return -pte_bad_image; mapping = malloc(sizeof(*mapping)); if (!mapping) return -pte_nomem; errcode = fmap_init(mapping); if (errcode < 0) { free(mapping); return errcode; } mapping->file = file; mapping->begin = begin; mapping->end = end; section->mapping = mapping; section->unmap = pt_sec_file_unmap; section->read = pt_sec_file_read; return pt_section_add_bcache(section); }