Lines Matching full:r

33 static void freader_init_from_file(struct freader *r, void *buf, u32 buf_sz,  in freader_init_from_file()  argument
36 memset(r, 0, sizeof(*r)); in freader_init_from_file()
37 r->buf = buf; in freader_init_from_file()
38 r->buf_sz = buf_sz; in freader_init_from_file()
39 r->file = file; in freader_init_from_file()
40 r->may_fault = may_fault; in freader_init_from_file()
43 static void freader_init_from_mem(struct freader *r, const char *data, u64 data_sz) in freader_init_from_mem() argument
45 memset(r, 0, sizeof(*r)); in freader_init_from_mem()
46 r->data = data; in freader_init_from_mem()
47 r->data_sz = data_sz; in freader_init_from_mem()
50 static void freader_put_folio(struct freader *r) in freader_put_folio() argument
52 if (!r->folio) in freader_put_folio()
54 kunmap_local(r->addr); in freader_put_folio()
55 folio_put(r->folio); in freader_put_folio()
56 r->folio = NULL; in freader_put_folio()
59 static int freader_get_folio(struct freader *r, loff_t file_off) in freader_get_folio() argument
62 if (r->folio && file_off >= r->folio_off && in freader_get_folio()
63 file_off < r->folio_off + folio_size(r->folio)) in freader_get_folio()
66 freader_put_folio(r); in freader_get_folio()
69 if (secretmem_mapping(r->file->f_mapping)) in freader_get_folio()
72 r->folio = filemap_get_folio(r->file->f_mapping, file_off >> PAGE_SHIFT); in freader_get_folio()
75 if (r->may_fault && (IS_ERR(r->folio) || !folio_test_uptodate(r->folio))) { in freader_get_folio()
76 filemap_invalidate_lock_shared(r->file->f_mapping); in freader_get_folio()
77 r->folio = read_cache_folio(r->file->f_mapping, file_off >> PAGE_SHIFT, in freader_get_folio()
78 NULL, r->file); in freader_get_folio()
79 filemap_invalidate_unlock_shared(r->file->f_mapping); in freader_get_folio()
82 if (IS_ERR(r->folio) || !folio_test_uptodate(r->folio)) { in freader_get_folio()
83 if (!IS_ERR(r->folio)) in freader_get_folio()
84 folio_put(r->folio); in freader_get_folio()
85 r->folio = NULL; in freader_get_folio()
89 r->folio_off = folio_pos(r->folio); in freader_get_folio()
90 r->addr = kmap_local_folio(r->folio, 0); in freader_get_folio()
95 static const void *freader_fetch(struct freader *r, loff_t file_off, size_t sz) in freader_fetch() argument
100 if (WARN_ON(r->buf && sz > r->buf_sz)) { in freader_fetch()
101 r->err = -E2BIG; in freader_fetch()
106 r->err = -EOVERFLOW; in freader_fetch()
111 if (!r->buf) { in freader_fetch()
112 if (file_off + sz > r->data_sz) { in freader_fetch()
113 r->err = -ERANGE; in freader_fetch()
116 return r->data + file_off; in freader_fetch()
120 r->err = freader_get_folio(r, file_off); in freader_fetch()
121 if (r->err) in freader_fetch()
128 folio_sz = folio_size(r->folio); in freader_fetch()
129 if (file_off + sz > r->folio_off + folio_sz) { in freader_fetch()
130 int part_sz = r->folio_off + folio_sz - file_off; in freader_fetch()
133 memcpy(r->buf, r->addr + (file_off - r->folio_off), part_sz); in freader_fetch()
136 r->err = freader_get_folio(r, r->folio_off + folio_sz); in freader_fetch()
137 if (r->err) in freader_fetch()
141 memcpy(r->buf + part_sz, r->addr, sz - part_sz); in freader_fetch()
143 return r->buf; in freader_fetch()
147 return r->addr + (file_off - r->folio_off); in freader_fetch()
150 static void freader_cleanup(struct freader *r) in freader_cleanup() argument
152 if (!r->buf) in freader_cleanup()
155 freader_put_folio(r); in freader_cleanup()
163 static int parse_build_id(struct freader *r, unsigned char *build_id, __u32 *size, in parse_build_id() argument
176 nhdr = freader_fetch(r, note_off, sizeof(Elf32_Nhdr) + note_name_sz); in parse_build_id()
178 return r->err; in parse_build_id()
196 data = freader_fetch(r, build_id_off, desc_sz); in parse_build_id()
198 return r->err; in parse_build_id()
214 static int get_build_id_32(struct freader *r, unsigned char *build_id, __u32 *size) in get_build_id_32() argument
220 ehdr = freader_fetch(r, 0, sizeof(Elf32_Ehdr)); in get_build_id_32()
222 return r->err; in get_build_id_32()
237 phdr = freader_fetch(r, phoff + i * sizeof(Elf32_Phdr), sizeof(Elf32_Phdr)); in get_build_id_32()
239 return r->err; in get_build_id_32()
242 !parse_build_id(r, build_id, size, READ_ONCE(phdr->p_offset), in get_build_id_32()
250 static int get_build_id_64(struct freader *r, unsigned char *build_id, __u32 *size) in get_build_id_64() argument
257 ehdr = freader_fetch(r, 0, sizeof(Elf64_Ehdr)); in get_build_id_64()
259 return r->err; in get_build_id_64()
274 phdr = freader_fetch(r, phoff + i * sizeof(Elf64_Phdr), sizeof(Elf64_Phdr)); in get_build_id_64()
276 return r->err; in get_build_id_64()
279 !parse_build_id(r, build_id, size, READ_ONCE(phdr->p_offset), in get_build_id_64()
294 struct freader r; in __build_id_parse() local
302 freader_init_from_file(&r, buf, sizeof(buf), vma->vm_file, may_fault); in __build_id_parse()
305 ehdr = freader_fetch(&r, 0, offsetofend(Elf32_Ehdr, e_type)); in __build_id_parse()
307 ret = r.err; in __build_id_parse()
322 ret = get_build_id_32(&r, build_id, size); in __build_id_parse()
324 ret = get_build_id_64(&r, build_id, size); in __build_id_parse()
326 freader_cleanup(&r); in __build_id_parse()
372 struct freader r; in build_id_parse_buf() local
375 freader_init_from_mem(&r, buf, buf_size); in build_id_parse_buf()
377 err = parse_build_id(&r, build_id, NULL, 0, buf_size); in build_id_parse_buf()
379 freader_cleanup(&r); in build_id_parse_buf()