18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci#include <elf.h>
38c2ecf20Sopenharmony_ci#include <inttypes.h>
48c2ecf20Sopenharmony_ci#include <stdio.h>
58c2ecf20Sopenharmony_ci
68c2ecf20Sopenharmony_ci#include "dso.h"
78c2ecf20Sopenharmony_ci#include "map.h"
88c2ecf20Sopenharmony_ci#include "symbol.h"
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_cisize_t symbol__fprintf(struct symbol *sym, FILE *fp)
118c2ecf20Sopenharmony_ci{
128c2ecf20Sopenharmony_ci	return fprintf(fp, " %" PRIx64 "-%" PRIx64 " %c %s\n",
138c2ecf20Sopenharmony_ci		       sym->start, sym->end,
148c2ecf20Sopenharmony_ci		       sym->binding == STB_GLOBAL ? 'g' :
158c2ecf20Sopenharmony_ci		       sym->binding == STB_LOCAL  ? 'l' : 'w',
168c2ecf20Sopenharmony_ci		       sym->name);
178c2ecf20Sopenharmony_ci}
188c2ecf20Sopenharmony_ci
198c2ecf20Sopenharmony_cisize_t __symbol__fprintf_symname_offs(const struct symbol *sym,
208c2ecf20Sopenharmony_ci				      const struct addr_location *al,
218c2ecf20Sopenharmony_ci				      bool unknown_as_addr,
228c2ecf20Sopenharmony_ci				      bool print_offsets, FILE *fp)
238c2ecf20Sopenharmony_ci{
248c2ecf20Sopenharmony_ci	unsigned long offset;
258c2ecf20Sopenharmony_ci	size_t length;
268c2ecf20Sopenharmony_ci
278c2ecf20Sopenharmony_ci	if (sym) {
288c2ecf20Sopenharmony_ci		length = fprintf(fp, "%s", sym->name);
298c2ecf20Sopenharmony_ci		if (al && print_offsets) {
308c2ecf20Sopenharmony_ci			if (al->addr < sym->end)
318c2ecf20Sopenharmony_ci				offset = al->addr - sym->start;
328c2ecf20Sopenharmony_ci			else
338c2ecf20Sopenharmony_ci				offset = al->addr - al->map->start - sym->start;
348c2ecf20Sopenharmony_ci			length += fprintf(fp, "+0x%lx", offset);
358c2ecf20Sopenharmony_ci		}
368c2ecf20Sopenharmony_ci		return length;
378c2ecf20Sopenharmony_ci	} else if (al && unknown_as_addr)
388c2ecf20Sopenharmony_ci		return fprintf(fp, "[%#" PRIx64 "]", al->addr);
398c2ecf20Sopenharmony_ci	else
408c2ecf20Sopenharmony_ci		return fprintf(fp, "[unknown]");
418c2ecf20Sopenharmony_ci}
428c2ecf20Sopenharmony_ci
438c2ecf20Sopenharmony_cisize_t symbol__fprintf_symname_offs(const struct symbol *sym,
448c2ecf20Sopenharmony_ci				    const struct addr_location *al,
458c2ecf20Sopenharmony_ci				    FILE *fp)
468c2ecf20Sopenharmony_ci{
478c2ecf20Sopenharmony_ci	return __symbol__fprintf_symname_offs(sym, al, false, true, fp);
488c2ecf20Sopenharmony_ci}
498c2ecf20Sopenharmony_ci
508c2ecf20Sopenharmony_cisize_t __symbol__fprintf_symname(const struct symbol *sym,
518c2ecf20Sopenharmony_ci				 const struct addr_location *al,
528c2ecf20Sopenharmony_ci				 bool unknown_as_addr, FILE *fp)
538c2ecf20Sopenharmony_ci{
548c2ecf20Sopenharmony_ci	return __symbol__fprintf_symname_offs(sym, al, unknown_as_addr, false, fp);
558c2ecf20Sopenharmony_ci}
568c2ecf20Sopenharmony_ci
578c2ecf20Sopenharmony_cisize_t symbol__fprintf_symname(const struct symbol *sym, FILE *fp)
588c2ecf20Sopenharmony_ci{
598c2ecf20Sopenharmony_ci	return __symbol__fprintf_symname_offs(sym, NULL, false, false, fp);
608c2ecf20Sopenharmony_ci}
618c2ecf20Sopenharmony_ci
628c2ecf20Sopenharmony_cisize_t dso__fprintf_symbols_by_name(struct dso *dso,
638c2ecf20Sopenharmony_ci				    FILE *fp)
648c2ecf20Sopenharmony_ci{
658c2ecf20Sopenharmony_ci	size_t ret = 0;
668c2ecf20Sopenharmony_ci	struct rb_node *nd;
678c2ecf20Sopenharmony_ci	struct symbol_name_rb_node *pos;
688c2ecf20Sopenharmony_ci
698c2ecf20Sopenharmony_ci	for (nd = rb_first_cached(&dso->symbol_names); nd; nd = rb_next(nd)) {
708c2ecf20Sopenharmony_ci		pos = rb_entry(nd, struct symbol_name_rb_node, rb_node);
718c2ecf20Sopenharmony_ci		ret += fprintf(fp, "%s\n", pos->sym.name);
728c2ecf20Sopenharmony_ci	}
738c2ecf20Sopenharmony_ci
748c2ecf20Sopenharmony_ci	return ret;
758c2ecf20Sopenharmony_ci}
76