Coverage Report

Created: 2025-06-24 06:45

/src/binutils-gdb/libctf/ctf-labels.c
Line
Count
Source (jump to first uncovered line)
1
/* Labelled ranges of type IDs.
2
   Copyright (C) 2019-2025 Free Software Foundation, Inc.
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 <string.h>
22
23
static int
24
extract_label_info (ctf_dict_t *fp, const ctf_lblent_t **ctl,
25
        uint32_t *num_labels)
26
0
{
27
0
  const ctf_header_t *h;
28
29
0
  h = (const ctf_header_t *) fp->ctf_data.cts_data;
30
31
0
  *ctl = (const ctf_lblent_t *) (fp->ctf_buf + h->cth_lbloff);
32
0
  *num_labels = (h->cth_objtoff - h->cth_lbloff) / sizeof (ctf_lblent_t);
33
34
0
  return 0;
35
0
}
36
37
/* Returns the topmost label, or NULL if any errors are encountered.  */
38
39
const char *
40
ctf_label_topmost (ctf_dict_t *fp)
41
0
{
42
0
  const ctf_lblent_t *ctlp = NULL;
43
0
  const char *s;
44
0
  uint32_t num_labels = 0;
45
46
0
  if (extract_label_info (fp, &ctlp, &num_labels) < 0)
47
0
    return NULL;       /* errno is set for us.  */
48
49
0
  if (num_labels == 0)
50
0
    {
51
0
      (void) ctf_set_errno (fp, ECTF_NOLABELDATA);
52
0
      return NULL;
53
0
    }
54
55
0
  if ((s = ctf_strraw (fp, (ctlp + num_labels - 1)->ctl_label)) == NULL)
56
0
    (void) ctf_set_errno (fp, ECTF_CORRUPT);
57
58
0
  return s;
59
0
}
60
61
/* Iterate over all labels.  We pass the label string and the lblinfo_t struct
62
   to the specified callback function.  */
63
int
64
ctf_label_iter (ctf_dict_t *fp, ctf_label_f *func, void *arg)
65
0
{
66
0
  const ctf_lblent_t *ctlp = NULL;
67
0
  uint32_t i;
68
0
  uint32_t num_labels = 0;
69
0
  ctf_lblinfo_t linfo;
70
0
  const char *lname;
71
0
  int rc;
72
73
0
  if (extract_label_info (fp, &ctlp, &num_labels) < 0)
74
0
    return -1;     /* errno is set for us.  */
75
76
0
  if (num_labels == 0)
77
0
    return (ctf_set_errno (fp, ECTF_NOLABELDATA));
78
79
0
  for (i = 0; i < num_labels; i++, ctlp++)
80
0
    {
81
0
      if ((lname = ctf_strraw (fp, ctlp->ctl_label)) == NULL)
82
0
  {
83
    /* Not marked for translation: label code not used yet.  */
84
0
    ctf_err_warn (fp, 0, ECTF_CORRUPT,
85
0
      "failed to decode label %u with type %u",
86
0
      ctlp->ctl_label, ctlp->ctl_type);
87
0
    return (ctf_set_errno (fp, ECTF_CORRUPT));
88
0
  }
89
90
0
      linfo.ctb_type = ctlp->ctl_type;
91
0
      if ((rc = func (lname, &linfo, arg)) != 0)
92
0
  return rc;
93
0
    }
94
95
0
  return 0;
96
0
}
97
98
typedef struct linfo_cb_arg
99
{
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.  */
102
} linfo_cb_arg_t;
103
104
static int
105
label_info_cb (const char *lname, const ctf_lblinfo_t *linfo, void *arg)
106
0
{
107
  /* If lname matches the label we are looking for, copy the
108
    lblinfo_t struct for the caller.  */
109
110
0
  if (strcmp (lname, ((linfo_cb_arg_t *) arg)->lca_name) == 0)
111
0
    {
112
      /* * Allow caller not to allocate storage to test if label exists.  */
113
114
0
      if (((linfo_cb_arg_t *) arg)->lca_info != NULL)
115
0
  memcpy (((linfo_cb_arg_t *) arg)->lca_info, linfo,
116
0
         sizeof (ctf_lblinfo_t));
117
0
      return 1;   /* Indicate we found a match.  */
118
0
    }
119
120
0
  return 0;
121
0
}
122
123
/* Retrieve information about the label with name "lname". */
124
int
125
ctf_label_info (ctf_dict_t *fp, const char *lname, ctf_lblinfo_t *linfo)
126
0
{
127
0
  linfo_cb_arg_t cb_arg;
128
0
  int rc;
129
130
0
  cb_arg.lca_name = lname;
131
0
  cb_arg.lca_info = linfo;
132
133
0
  if ((rc = ctf_label_iter (fp, label_info_cb, &cb_arg)) < 0)
134
0
    return rc;
135
136
0
  if (rc != 1)
137
0
    return (ctf_set_errno (fp, ECTF_NOLABEL));
138
139
0
  return 0;
140
0
}