dwarf_loader: Use libdw__lock for dwarf_getlocation(s)
[dwarves.git] / dutil.c
blob14f134016add1f0c5a1f265b4a68b8a80c199ac5
1 /*
2 SPDX-License-Identifier: GPL-2.0-only
4 Copyright (C) 2007 Arnaldo Carvalho de Melo <acme@redhat.com>
5 */
8 #include "dutil.h"
10 #include <ctype.h>
11 #include <errno.h>
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
16 void *zalloc(size_t size)
18 return calloc(1, size);
21 void __zfree(void **ptr)
23 free(*ptr);
24 *ptr = NULL;
27 struct str_node *str_node__new(const char *s, bool dupstr)
29 struct str_node *snode = malloc(sizeof(*snode));
31 if (snode != NULL){
32 if (dupstr) {
33 s = strdup(s);
34 if (s == NULL)
35 goto out_delete;
37 snode->s = s;
40 return snode;
42 out_delete:
43 free(snode);
44 return NULL;
47 static void str_node__delete(struct str_node *snode, bool dupstr)
49 if (snode == NULL)
50 return;
52 if (dupstr)
53 zfree(&snode->s);
54 free(snode);
57 int __strlist__add(struct strlist *slist, const char *new_entry, void *priv)
59 struct rb_node **p = &slist->entries.rb_node;
60 struct rb_node *parent = NULL;
61 struct str_node *sn;
63 while (*p != NULL) {
64 int rc;
66 parent = *p;
67 sn = rb_entry(parent, struct str_node, rb_node);
68 rc = strcmp(sn->s, new_entry);
70 if (rc > 0)
71 p = &(*p)->rb_left;
72 else if (rc < 0)
73 p = &(*p)->rb_right;
74 else
75 return -EEXIST;
78 sn = str_node__new(new_entry, slist->dupstr);
79 if (sn == NULL)
80 return -ENOMEM;
82 rb_link_node(&sn->rb_node, parent, p);
83 rb_insert_color(&sn->rb_node, &slist->entries);
85 sn->priv = priv;
87 list_add_tail(&sn->node, &slist->list_entries);
89 return 0;
92 int strlist__add(struct strlist *slist, const char *new_entry)
94 return __strlist__add(slist, new_entry, NULL);
97 int strlist__load(struct strlist *slist, const char *filename)
99 char entry[1024];
100 int err = -1;
101 FILE *fp = fopen(filename, "r");
103 if (fp == NULL)
104 return -1;
106 while (fgets(entry, sizeof(entry), fp) != NULL) {
107 const size_t len = strlen(entry);
109 if (len == 0)
110 continue;
111 entry[len - 1] = '\0';
113 if (strlist__add(slist, entry) != 0)
114 goto out;
117 err = 0;
118 out:
119 fclose(fp);
120 return err;
123 struct strlist *strlist__new(bool dupstr)
125 struct strlist *slist = malloc(sizeof(*slist));
127 if (slist != NULL) {
128 slist->entries = RB_ROOT;
129 INIT_LIST_HEAD(&slist->list_entries);
130 slist->dupstr = dupstr;
133 return slist;
136 void strlist__delete(struct strlist *slist)
138 if (slist != NULL) {
139 struct str_node *pos;
140 struct rb_node *next = rb_first(&slist->entries);
142 while (next) {
143 pos = rb_entry(next, struct str_node, rb_node);
144 next = rb_next(&pos->rb_node);
145 strlist__remove(slist, pos);
147 slist->entries = RB_ROOT;
148 free(slist);
152 void strlist__remove(struct strlist *slist, struct str_node *sn)
154 rb_erase(&sn->rb_node, &slist->entries);
155 list_del_init(&sn->node);
156 str_node__delete(sn, slist->dupstr);
159 bool strlist__has_entry(struct strlist *slist, const char *entry)
161 struct rb_node **p = &slist->entries.rb_node;
162 struct rb_node *parent = NULL;
164 while (*p != NULL) {
165 struct str_node *sn;
166 int rc;
168 parent = *p;
169 sn = rb_entry(parent, struct str_node, rb_node);
170 rc = strcmp(sn->s, entry);
172 if (rc > 0)
173 p = &(*p)->rb_left;
174 else if (rc < 0)
175 p = &(*p)->rb_right;
176 else
177 return true;
180 return false;
183 Elf_Scn *elf_section_by_name(Elf *elf, GElf_Shdr *shp, const char *name, size_t *index)
185 Elf_Scn *sec = NULL;
186 size_t cnt = 1;
187 size_t str_idx;
189 if (elf_getshdrstrndx(elf, &str_idx))
190 return NULL;
192 while ((sec = elf_nextscn(elf, sec)) != NULL) {
193 char *str;
195 gelf_getshdr(sec, shp);
196 str = elf_strptr(elf, str_idx, shp->sh_name);
197 if (!str)
198 return NULL;
199 if (!strcmp(name, str)) {
200 if (index)
201 *index = cnt;
202 break;
204 ++cnt;
207 return sec;
210 Elf_Scn *elf_section_by_idx(Elf *elf, GElf_Shdr *shp, int idx, const char **name_out)
212 Elf_Scn *sec;
213 size_t str_idx;
215 sec = elf_getscn(elf, idx);
216 if (!sec)
217 return NULL;
218 if (!gelf_getshdr(sec, shp))
219 return NULL;
220 if (name_out) {
221 if (elf_getshdrstrndx(elf, &str_idx))
222 return NULL;
223 *name_out = elf_strptr(elf, str_idx, shp->sh_name);
225 return sec;
228 char *strlwr(char *s)
230 int len = strlen(s), i;
232 for (i = 0; i < len; ++i)
233 s[i] = tolower(s[i]);
235 return s;