diff --git a/ctf_encoder.c b/ctf_encoder.c index 3cb455a..b761287 100644 --- a/ctf_encoder.c +++ b/ctf_encoder.c @@ -248,7 +248,7 @@ int cu__encode_ctf(struct cu *cu, int verbose) if (cu__cache_symtab(cu) < 0) goto out_delete; - ctf__set_strings(ctf, &strings->gb); + ctf__set_strings(ctf, strings); uint32_t id; struct tag *pos; diff --git a/dwarf_loader.c b/dwarf_loader.c index ac5d070..2e55031 100644 --- a/dwarf_loader.c +++ b/dwarf_loader.c @@ -2159,7 +2159,7 @@ static unsigned long long dwarf_tag__orig_id(const struct tag *tag, static const char *dwarf__strings_ptr(const struct cu *cu __unused, strings_t s) { - return strings__ptr(strings, s); + return s ? strings__ptr(strings, s) : NULL; } struct debug_fmt_ops dwarf__ops; diff --git a/libctf.c b/libctf.c index b7d237f..2de3912 100644 --- a/libctf.c +++ b/libctf.c @@ -19,6 +19,7 @@ #include "ctf.h" #include "dutil.h" #include "gobuffer.h" +#include "pahole_strings.h" bool ctf__ignore_symtab_function(const GElf_Sym *sym, const char *sym_name) { @@ -287,7 +288,7 @@ int ctf__load_symtab(struct ctf *ctf) return ctf->symtab == NULL ? -1 : 0; } -void ctf__set_strings(struct ctf *ctf, struct gobuffer *strings) +void ctf__set_strings(struct ctf *ctf, struct strings *strings) { ctf->strings = strings; } @@ -570,7 +571,7 @@ int ctf__encode(struct ctf *ctf, uint8_t flags) size = (gobuffer__size(&ctf->types) + gobuffer__size(&ctf->objects) + gobuffer__size(&ctf->funcs) + - gobuffer__size(ctf->strings)); + strings__size(ctf->strings)); ctf->size = sizeof(*hdr) + size; ctf->buf = malloc(ctf->size); @@ -594,13 +595,13 @@ int ctf__encode(struct ctf *ctf, uint8_t flags) hdr->ctf_type_off = offset; offset += gobuffer__size(&ctf->types); hdr->ctf_str_off = offset; - hdr->ctf_str_len = gobuffer__size(ctf->strings); + hdr->ctf_str_len = strings__size(ctf->strings); void *payload = ctf->buf + sizeof(*hdr); gobuffer__copy(&ctf->objects, payload + hdr->ctf_object_off); gobuffer__copy(&ctf->funcs, payload + hdr->ctf_func_off); gobuffer__copy(&ctf->types, payload + hdr->ctf_type_off); - gobuffer__copy(ctf->strings, payload + hdr->ctf_str_off); + strings__copy(ctf->strings, payload + hdr->ctf_str_off); *(char *)(ctf->buf + sizeof(*hdr) + hdr->ctf_str_off) = '\0'; if (flags & CTF_FLAGS_COMPR) { @@ -623,11 +624,10 @@ int ctf__encode(struct ctf *ctf, uint8_t flags) } #if 0 printf("\n\ntypes:\n entries: %d\n size: %u" - "\nstrings:\n entries: %u\n size: %u\ncompressed size: %d\n", + "\nstrings:\n size: %u\ncompressed size: %d\n", ctf->type_index, gobuffer__size(&ctf->types), - gobuffer__nr_entries(ctf->strings), - gobuffer__size(ctf->strings), size); + strings__size(ctf->strings), size); #endif int fd = open(ctf->filename, O_RDWR); if (fd < 0) { diff --git a/libctf.h b/libctf.h index 071616c..749be89 100644 --- a/libctf.h +++ b/libctf.h @@ -24,7 +24,7 @@ struct ctf { struct gobuffer objects; /* data/variables */ struct gobuffer types; struct gobuffer funcs; - struct gobuffer *strings; + struct strings *strings; char *filename; size_t size; int swapped; @@ -76,7 +76,7 @@ int ctf__add_function(struct ctf *ctf, uint16_t type, uint16_t nr_parms, int ctf__add_object(struct ctf *ctf, uint16_t type); -void ctf__set_strings(struct ctf *ctf, struct gobuffer *strings); +void ctf__set_strings(struct ctf *ctf, struct strings *strings); int ctf__encode(struct ctf *ctf, uint8_t flags); char *ctf__string(struct ctf *ctf, uint32_t ref); diff --git a/pahole_strings.h b/pahole_strings.h index 01f50ef..522fbf2 100644 --- a/pahole_strings.h +++ b/pahole_strings.h @@ -6,13 +6,12 @@ Copyright (C) 2008 Arnaldo Carvalho de Melo */ -#include "gobuffer.h" +#include "lib/bpf/src/btf.h" typedef unsigned int strings_t; struct strings { - void *tree; - struct gobuffer gb; + struct btf *btf; }; struct strings *strings__new(void); @@ -21,33 +20,12 @@ void strings__delete(struct strings *strings); strings_t strings__add(struct strings *strings, const char *str); strings_t strings__find(struct strings *strings, const char *str); - -int strings__cmp(const struct strings *strings, strings_t a, strings_t b); +strings_t strings__size(const struct strings *strings); +int strings__copy(const struct strings *strings, void *dst); static inline const char *strings__ptr(const struct strings *strings, strings_t s) { - return gobuffer__ptr(&strings->gb, s); -} - -static inline const char *strings__entries(const struct strings *strings) -{ - return gobuffer__entries(&strings->gb); -} - -static inline unsigned int strings__nr_entries(const struct strings *strings) -{ - return gobuffer__nr_entries(&strings->gb); -} - -static inline strings_t strings__size(const struct strings *strings) -{ - return gobuffer__size(&strings->gb); -} - -static inline const char *strings__compress(struct strings *strings, - unsigned int *size) -{ - return gobuffer__compress(&strings->gb, size); + return btf__str_by_offset(strings->btf, s); } #endif /* _STRINGS_H_ */ diff --git a/strings.c b/strings.c index fd74fda..d37f49d 100644 --- a/strings.c +++ b/strings.c @@ -15,75 +15,41 @@ #include #include "dutil.h" +#include "lib/bpf/src/libbpf.h" struct strings *strings__new(void) { struct strings *strs = malloc(sizeof(*strs)); - if (strs != NULL) { - strs->tree = NULL; - gobuffer__init(&strs->gb); + if (!strs) + return NULL; + + strs->btf = btf__new_empty(); + if (libbpf_get_error(strs->btf)) { + free(strs); + return NULL; } return strs; - -} - -static void do_nothing(void *ptr __unused) -{ } void strings__delete(struct strings *strs) { if (strs == NULL) return; - tdestroy(strs->tree, do_nothing); - __gobuffer__delete(&strs->gb); + btf__free(strs->btf); free(strs); } -static strings_t strings__insert(struct strings *strs, const char *s) -{ - return gobuffer__add(&strs->gb, s, strlen(s) + 1); -} - -struct search_key { - struct strings *strs; - const char *str; -}; - -static int strings__compare(const void *a, const void *b) -{ - const struct search_key *key = a; - - return strcmp(key->str, key->strs->gb.entries + (unsigned long)b); -} - strings_t strings__add(struct strings *strs, const char *str) { - unsigned long *s; strings_t index; - struct search_key key = { - .strs = strs, - .str = str, - }; if (str == NULL) return 0; - s = tsearch(&key, &strs->tree, strings__compare); - if (s != NULL) { - if (*(struct search_key **)s == (void *)&key) { /* Not found, replace with the right key */ - index = strings__insert(strs, str); - if (index != 0) - *s = (unsigned long)index; - else { - tdelete(&key, &strs->tree, strings__compare); - return 0; - } - } else /* Found! */ - index = *s; - } else + index = btf__add_str(strs->btf, str); + if (index < 0) return 0; return index; @@ -91,21 +57,32 @@ strings_t strings__add(struct strings *strs, const char *str) strings_t strings__find(struct strings *strs, const char *str) { - strings_t *s; - struct search_key key = { - .strs = strs, - .str = str, - }; - - if (str == NULL) - return 0; - - s = tfind(&key, &strs->tree, strings__compare); - return s ? *s : 0; + return btf__find_str(strs->btf, str); } -int strings__cmp(const struct strings *strs, strings_t a, strings_t b) +/* a horrible and inefficient hack to get string section size out of BTF */ +strings_t strings__size(const struct strings *strs) { - return a == b ? 0 : strcmp(strings__ptr(strs, a), - strings__ptr(strs, b)); + const struct btf_header *p; + uint32_t sz; + + p = btf__get_raw_data(strs->btf, &sz); + if (!p) + return -1; + + return p->str_len; +} + +/* similarly horrible hack to copy out string section out of BTF */ +int strings__copy(const struct strings *strs, void *dst) +{ + const struct btf_header *p; + uint32_t sz; + + p = btf__get_raw_data(strs->btf, &sz); + if (!p) + return -1; + + memcpy(dst, (void *)p + p->str_off, p->str_len); + return 0; }