1 /* Labelled ranges of type IDs.
2 Copyright (C) 2019-2021 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_dict_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_dict_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_dict_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 /* Not marked for translation: label code not used yet. */
84 ctf_err_warn (fp
, 0, ECTF_CORRUPT
,
85 "failed to decode label %u with type %u",
86 ctlp
->ctl_label
, ctlp
->ctl_type
);
87 return (ctf_set_errno (fp
, ECTF_CORRUPT
));
90 linfo
.ctb_type
= ctlp
->ctl_type
;
91 if ((rc
= func (lname
, &linfo
, arg
)) != 0)
98 typedef struct linfo_cb_arg
100 const char *lca_name
; /* Label we want to retrieve info for. */
101 ctf_lblinfo_t
*lca_info
; /* Where to store the info about the label. */
105 label_info_cb (const char *lname
, const ctf_lblinfo_t
*linfo
, void *arg
)
107 /* If lname matches the label we are looking for, copy the
108 lblinfo_t struct for the caller. */
110 if (strcmp (lname
, ((linfo_cb_arg_t
*) arg
)->lca_name
) == 0)
112 /* * Allow caller not to allocate storage to test if label exists. */
114 if (((linfo_cb_arg_t
*) arg
)->lca_info
!= NULL
)
115 memcpy (((linfo_cb_arg_t
*) arg
)->lca_info
, linfo
,
116 sizeof (ctf_lblinfo_t
));
117 return 1; /* Indicate we found a match. */
123 /* Retrieve information about the label with name "lname". */
125 ctf_label_info (ctf_dict_t
*fp
, const char *lname
, ctf_lblinfo_t
*linfo
)
127 linfo_cb_arg_t cb_arg
;
130 cb_arg
.lca_name
= lname
;
131 cb_arg
.lca_info
= linfo
;
133 if ((rc
= ctf_label_iter (fp
, label_info_cb
, &cb_arg
)) < 0)
137 return (ctf_set_errno (fp
, ECTF_NOLABEL
));