]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - libctf/ctf-archive.c
Update year range in copyright notice of binutils files
[thirdparty/binutils-gdb.git] / libctf / ctf-archive.c
CommitLineData
9402cc59 1/* CTF archive files.
d87bef3a 2 Copyright (C) 2019-2023 Free Software Foundation, Inc.
9402cc59
NA
3
4 This file is part of libctf.
5
6 libctf is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
9 version.
10
11 This program is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 See the GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; see the file COPYING. If not see
18 <http://www.gnu.org/licenses/>. */
19
20#include <ctf-impl.h>
21#include <sys/types.h>
22#include <sys/stat.h>
23#include <elf.h>
a0486bac 24#include "ctf-endian.h"
9402cc59
NA
25#include <errno.h>
26#include <fcntl.h>
27#include <stdio.h>
28#include <string.h>
29#include <unistd.h>
30
31#ifdef HAVE_MMAP
32#include <sys/mman.h>
33#endif
34
139633c3 35static off_t arc_write_one_ctf (ctf_dict_t * f, int fd, size_t threshold);
ae41200b
NA
36static ctf_dict_t *ctf_dict_open_by_offset (const struct ctf_archive *arc,
37 const ctf_sect_t *symsect,
38 const ctf_sect_t *strsect,
53651de8
NA
39 size_t offset, int little_endian,
40 int *errp);
9402cc59
NA
41static int sort_modent_by_name (const void *one, const void *two, void *n);
42static void *arc_mmap_header (int fd, size_t headersz);
43static void *arc_mmap_file (int fd, size_t size);
44static int arc_mmap_writeout (int fd, void *header, size_t headersz,
45 const char **errmsg);
46static int arc_mmap_unmap (void *header, size_t headersz, const char **errmsg);
2c78e925
NA
47static void ctf_arc_import_parent (const ctf_archive_t *arc, ctf_dict_t *fp);
48
f4f60336
NA
49/* Flag to indicate "symbol not present" in ctf_archive_internal.ctfi_symdicts
50 and ctfi_symnamedicts. Never initialized. */
2c78e925 51static ctf_dict_t enosym;
9402cc59 52
5537f9b9 53/* Write out a CTF archive to the start of the file referenced by the passed-in
139633c3
NA
54 fd. The entries in CTF_DICTS are referenced by name: the names are passed in
55 the names array, which must have CTF_DICTS entries.
9402cc59
NA
56
57 Returns 0 on success, or an errno, or an ECTF_* value. */
58int
139633c3 59ctf_arc_write_fd (int fd, ctf_dict_t **ctf_dicts, size_t ctf_dict_cnt,
5537f9b9 60 const char **names, size_t threshold)
9402cc59
NA
61{
62 const char *errmsg;
63 struct ctf_archive *archdr;
9402cc59
NA
64 size_t i;
65 char dummy = 0;
66 size_t headersz;
67 ssize_t namesz;
68 size_t ctf_startoffs; /* Start of the section we are working over. */
69 char *nametbl = NULL; /* The name table. */
70 char *np;
71 off_t nameoffs;
72 struct ctf_archive_modent *modent;
73
5537f9b9 74 ctf_dprintf ("Writing CTF archive with %lu files\n",
139633c3 75 (unsigned long) ctf_dict_cnt);
9402cc59 76
9402cc59
NA
77 /* Figure out the size of the mmap()ed header, including the
78 ctf_archive_modent array. We assume that all of this needs no
79 padding: a likely assumption, given that it's all made up of
80 uint64_t's. */
81 headersz = sizeof (struct ctf_archive)
139633c3 82 + (ctf_dict_cnt * sizeof (uint64_t) * 2);
62d8e3b7 83 ctf_dprintf ("headersz is %lu\n", (unsigned long) headersz);
9402cc59
NA
84
85 /* From now on we work in two pieces: an mmap()ed region from zero up to the
86 headersz, and a region updated via write() starting after that, containing
87 all the tables. Platforms that do not support mmap() just use write(). */
88 ctf_startoffs = headersz;
89 if (lseek (fd, ctf_startoffs - 1, SEEK_SET) < 0)
90 {
926c9e76 91 errmsg = N_("ctf_arc_write(): cannot extend file while writing");
5537f9b9 92 goto err;
9402cc59
NA
93 }
94
95 if (write (fd, &dummy, 1) < 0)
96 {
926c9e76 97 errmsg = N_("ctf_arc_write(): cannot extend file while writing");
5537f9b9 98 goto err;
9402cc59
NA
99 }
100
101 if ((archdr = arc_mmap_header (fd, headersz)) == NULL)
102 {
926c9e76 103 errmsg = N_("ctf_arc_write(): cannot mmap");
5537f9b9 104 goto err;
9402cc59
NA
105 }
106
107 /* Fill in everything we can, which is everything other than the name
108 table offset. */
109 archdr->ctfa_magic = htole64 (CTFA_MAGIC);
139633c3 110 archdr->ctfa_ndicts = htole64 (ctf_dict_cnt);
9402cc59
NA
111 archdr->ctfa_ctfs = htole64 (ctf_startoffs);
112
113 /* We could validate that all CTF files have the same data model, but
114 since any reasonable construction process will be building things of
115 only one bitness anyway, this is pretty pointless, so just use the
116 model of the first CTF file for all of them. (It *is* valid to
117 create an empty archive: the value of ctfa_model is irrelevant in
118 this case, but we must be sure not to dereference uninitialized
119 memory.) */
120
139633c3
NA
121 if (ctf_dict_cnt > 0)
122 archdr->ctfa_model = htole64 (ctf_getmodel (ctf_dicts[0]));
9402cc59
NA
123
124 /* Now write out the CTFs: ctf_archive_modent array via the mapping,
125 ctfs via write(). The names themselves have not been written yet: we
126 track them in a local strtab until the time is right, and sort the
127 modents array after construction.
128
129 The name table is not sorted. */
130
139633c3 131 for (i = 0, namesz = 0; i < le64toh (archdr->ctfa_ndicts); i++)
9402cc59
NA
132 namesz += strlen (names[i]) + 1;
133
134 nametbl = malloc (namesz);
135 if (nametbl == NULL)
136 {
926c9e76 137 errmsg = N_("ctf_arc_write(): error writing named CTF to archive");
9402cc59
NA
138 goto err_unmap;
139 }
140
141 for (i = 0, namesz = 0,
142 modent = (ctf_archive_modent_t *) ((char *) archdr
143 + sizeof (struct ctf_archive));
139633c3 144 i < le64toh (archdr->ctfa_ndicts); i++)
9402cc59
NA
145 {
146 off_t off;
147
148 strcpy (&nametbl[namesz], names[i]);
149
139633c3 150 off = arc_write_one_ctf (ctf_dicts[i], fd, threshold);
9402cc59
NA
151 if ((off < 0) && (off > -ECTF_BASE))
152 {
926c9e76
NA
153 errmsg = N_("ctf_arc_write(): cannot determine file "
154 "position while writing to archive");
9402cc59
NA
155 goto err_free;
156 }
157 if (off < 0)
158 {
926c9e76 159 errmsg = N_("ctf_arc_write(): cannot write CTF file to archive");
9402cc59
NA
160 errno = off * -1;
161 goto err_free;
162 }
163
164 modent->name_offset = htole64 (namesz);
165 modent->ctf_offset = htole64 (off - ctf_startoffs);
166 namesz += strlen (names[i]) + 1;
167 modent++;
168 }
169
6b22174f
NA
170 ctf_qsort_r ((ctf_archive_modent_t *) ((char *) archdr
171 + sizeof (struct ctf_archive)),
139633c3 172 le64toh (archdr->ctfa_ndicts),
6b22174f
NA
173 sizeof (struct ctf_archive_modent), sort_modent_by_name,
174 nametbl);
9402cc59
NA
175
176 /* Now the name table. */
177
178 if ((nameoffs = lseek (fd, 0, SEEK_CUR)) < 0)
179 {
926c9e76
NA
180 errmsg = N_("ctf_arc_write(): cannot get current file position "
181 "in archive");
9402cc59
NA
182 goto err_free;
183 }
184 archdr->ctfa_names = htole64 (nameoffs);
185 np = nametbl;
186 while (namesz > 0)
187 {
188 ssize_t len;
189 if ((len = write (fd, np, namesz)) < 0)
190 {
926c9e76 191 errmsg = N_("ctf_arc_write(): cannot write name table to archive");
9402cc59
NA
192 goto err_free;
193 }
194 namesz -= len;
195 np += len;
196 }
197 free (nametbl);
198
199 if (arc_mmap_writeout (fd, archdr, headersz, &errmsg) < 0)
200 goto err_unmap;
201 if (arc_mmap_unmap (archdr, headersz, &errmsg) < 0)
5537f9b9 202 goto err;
9402cc59
NA
203 return 0;
204
205err_free:
206 free (nametbl);
207err_unmap:
208 arc_mmap_unmap (archdr, headersz, NULL);
9402cc59 209err:
926c9e76
NA
210 /* We report errors into the first file in the archive, if any: if this is a
211 zero-file archive, put it in the open-errors stream for lack of anywhere
212 else for it to go. */
139633c3 213 ctf_err_warn (ctf_dict_cnt > 0 ? ctf_dicts[0] : NULL, 0, errno, "%s",
926c9e76 214 gettext (errmsg));
9402cc59
NA
215 return errno;
216}
217
139633c3
NA
218/* Write out a CTF archive. The entries in CTF_DICTS are referenced by name:
219 the names are passed in the names array, which must have CTF_DICTS entries.
5537f9b9
NA
220
221 If the filename is NULL, create a temporary file and return a pointer to it.
222
223 Returns 0 on success, or an errno, or an ECTF_* value. */
224int
139633c3 225ctf_arc_write (const char *file, ctf_dict_t **ctf_dicts, size_t ctf_dict_cnt,
5537f9b9
NA
226 const char **names, size_t threshold)
227{
228 int err;
229 int fd;
230
231 if ((fd = open (file, O_RDWR | O_CREAT | O_TRUNC | O_CLOEXEC, 0666)) < 0)
232 {
139633c3 233 ctf_err_warn (ctf_dict_cnt > 0 ? ctf_dicts[0] : NULL, 0, errno,
926c9e76 234 _("ctf_arc_write(): cannot create %s"), file);
5537f9b9
NA
235 return errno;
236 }
237
139633c3 238 err = ctf_arc_write_fd (fd, ctf_dicts, ctf_dict_cnt, names, threshold);
5537f9b9 239 if (err)
df16e041 240 goto err_close;
5537f9b9
NA
241
242 if ((err = close (fd)) < 0)
139633c3 243 ctf_err_warn (ctf_dict_cnt > 0 ? ctf_dicts[0] : NULL, 0, errno,
926c9e76 244 _("ctf_arc_write(): cannot close after writing to archive"));
df16e041 245 goto err;
5537f9b9
NA
246
247 err_close:
df16e041
NC
248 (void) close (fd);
249 err:
5537f9b9
NA
250 if (err < 0)
251 unlink (file);
252
253 return err;
254}
255
9402cc59
NA
256/* Write one CTF file out. Return the file position of the written file (or
257 rather, of the file-size uint64_t that precedes it): negative return is a
258 negative errno or ctf_errno value. On error, the file position may no longer
259 be at the end of the file. */
260static off_t
139633c3 261arc_write_one_ctf (ctf_dict_t * f, int fd, size_t threshold)
9402cc59
NA
262{
263 off_t off, end_off;
264 uint64_t ctfsz = 0;
265 char *ctfszp;
266 size_t ctfsz_len;
139633c3 267 int (*writefn) (ctf_dict_t * fp, int fd);
9402cc59 268
676c3ecb
NA
269 if (ctf_serialize (f) < 0)
270 return f->ctf_errno * -1;
271
9402cc59
NA
272 if ((off = lseek (fd, 0, SEEK_CUR)) < 0)
273 return errno * -1;
274
275 if (f->ctf_size > threshold)
276 writefn = ctf_compress_write;
277 else
278 writefn = ctf_write;
279
280 /* This zero-write turns into the size in a moment. */
281 ctfsz_len = sizeof (ctfsz);
282 ctfszp = (char *) &ctfsz;
283 while (ctfsz_len > 0)
284 {
285 ssize_t writelen = write (fd, ctfszp, ctfsz_len);
286 if (writelen < 0)
287 return errno * -1;
288 ctfsz_len -= writelen;
289 ctfszp += writelen;
290 }
291
292 if (writefn (f, fd) != 0)
293 return f->ctf_errno * -1;
294
295 if ((end_off = lseek (fd, 0, SEEK_CUR)) < 0)
296 return errno * -1;
297 ctfsz = htole64 (end_off - off);
298
299 if ((lseek (fd, off, SEEK_SET)) < 0)
300 return errno * -1;
301
302 /* ... here. */
303 ctfsz_len = sizeof (ctfsz);
304 ctfszp = (char *) &ctfsz;
305 while (ctfsz_len > 0)
306 {
307 ssize_t writelen = write (fd, ctfszp, ctfsz_len);
308 if (writelen < 0)
309 return errno * -1;
310 ctfsz_len -= writelen;
311 ctfszp += writelen;
312 }
313
314 end_off = LCTF_ALIGN_OFFS (end_off, 8);
315 if ((lseek (fd, end_off, SEEK_SET)) < 0)
316 return errno * -1;
317
318 return off;
319}
320
321/* qsort() function to sort the array of struct ctf_archive_modents into
322 ascending name order. */
323static int
324sort_modent_by_name (const void *one, const void *two, void *n)
325{
326 const struct ctf_archive_modent *a = one;
327 const struct ctf_archive_modent *b = two;
328 char *nametbl = n;
329
330 return strcmp (&nametbl[le64toh (a->name_offset)],
331 &nametbl[le64toh (b->name_offset)]);
332}
333
2e428e74 334/* bsearch_r() function to search for a given name in the sorted array of struct
9402cc59
NA
335 ctf_archive_modents. */
336static int
2e428e74 337search_modent_by_name (const void *key, const void *ent, void *arg)
9402cc59
NA
338{
339 const char *k = key;
340 const struct ctf_archive_modent *v = ent;
2e428e74 341 const char *search_nametbl = arg;
9402cc59
NA
342
343 return strcmp (k, &search_nametbl[le64toh (v->name_offset)]);
344}
345
2f6ecaed 346/* Make a new struct ctf_archive_internal wrapper for a ctf_archive or a
139633c3 347 ctf_dict. Closes ARC and/or FP on error. Arrange to free the SYMSECT or
601e455b 348 STRSECT, as needed, on close. Possibly do not unmap on close. */
2f6ecaed
NA
349
350struct ctf_archive_internal *
601e455b
NA
351ctf_new_archive_internal (int is_archive, int unmap_on_close,
352 struct ctf_archive *arc,
139633c3 353 ctf_dict_t *fp, const ctf_sect_t *symsect,
2f6ecaed
NA
354 const ctf_sect_t *strsect,
355 int *errp)
9402cc59 356{
2f6ecaed 357 struct ctf_archive_internal *arci;
9402cc59 358
2f6ecaed 359 if ((arci = calloc (1, sizeof (struct ctf_archive_internal))) == NULL)
9402cc59 360 {
2f6ecaed 361 if (is_archive)
601e455b
NA
362 {
363 if (unmap_on_close)
364 ctf_arc_close_internal (arc);
365 }
2f6ecaed 366 else
139633c3 367 ctf_dict_close (fp);
2f6ecaed 368 return (ctf_set_open_errno (errp, errno));
9402cc59 369 }
2f6ecaed
NA
370 arci->ctfi_is_archive = is_archive;
371 if (is_archive)
372 arci->ctfi_archive = arc;
373 else
139633c3 374 arci->ctfi_dict = fp;
2f6ecaed
NA
375 if (symsect)
376 memcpy (&arci->ctfi_symsect, symsect, sizeof (struct ctf_sect));
377 if (strsect)
378 memcpy (&arci->ctfi_strsect, strsect, sizeof (struct ctf_sect));
379 arci->ctfi_free_symsect = 0;
d50c0802 380 arci->ctfi_free_strsect = 0;
601e455b 381 arci->ctfi_unmap_on_close = unmap_on_close;
53651de8 382 arci->ctfi_symsect_little_endian = -1;
2f6ecaed
NA
383
384 return arci;
385}
386
53651de8
NA
387/* Set the symbol-table endianness of an archive (defaulting the symtab
388 endianness of all ctf_file_t's opened from that archive). */
389void
390ctf_arc_symsect_endianness (ctf_archive_t *arc, int little_endian)
391{
392 arc->ctfi_symsect_little_endian = !!little_endian;
393 if (!arc->ctfi_is_archive)
394 ctf_symsect_endianness (arc->ctfi_dict, arc->ctfi_symsect_little_endian);
395}
396
3d16b64e
NA
397/* Get the CTF preamble from data in a buffer, which may be either an archive or
398 a CTF dict. If multiple dicts are present in an archive, the preamble comes
399 from an arbitrary dict. The preamble is a pointer into the ctfsect passed
400 in. */
401
402const ctf_preamble_t *
403ctf_arc_bufpreamble (const ctf_sect_t *ctfsect)
404{
405 if (ctfsect->cts_size > sizeof (uint64_t) &&
406 (le64toh ((*(uint64_t *) ctfsect->cts_data)) == CTFA_MAGIC))
407 {
408 struct ctf_archive *arc = (struct ctf_archive *) ctfsect->cts_data;
409 return (const ctf_preamble_t *) ((char *) arc + le64toh (arc->ctfa_ctfs)
410 + sizeof (uint64_t));
411 }
412 else
413 return (const ctf_preamble_t *) ctfsect->cts_data;
414}
415
2f6ecaed
NA
416/* Open a CTF archive or dictionary from data in a buffer (which the caller must
417 preserve until ctf_arc_close() time). Returns the archive, or NULL and an
418 error in *err (if not NULL). */
419ctf_archive_t *
420ctf_arc_bufopen (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect,
421 const ctf_sect_t *strsect, int *errp)
422{
423 struct ctf_archive *arc = NULL;
424 int is_archive;
139633c3 425 ctf_dict_t *fp = NULL;
2f6ecaed
NA
426
427 if (ctfsect->cts_size > sizeof (uint64_t) &&
4533ed56 428 (le64toh ((*(uint64_t *) ctfsect->cts_data)) == CTFA_MAGIC))
2f6ecaed 429 {
601e455b
NA
430 /* The archive is mmappable, so this operation is trivial.
431
432 This buffer is nonmodifiable, so the trick involving mmapping only part
433 of it and storing the length in the magic number is not applicable: so
434 record this fact in the archive-wrapper header. (We cannot record it
435 in the archive, because the archive may very well be a read-only
436 mapping.) */
2f6ecaed
NA
437
438 is_archive = 1;
439 arc = (struct ctf_archive *) ctfsect->cts_data;
440 }
441 else
442 {
443 is_archive = 0;
444 if ((fp = ctf_bufopen (ctfsect, symsect, strsect, errp)) == NULL)
445 {
926c9e76 446 ctf_err_warn (NULL, 0, *errp, _("ctf_arc_bufopen(): cannot open CTF"));
2f6ecaed
NA
447 return NULL;
448 }
449 }
601e455b 450 return ctf_new_archive_internal (is_archive, 0, arc, fp, symsect, strsect,
2f6ecaed 451 errp);
9402cc59
NA
452}
453
454/* Open a CTF archive. Returns the archive, or NULL and an error in *err (if
455 not NULL). */
456struct ctf_archive *
457ctf_arc_open_internal (const char *filename, int *errp)
458{
459 const char *errmsg;
460 int fd;
461 struct stat s;
462 struct ctf_archive *arc; /* (Actually the whole file.) */
463
464 libctf_init_debug();
465 if ((fd = open (filename, O_RDONLY)) < 0)
466 {
926c9e76 467 errmsg = N_("ctf_arc_open(): cannot open %s");
9402cc59
NA
468 goto err;
469 }
470 if (fstat (fd, &s) < 0)
471 {
926c9e76 472 errmsg = N_("ctf_arc_open(): cannot stat %s");
9402cc59
NA
473 goto err_close;
474 }
475
476 if ((arc = arc_mmap_file (fd, s.st_size)) == NULL)
477 {
926c9e76 478 errmsg = N_("ctf_arc_open(): cannot read in %s");
9402cc59
NA
479 goto err_close;
480 }
481
482 if (le64toh (arc->ctfa_magic) != CTFA_MAGIC)
483 {
926c9e76 484 errmsg = N_("ctf_arc_open(): %s: invalid magic number");
9402cc59
NA
485 errno = ECTF_FMT;
486 goto err_unmap;
487 }
488
489 /* This horrible hack lets us know how much to unmap when the file is
490 closed. (We no longer need the magic number, and the mapping
491 is private.) */
492 arc->ctfa_magic = s.st_size;
493 close (fd);
494 return arc;
495
496err_unmap:
497 arc_mmap_unmap (arc, s.st_size, NULL);
498err_close:
499 close (fd);
500err:
501 if (errp)
502 *errp = errno;
926c9e76 503 ctf_err_warn (NULL, 0, errno, gettext (errmsg), filename);
9402cc59
NA
504 return NULL;
505}
506
507/* Close an archive. */
508void
509ctf_arc_close_internal (struct ctf_archive *arc)
510{
511 if (arc == NULL)
512 return;
513
514 /* See the comment in ctf_arc_open(). */
515 arc_mmap_unmap (arc, arc->ctfa_magic, NULL);
516}
517
518/* Public entry point: close an archive, or CTF file. */
519void
520ctf_arc_close (ctf_archive_t *arc)
521{
522 if (arc == NULL)
523 return;
524
525 if (arc->ctfi_is_archive)
601e455b
NA
526 {
527 if (arc->ctfi_unmap_on_close)
528 ctf_arc_close_internal (arc->ctfi_archive);
529 }
9402cc59 530 else
139633c3 531 ctf_dict_close (arc->ctfi_dict);
2c78e925 532 free (arc->ctfi_symdicts);
f4f60336 533 free (arc->ctfi_symnamedicts);
2c78e925 534 ctf_dynhash_destroy (arc->ctfi_dicts);
2f6ecaed
NA
535 if (arc->ctfi_free_symsect)
536 free ((void *) arc->ctfi_symsect.cts_data);
d50c0802
NA
537 if (arc->ctfi_free_strsect)
538 free ((void *) arc->ctfi_strsect.cts_data);
9402cc59 539 free (arc->ctfi_data);
f046147d
NA
540 if (arc->ctfi_bfd_close)
541 arc->ctfi_bfd_close (arc);
9402cc59
NA
542 free (arc);
543}
544
139633c3 545/* Return the ctf_dict_t with the given name, or NULL if none, setting 'err' if
9402cc59 546 non-NULL. A name of NULL means to open the default file. */
139633c3 547static ctf_dict_t *
ae41200b
NA
548ctf_dict_open_internal (const struct ctf_archive *arc,
549 const ctf_sect_t *symsect,
550 const ctf_sect_t *strsect,
53651de8
NA
551 const char *name, int little_endian,
552 int *errp)
9402cc59
NA
553{
554 struct ctf_archive_modent *modent;
2e428e74 555 const char *search_nametbl;
9402cc59
NA
556
557 if (name == NULL)
558 name = _CTF_SECTION; /* The default name. */
559
ae41200b 560 ctf_dprintf ("ctf_dict_open_internal(%s): opening\n", name);
9402cc59
NA
561
562 modent = (ctf_archive_modent_t *) ((char *) arc
563 + sizeof (struct ctf_archive));
564
2e428e74 565 search_nametbl = (const char *) arc + le64toh (arc->ctfa_names);
139633c3 566 modent = bsearch_r (name, modent, le64toh (arc->ctfa_ndicts),
2e428e74
NA
567 sizeof (struct ctf_archive_modent),
568 search_modent_by_name, (void *) search_nametbl);
9402cc59
NA
569
570 /* This is actually a common case and normal operation: no error
571 debug output. */
572 if (modent == NULL)
573 {
574 if (errp)
575 *errp = ECTF_ARNNAME;
576 return NULL;
577 }
578
ae41200b 579 return ctf_dict_open_by_offset (arc, symsect, strsect,
53651de8
NA
580 le64toh (modent->ctf_offset),
581 little_endian, errp);
9402cc59
NA
582}
583
139633c3 584/* Return the ctf_dict_t with the given name, or NULL if none, setting 'err' if
9402cc59
NA
585 non-NULL. A name of NULL means to open the default file.
586
587 Use the specified string and symbol table sections.
588
589 Public entry point. */
139633c3 590ctf_dict_t *
ae41200b
NA
591ctf_dict_open_sections (const ctf_archive_t *arc,
592 const ctf_sect_t *symsect,
593 const ctf_sect_t *strsect,
594 const char *name,
595 int *errp)
9402cc59
NA
596{
597 if (arc->ctfi_is_archive)
598 {
139633c3 599 ctf_dict_t *ret;
ae41200b 600 ret = ctf_dict_open_internal (arc->ctfi_archive, symsect, strsect,
53651de8
NA
601 name, arc->ctfi_symsect_little_endian,
602 errp);
9402cc59 603 if (ret)
2c78e925
NA
604 {
605 ret->ctf_archive = (ctf_archive_t *) arc;
606 ctf_arc_import_parent (arc, ret);
607 }
9402cc59
NA
608 return ret;
609 }
610
611 if ((name != NULL) && (strcmp (name, _CTF_SECTION) != 0))
612 {
613 if (errp)
614 *errp = ECTF_ARNNAME;
615 return NULL;
616 }
139633c3 617 arc->ctfi_dict->ctf_archive = (ctf_archive_t *) arc;
9402cc59 618
139633c3
NA
619 /* Bump the refcount so that the user can ctf_dict_close() it. */
620 arc->ctfi_dict->ctf_refcnt++;
621 return arc->ctfi_dict;
9402cc59
NA
622}
623
139633c3 624/* Return the ctf_dict_t with the given name, or NULL if none, setting 'err' if
9402cc59
NA
625 non-NULL. A name of NULL means to open the default file.
626
627 Public entry point. */
139633c3 628ctf_dict_t *
ae41200b 629ctf_dict_open (const ctf_archive_t *arc, const char *name, int *errp)
9402cc59
NA
630{
631 const ctf_sect_t *symsect = &arc->ctfi_symsect;
632 const ctf_sect_t *strsect = &arc->ctfi_strsect;
633
634 if (symsect->cts_name == NULL)
635 symsect = NULL;
636 if (strsect->cts_name == NULL)
637 strsect = NULL;
638
ae41200b 639 return ctf_dict_open_sections (arc, symsect, strsect, name, errp);
9402cc59
NA
640}
641
2c78e925
NA
642static void
643ctf_cached_dict_close (void *fp)
644{
645 ctf_dict_close ((ctf_dict_t *) fp);
646}
647
f4f60336
NA
648/* Return the ctf_dict_t with the given name and cache it in the archive's
649 ctfi_dicts. If this is the first cached dict, designate it the
650 crossdict_cache. */
2c78e925
NA
651static ctf_dict_t *
652ctf_dict_open_cached (ctf_archive_t *arc, const char *name, int *errp)
653{
654 ctf_dict_t *fp;
655 char *dupname;
656
657 /* Just return from the cache if possible. */
658 if (arc->ctfi_dicts
659 && ((fp = ctf_dynhash_lookup (arc->ctfi_dicts, name)) != NULL))
660 {
661 fp->ctf_refcnt++;
662 return fp;
663 }
664
665 /* Not yet cached: open it. */
666 fp = ctf_dict_open (arc, name, errp);
667 dupname = strdup (name);
668
669 if (!fp || !dupname)
670 goto oom;
671
672 if (arc->ctfi_dicts == NULL)
673 if ((arc->ctfi_dicts
674 = ctf_dynhash_create (ctf_hash_string, ctf_hash_eq_string,
675 free, ctf_cached_dict_close)) == NULL)
676 goto oom;
677
678 if (ctf_dynhash_insert (arc->ctfi_dicts, dupname, fp) < 0)
679 goto oom;
680 fp->ctf_refcnt++;
681
f4f60336
NA
682 if (arc->ctfi_crossdict_cache == NULL)
683 arc->ctfi_crossdict_cache = fp;
684
2c78e925
NA
685 return fp;
686
687 oom:
688 ctf_dict_close (fp);
689 free (dupname);
690 if (errp)
691 *errp = ENOMEM;
692 return NULL;
693}
694
695/* Flush any caches the CTF archive may have open. */
696void
697ctf_arc_flush_caches (ctf_archive_t *wrapper)
698{
699 free (wrapper->ctfi_symdicts);
f4f60336 700 free (wrapper->ctfi_symnamedicts);
2c78e925
NA
701 ctf_dynhash_destroy (wrapper->ctfi_dicts);
702 wrapper->ctfi_symdicts = NULL;
f4f60336 703 wrapper->ctfi_symnamedicts = NULL;
2c78e925 704 wrapper->ctfi_dicts = NULL;
f4f60336 705 wrapper->ctfi_crossdict_cache = NULL;
2c78e925
NA
706}
707
139633c3 708/* Return the ctf_dict_t at the given ctfa_ctfs-relative offset, or NULL if
9402cc59 709 none, setting 'err' if non-NULL. */
139633c3 710static ctf_dict_t *
ae41200b
NA
711ctf_dict_open_by_offset (const struct ctf_archive *arc,
712 const ctf_sect_t *symsect,
713 const ctf_sect_t *strsect, size_t offset,
53651de8 714 int little_endian, int *errp)
9402cc59
NA
715{
716 ctf_sect_t ctfsect;
139633c3 717 ctf_dict_t *fp;
9402cc59 718
ae41200b 719 ctf_dprintf ("ctf_dict_open_by_offset(%lu): opening\n", (unsigned long) offset);
9402cc59 720
a0486bac 721 memset (&ctfsect, 0, sizeof (ctf_sect_t));
9402cc59
NA
722
723 offset += le64toh (arc->ctfa_ctfs);
724
725 ctfsect.cts_name = _CTF_SECTION;
9402cc59
NA
726 ctfsect.cts_size = le64toh (*((uint64_t *) ((char *) arc + offset)));
727 ctfsect.cts_entsize = 1;
9402cc59
NA
728 ctfsect.cts_data = (void *) ((char *) arc + offset + sizeof (uint64_t));
729 fp = ctf_bufopen (&ctfsect, symsect, strsect, errp);
730 if (fp)
53651de8
NA
731 {
732 ctf_setmodel (fp, le64toh (arc->ctfa_model));
733 if (little_endian >= 0)
734 ctf_symsect_endianness (fp, little_endian);
735 }
9402cc59
NA
736 return fp;
737}
738
ae41200b
NA
739/* Backward compatibility. */
740ctf_dict_t *
741ctf_arc_open_by_name (const ctf_archive_t *arc, const char *name,
742 int *errp)
743{
744 return ctf_dict_open (arc, name, errp);
745}
746
747ctf_dict_t *
748ctf_arc_open_by_name_sections (const ctf_archive_t *arc,
749 const ctf_sect_t *symsect,
750 const ctf_sect_t *strsect,
751 const char *name,
752 int *errp)
753{
754 return ctf_dict_open_sections (arc, symsect, strsect, name, errp);
755}
756
2c78e925
NA
757/* Import the parent into a ctf archive, if this is a child, the parent is not
758 already set, and a suitable archive member exists. No error is raised if
759 this is not possible: this is just a best-effort helper operation to give
760 people useful dicts to start with. */
761static void
762ctf_arc_import_parent (const ctf_archive_t *arc, ctf_dict_t *fp)
763{
764 if ((fp->ctf_flags & LCTF_CHILD) && fp->ctf_parname && !fp->ctf_parent)
765 {
766 ctf_dict_t *parent = ctf_dict_open_cached ((ctf_archive_t *) arc,
767 fp->ctf_parname, NULL);
768 if (parent)
769 {
770 ctf_import (fp, parent);
771 ctf_dict_close (parent);
772 }
773 }
774}
775
9c23dfa5
NA
776/* Return the number of members in an archive. */
777size_t
778ctf_archive_count (const ctf_archive_t *wrapper)
779{
780 if (!wrapper->ctfi_is_archive)
781 return 1;
782
139633c3 783 return wrapper->ctfi_archive->ctfa_ndicts;
9c23dfa5
NA
784}
785
f4f60336
NA
786/* Look up a symbol in an archive by name or index (if the name is set, a lookup
787 by name is done). Return the dict in the archive that the symbol is found
788 in, and (optionally) the ctf_id_t of the symbol in that dict (so you don't
789 have to look it up yourself). The dict is cached, so repeated lookups are
790 nearly free.
2c78e925
NA
791
792 As usual, you should ctf_dict_close() the returned dict once you are done
793 with it.
794
795 Returns NULL on error, and an error in errp (if set). */
796
f4f60336
NA
797static ctf_dict_t *
798ctf_arc_lookup_sym_or_name (ctf_archive_t *wrapper, unsigned long symidx,
799 const char *symname, ctf_id_t *typep, int *errp)
2c78e925
NA
800{
801 ctf_dict_t *fp;
f4f60336 802 void *fpkey;
2c78e925
NA
803 ctf_id_t type;
804
805 /* The usual non-archive-transparent-wrapper special case. */
806 if (!wrapper->ctfi_is_archive)
807 {
f4f60336 808 if (!symname)
2c78e925 809 {
f4f60336
NA
810 if ((type = ctf_lookup_by_symbol (wrapper->ctfi_dict, symidx)) == CTF_ERR)
811 {
812 if (errp)
813 *errp = ctf_errno (wrapper->ctfi_dict);
814 return NULL;
815 }
816 }
817 else
818 {
819 if ((type = ctf_lookup_by_symbol_name (wrapper->ctfi_dict,
820 symname)) == CTF_ERR)
821 {
822 if (errp)
823 *errp = ctf_errno (wrapper->ctfi_dict);
824 return NULL;
825 }
2c78e925
NA
826 }
827 if (typep)
828 *typep = type;
829 wrapper->ctfi_dict->ctf_refcnt++;
830 return wrapper->ctfi_dict;
831 }
832
833 if (wrapper->ctfi_symsect.cts_name == NULL
834 || wrapper->ctfi_symsect.cts_data == NULL
835 || wrapper->ctfi_symsect.cts_size == 0
836 || wrapper->ctfi_symsect.cts_entsize == 0)
837 {
838 if (errp)
839 *errp = ECTF_NOSYMTAB;
840 return NULL;
841 }
842
f4f60336
NA
843 /* Make enough space for all possible symbol indexes, if not already done. We
844 cache the originating dictionary of all symbols. The dict links are weak,
845 to the dictionaries cached in ctfi_dicts: their refcnts are *not* bumped.
846 We also cache similar mappings for symbol names: these are ordinary
847 dynhashes, with weak links to dicts. */
2c78e925 848
f4f60336 849 if (!wrapper->ctfi_symdicts)
2c78e925 850 {
f4f60336
NA
851 if ((wrapper->ctfi_symdicts = calloc (wrapper->ctfi_symsect.cts_size
852 / wrapper->ctfi_symsect.cts_entsize,
853 sizeof (ctf_dict_t *))) == NULL)
2c78e925
NA
854 {
855 if (errp)
856 *errp = ENOMEM;
857 return NULL;
858 }
859 }
f4f60336 860 if (!wrapper->ctfi_symnamedicts)
2c78e925 861 {
f4f60336
NA
862 if ((wrapper->ctfi_symnamedicts = ctf_dynhash_create (ctf_hash_string,
863 ctf_hash_eq_string,
864 free, NULL)) == NULL)
2c78e925
NA
865 {
866 if (errp)
867 *errp = ENOMEM;
868 return NULL;
869 }
870 }
871
f4f60336
NA
872 /* Perhaps the dict in which we found a previous lookup is cached. If it's
873 supposed to be cached but we don't find it, pretend it was always not
874 found: this should never happen, but shouldn't be allowed to cause trouble
875 if it does. */
876
877 if ((symname && ctf_dynhash_lookup_kv (wrapper->ctfi_symnamedicts,
878 symname, NULL, &fpkey))
879 || (!symname && wrapper->ctfi_symdicts[symidx] != NULL))
2c78e925 880 {
f4f60336
NA
881 if (symname)
882 fp = (ctf_dict_t *) fpkey;
883 else
884 fp = wrapper->ctfi_symdicts[symidx];
885
886 if (fp == &enosym)
887 goto no_sym;
888
889 if (symname)
2c78e925 890 {
f4f60336
NA
891 if ((type = ctf_lookup_by_symbol_name (fp, symname)) == CTF_ERR)
892 goto cache_no_sym;
893 }
894 else
895 {
896 if ((type = ctf_lookup_by_symbol (fp, symidx)) == CTF_ERR)
897 goto cache_no_sym;
2c78e925
NA
898 }
899
900 if (typep)
f4f60336
NA
901 *typep = type;
902 fp->ctf_refcnt++;
903 return fp;
2c78e925
NA
904 }
905
906 /* Not cached: find it and cache it. We must track open errors ourselves even
907 if our caller doesn't, to be able to distinguish no-error end-of-iteration
908 from open errors. */
909
910 int local_err;
911 int *local_errp;
912 ctf_next_t *i = NULL;
913 const char *name;
914
915 if (errp)
916 local_errp = errp;
917 else
918 local_errp = &local_err;
919
920 while ((fp = ctf_archive_next (wrapper, &i, &name, 0, local_errp)) != NULL)
921 {
f4f60336 922 if (!symname)
2c78e925 923 {
f4f60336
NA
924 if ((type = ctf_lookup_by_symbol (fp, symidx)) != CTF_ERR)
925 wrapper->ctfi_symdicts[symidx] = fp;
926 }
927 else
928 {
929 if ((type = ctf_lookup_by_symbol_name (fp, symname)) != CTF_ERR)
930 {
931 char *tmp;
932 /* No error checking, as above. */
933 if ((tmp = strdup (symname)) != NULL)
934 ctf_dynhash_insert (wrapper->ctfi_symnamedicts, tmp, fp);
935 }
936 }
2c78e925 937
f4f60336
NA
938 if (type != CTF_ERR)
939 {
2c78e925
NA
940 if (typep)
941 *typep = type;
f4f60336 942 ctf_next_destroy (i);
2c78e925
NA
943 return fp;
944 }
f4f60336
NA
945 if (ctf_errno (fp) != ECTF_NOTYPEDAT)
946 {
947 if (errp)
948 *errp = ctf_errno (fp);
949 ctf_next_destroy (i);
950 return NULL; /* errno is set for us. */
951 }
2c78e925
NA
952 ctf_dict_close (fp);
953 }
954 if (*local_errp != ECTF_NEXT_END)
955 {
956 ctf_next_destroy (i);
957 return NULL;
958 }
f4f60336 959
2c78e925
NA
960 /* Don't leak end-of-iteration to the caller. */
961 *local_errp = 0;
962
f4f60336
NA
963 cache_no_sym:
964 if (!symname)
965 wrapper->ctfi_symdicts[symidx] = &enosym;
966 else
967 {
968 char *tmp;
969
970 /* No error checking: if caching fails, there is only a slight performance
971 impact. */
972 if ((tmp = strdup (symname)) != NULL)
973 if (ctf_dynhash_insert (wrapper->ctfi_symnamedicts, tmp, &enosym) < 0)
974 free (tmp);
975 }
2c78e925 976
f4f60336 977 no_sym:
2c78e925
NA
978 if (errp)
979 *errp = ECTF_NOTYPEDAT;
980 if (typep)
981 *typep = CTF_ERR;
982 return NULL;
983}
984
f4f60336
NA
985/* The public API for looking up a symbol by index. */
986ctf_dict_t *
987ctf_arc_lookup_symbol (ctf_archive_t *wrapper, unsigned long symidx,
988 ctf_id_t *typep, int *errp)
989{
990 return ctf_arc_lookup_sym_or_name (wrapper, symidx, NULL, typep, errp);
991}
992
993/* The public API for looking up a symbol by name. */
994
995ctf_dict_t *
996ctf_arc_lookup_symbol_name (ctf_archive_t *wrapper, const char *symname,
997 ctf_id_t *typep, int *errp)
998{
999 return ctf_arc_lookup_sym_or_name (wrapper, 0, symname, typep, errp);
1000}
1001
9402cc59
NA
1002/* Raw iteration over all CTF files in an archive. We pass the raw data for all
1003 CTF files in turn to the specified callback function. */
1004static int
1005ctf_archive_raw_iter_internal (const struct ctf_archive *arc,
1006 ctf_archive_raw_member_f *func, void *data)
1007{
1008 int rc;
1009 size_t i;
1010 struct ctf_archive_modent *modent;
1011 const char *nametbl;
1012
1013 modent = (ctf_archive_modent_t *) ((char *) arc
1014 + sizeof (struct ctf_archive));
1015 nametbl = (((const char *) arc) + le64toh (arc->ctfa_names));
1016
139633c3 1017 for (i = 0; i < le64toh (arc->ctfa_ndicts); i++)
9402cc59
NA
1018 {
1019 const char *name;
1020 char *fp;
1021
1022 name = &nametbl[le64toh (modent[i].name_offset)];
1023 fp = ((char *) arc + le64toh (arc->ctfa_ctfs)
1024 + le64toh (modent[i].ctf_offset));
1025
1026 if ((rc = func (name, (void *) (fp + sizeof (uint64_t)),
1027 le64toh (*((uint64_t *) fp)), data)) != 0)
1028 return rc;
1029 }
1030 return 0;
1031}
1032
1033/* Raw iteration over all CTF files in an archive: public entry point.
1034
1035 Returns -EINVAL if not supported for this sort of archive. */
1036int
1037ctf_archive_raw_iter (const ctf_archive_t *arc,
1038 ctf_archive_raw_member_f * func, void *data)
1039{
1040 if (arc->ctfi_is_archive)
1041 return ctf_archive_raw_iter_internal (arc->ctfi_archive, func, data);
1042
1043 return -EINVAL; /* Not supported. */
1044}
1045
ac36e134
NA
1046/* Iterate over all CTF files in an archive: public entry point. We pass all
1047 CTF files in turn to the specified callback function. */
1048int
1049ctf_archive_iter (const ctf_archive_t *arc, ctf_archive_member_f *func,
1050 void *data)
9402cc59 1051{
ac36e134
NA
1052 ctf_next_t *i = NULL;
1053 ctf_dict_t *fp;
1054 const char *name;
1055 int err;
9402cc59 1056
ac36e134 1057 while ((fp = ctf_archive_next (arc, &i, &name, 0, &err)) != NULL)
9402cc59 1058 {
ac36e134 1059 int rc;
9402cc59 1060
ac36e134 1061 if ((rc = func (fp, name, data)) != 0)
9402cc59 1062 {
ac36e134
NA
1063 ctf_dict_close (fp);
1064 ctf_next_destroy (i);
9402cc59
NA
1065 return rc;
1066 }
ac36e134 1067 ctf_dict_close (fp);
9402cc59
NA
1068 }
1069 return 0;
1070}
1071
688d28f6 1072/* Iterate over all CTF files in an archive, returning each dict in turn as a
139633c3 1073 ctf_dict_t, and NULL on error or end of iteration. It is the caller's
8769046e 1074 responsibility to close it. Parent dicts may be skipped.
688d28f6 1075
2c78e925
NA
1076 The archive member is cached for rapid return on future calls.
1077
688d28f6
NA
1078 We identify parents by name rather than by flag value: for now, with the
1079 linker only emitting parents named _CTF_SECTION, this works well enough. */
1080
139633c3 1081ctf_dict_t *
688d28f6
NA
1082ctf_archive_next (const ctf_archive_t *wrapper, ctf_next_t **it, const char **name,
1083 int skip_parent, int *errp)
1084{
139633c3 1085 ctf_dict_t *f;
688d28f6
NA
1086 ctf_next_t *i = *it;
1087 struct ctf_archive *arc;
1088 struct ctf_archive_modent *modent;
1089 const char *nametbl;
1090 const char *name_;
1091
1092 if (!i)
1093 {
1094 if ((i = ctf_next_create()) == NULL)
1095 {
1096 if (errp)
1097 *errp = ENOMEM;
1098 return NULL;
1099 }
1100 i->cu.ctn_arc = wrapper;
1101 i->ctn_iter_fun = (void (*) (void)) ctf_archive_next;
1102 *it = i;
1103 }
1104
1105 if ((void (*) (void)) ctf_archive_next != i->ctn_iter_fun)
1106 {
1107 if (errp)
1108 *errp = ECTF_NEXT_WRONGFUN;
1109 return NULL;
1110 }
1111
1112 if (wrapper != i->cu.ctn_arc)
1113 {
1114 if (errp)
1115 *errp = ECTF_NEXT_WRONGFP;
1116 return NULL;
1117 }
1118
139633c3 1119 /* Iteration is made a bit more complex by the need to handle ctf_dict_t's
688d28f6
NA
1120 transparently wrapped in a single-member archive. These are parents: if
1121 skip_parent is on, they are skipped and the iterator terminates
1122 immediately. */
1123
1124 if (!wrapper->ctfi_is_archive && i->ctn_n == 0)
1125 {
1126 i->ctn_n++;
1127 if (!skip_parent)
1128 {
139633c3 1129 wrapper->ctfi_dict->ctf_refcnt++;
eaa2913a
NA
1130 if (name)
1131 *name = _CTF_SECTION;
139633c3 1132 return wrapper->ctfi_dict;
688d28f6
NA
1133 }
1134 }
1135
1136 arc = wrapper->ctfi_archive;
1137
1138 /* The loop keeps going when skip_parent is on as long as the member we find
1139 is the parent (i.e. at most two iterations, but possibly an early return if
1140 *all* we have is a parent). */
1141
688d28f6
NA
1142 do
1143 {
139633c3 1144 if ((!wrapper->ctfi_is_archive) || (i->ctn_n >= le64toh (arc->ctfa_ndicts)))
688d28f6
NA
1145 {
1146 ctf_next_destroy (i);
1147 *it = NULL;
1148 if (errp)
1149 *errp = ECTF_NEXT_END;
1150 return NULL;
1151 }
1152
688d28f6
NA
1153 modent = (ctf_archive_modent_t *) ((char *) arc
1154 + sizeof (struct ctf_archive));
1155 nametbl = (((const char *) arc) + le64toh (arc->ctfa_names));
1156
1157 name_ = &nametbl[le64toh (modent[i->ctn_n].name_offset)];
1158 i->ctn_n++;
eefe721e
NA
1159 }
1160 while (skip_parent && strcmp (name_, _CTF_SECTION) == 0);
688d28f6
NA
1161
1162 if (name)
1163 *name = name_;
1164
2c78e925 1165 f = ctf_dict_open_cached ((ctf_archive_t *) wrapper, name_, errp);
688d28f6
NA
1166 return f;
1167}
1168
9402cc59
NA
1169#ifdef HAVE_MMAP
1170/* Map the header in. Only used on new, empty files. */
1171static void *arc_mmap_header (int fd, size_t headersz)
1172{
1173 void *hdr;
1174 if ((hdr = mmap (NULL, headersz, PROT_READ | PROT_WRITE, MAP_SHARED, fd,
1175 0)) == MAP_FAILED)
1176 return NULL;
1177 return hdr;
1178}
1179
1180/* mmap() the whole file, for reading only. (Map it writably, but privately: we
1181 need to modify the region, but don't need anyone else to see the
1182 modifications.) */
1183static void *arc_mmap_file (int fd, size_t size)
1184{
1185 void *arc;
1186 if ((arc = mmap (NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE,
1187 fd, 0)) == MAP_FAILED)
1188 return NULL;
1189 return arc;
1190}
1191
1192/* Persist the header to disk. */
1193static int arc_mmap_writeout (int fd _libctf_unused_, void *header,
1194 size_t headersz, const char **errmsg)
1195{
1196 if (msync (header, headersz, MS_ASYNC) < 0)
1197 {
1198 if (errmsg)
926c9e76
NA
1199 *errmsg = N_("arc_mmap_writeout(): cannot sync after writing "
1200 "to %s: %s");
9402cc59
NA
1201 return -1;
1202 }
1203 return 0;
1204}
1205
1206/* Unmap the region. */
1207static int arc_mmap_unmap (void *header, size_t headersz, const char **errmsg)
1208{
1209 if (munmap (header, headersz) < 0)
1210 {
1211 if (errmsg)
926c9e76
NA
1212 *errmsg = N_("arc_mmap_munmap(): cannot unmap after writing "
1213 "to %s: %s");
9402cc59
NA
1214 return -1;
1215 }
1216 return 0;
1217}
1218#else
1219/* Map the header in. Only used on new, empty files. */
f5e73be1 1220static void *arc_mmap_header (int fd _libctf_unused_, size_t headersz)
9402cc59
NA
1221{
1222 void *hdr;
1223 if ((hdr = malloc (headersz)) == NULL)
1224 return NULL;
1225 return hdr;
1226}
1227
1228/* Pull in the whole file, for reading only. We assume the current file
1229 position is at the start of the file. */
1230static void *arc_mmap_file (int fd, size_t size)
1231{
1232 char *data;
1233
1234 if ((data = malloc (size)) == NULL)
1235 return NULL;
1236
1237 if (ctf_pread (fd, data, size, 0) < 0)
1238 {
1239 free (data);
1240 return NULL;
1241 }
1242 return data;
1243}
1244
1245/* Persist the header to disk. */
1246static int arc_mmap_writeout (int fd, void *header, size_t headersz,
1247 const char **errmsg)
1248{
1249 ssize_t len;
1250 size_t acc = 0;
1251 char *data = (char *) header;
1252 ssize_t count = headersz;
1253
1254 if ((lseek (fd, 0, SEEK_SET)) < 0)
1255 {
1256 if (errmsg)
926c9e76
NA
1257 *errmsg = N_("arc_mmap_writeout(): cannot seek while writing header to "
1258 "%s: %s");
9402cc59
NA
1259 return -1;
1260 }
1261
1262 while (headersz > 0)
1263 {
1264 if ((len = write (fd, data, count)) < 0)
1265 {
1266 if (errmsg)
926c9e76 1267 *errmsg = N_("arc_mmap_writeout(): cannot write header to %s: %s");
9402cc59
NA
1268 return len;
1269 }
1270 if (len == EINTR)
1271 continue;
1272
1273 acc += len;
1274 if (len == 0) /* EOF. */
1275 break;
1276
1277 count -= len;
1278 data += len;
1279 }
1280 return 0;
1281}
1282
1283/* Unmap the region. */
1284static int arc_mmap_unmap (void *header, size_t headersz _libctf_unused_,
1285 const char **errmsg _libctf_unused_)
1286{
1287 free (header);
1288 return 0;
1289}
1290#endif