1 /* Labelled ranges of type IDs.
2 Copyright (C) 2019 Free Software Foundation, Inc.
4 This file is part of libctf.
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
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.
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/>. */
24 extract_label_info (ctf_file_t
*fp
, const ctf_lblent_t
**ctl
,
27 const ctf_header_t
*h
;
29 h
= (const ctf_header_t
*) fp
->ctf_data
.cts_data
;
31 *ctl
= (const ctf_lblent_t
*) (fp
->ctf_buf
+ h
->cth_lbloff
);
32 *num_labels
= (h
->cth_objtoff
- h
->cth_lbloff
) / sizeof (ctf_lblent_t
);
37 /* Returns the topmost label, or NULL if any errors are encountered. */
40 ctf_label_topmost (ctf_file_t
*fp
)
42 const ctf_lblent_t
*ctlp
= NULL
;
44 uint32_t num_labels
= 0;
46 if (extract_label_info (fp
, &ctlp
, &num_labels
) < 0)
47 return NULL
; /* errno is set for us. */
51 (void) ctf_set_errno (fp
, ECTF_NOLABELDATA
);
55 if ((s
= ctf_strraw (fp
, (ctlp
+ num_labels
- 1)->ctl_label
)) == NULL
)
56 (void) ctf_set_errno (fp
, ECTF_CORRUPT
);
61 /* Iterate over all labels. We pass the label string and the lblinfo_t struct
62 to the specified callback function. */
64 ctf_label_iter (ctf_file_t
*fp
, ctf_label_f
*func
, void *arg
)
66 const ctf_lblent_t
*ctlp
= NULL
;
68 uint32_t num_labels
= 0;
73 if (extract_label_info (fp
, &ctlp
, &num_labels
) < 0)
74 return -1; /* errno is set for us. */
77 return (ctf_set_errno (fp
, ECTF_NOLABELDATA
));
79 for (i
= 0; i
< num_labels
; i
++, ctlp
++)
81 if ((lname
= ctf_strraw (fp
, ctlp
->ctl_label
)) == NULL
)
83 ctf_dprintf ("failed to decode label %u with "
84 "type %u\n", ctlp
->ctl_label
, ctlp
->ctl_type
);
85 return (ctf_set_errno (fp
, ECTF_CORRUPT
));
88 linfo
.ctb_type
= ctlp
->ctl_type
;
89 if ((rc
= func (lname
, &linfo
, arg
)) != 0)
96 typedef struct linfo_cb_arg
98 const char *lca_name
; /* Label we want to retrieve info for. */
99 ctf_lblinfo_t
*lca_info
; /* Where to store the info about the label. */
103 label_info_cb (const char *lname
, const ctf_lblinfo_t
*linfo
, void *arg
)
105 /* If lname matches the label we are looking for, copy the
106 lblinfo_t struct for the caller. */
108 if (strcmp (lname
, ((linfo_cb_arg_t
*) arg
)->lca_name
) == 0)
110 /* * Allow caller not to allocate storage to test if label exists. */
112 if (((linfo_cb_arg_t
*) arg
)->lca_info
!= NULL
)
113 memcpy (((linfo_cb_arg_t
*) arg
)->lca_info
, linfo
,
114 sizeof (ctf_lblinfo_t
));
115 return 1; /* Indicate we found a match. */
121 /* Retrieve information about the label with name "lname". */
123 ctf_label_info (ctf_file_t
*fp
, const char *lname
, ctf_lblinfo_t
*linfo
)
125 linfo_cb_arg_t cb_arg
;
128 cb_arg
.lca_name
= lname
;
129 cb_arg
.lca_info
= linfo
;
131 if ((rc
= ctf_label_iter (fp
, label_info_cb
, &cb_arg
)) < 0)
135 return (ctf_set_errno (fp
, ECTF_NOLABEL
));