162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci#include <elf.h>
362306a36Sopenharmony_ci#include <inttypes.h>
462306a36Sopenharmony_ci#include <stdio.h>
562306a36Sopenharmony_ci
662306a36Sopenharmony_ci#include "dso.h"
762306a36Sopenharmony_ci#include "map.h"
862306a36Sopenharmony_ci#include "symbol.h"
962306a36Sopenharmony_ci
1062306a36Sopenharmony_cisize_t symbol__fprintf(struct symbol *sym, FILE *fp)
1162306a36Sopenharmony_ci{
1262306a36Sopenharmony_ci	return fprintf(fp, " %" PRIx64 "-%" PRIx64 " %c %s\n",
1362306a36Sopenharmony_ci		       sym->start, sym->end,
1462306a36Sopenharmony_ci		       sym->binding == STB_GLOBAL ? 'g' :
1562306a36Sopenharmony_ci		       sym->binding == STB_LOCAL  ? 'l' : 'w',
1662306a36Sopenharmony_ci		       sym->name);
1762306a36Sopenharmony_ci}
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_cisize_t __symbol__fprintf_symname_offs(const struct symbol *sym,
2062306a36Sopenharmony_ci				      const struct addr_location *al,
2162306a36Sopenharmony_ci				      bool unknown_as_addr,
2262306a36Sopenharmony_ci				      bool print_offsets, FILE *fp)
2362306a36Sopenharmony_ci{
2462306a36Sopenharmony_ci	unsigned long offset;
2562306a36Sopenharmony_ci	size_t length;
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ci	if (sym) {
2862306a36Sopenharmony_ci		length = fprintf(fp, "%s", sym->name);
2962306a36Sopenharmony_ci		if (al && print_offsets) {
3062306a36Sopenharmony_ci			if (al->addr < sym->end)
3162306a36Sopenharmony_ci				offset = al->addr - sym->start;
3262306a36Sopenharmony_ci			else
3362306a36Sopenharmony_ci				offset = al->addr - map__start(al->map) - sym->start;
3462306a36Sopenharmony_ci			length += fprintf(fp, "+0x%lx", offset);
3562306a36Sopenharmony_ci		}
3662306a36Sopenharmony_ci		return length;
3762306a36Sopenharmony_ci	} else if (al && unknown_as_addr)
3862306a36Sopenharmony_ci		return fprintf(fp, "[%#" PRIx64 "]", al->addr);
3962306a36Sopenharmony_ci	else
4062306a36Sopenharmony_ci		return fprintf(fp, "[unknown]");
4162306a36Sopenharmony_ci}
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_cisize_t symbol__fprintf_symname_offs(const struct symbol *sym,
4462306a36Sopenharmony_ci				    const struct addr_location *al,
4562306a36Sopenharmony_ci				    FILE *fp)
4662306a36Sopenharmony_ci{
4762306a36Sopenharmony_ci	return __symbol__fprintf_symname_offs(sym, al, false, true, fp);
4862306a36Sopenharmony_ci}
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_cisize_t __symbol__fprintf_symname(const struct symbol *sym,
5162306a36Sopenharmony_ci				 const struct addr_location *al,
5262306a36Sopenharmony_ci				 bool unknown_as_addr, FILE *fp)
5362306a36Sopenharmony_ci{
5462306a36Sopenharmony_ci	return __symbol__fprintf_symname_offs(sym, al, unknown_as_addr, false, fp);
5562306a36Sopenharmony_ci}
5662306a36Sopenharmony_ci
5762306a36Sopenharmony_cisize_t symbol__fprintf_symname(const struct symbol *sym, FILE *fp)
5862306a36Sopenharmony_ci{
5962306a36Sopenharmony_ci	return __symbol__fprintf_symname_offs(sym, NULL, false, false, fp);
6062306a36Sopenharmony_ci}
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_cisize_t dso__fprintf_symbols_by_name(struct dso *dso,
6362306a36Sopenharmony_ci				    FILE *fp)
6462306a36Sopenharmony_ci{
6562306a36Sopenharmony_ci	size_t ret = 0;
6662306a36Sopenharmony_ci
6762306a36Sopenharmony_ci	for (size_t i = 0; i < dso->symbol_names_len; i++) {
6862306a36Sopenharmony_ci		struct symbol *pos = dso->symbol_names[i];
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_ci		ret += fprintf(fp, "%s\n", pos->name);
7162306a36Sopenharmony_ci	}
7262306a36Sopenharmony_ci	return ret;
7362306a36Sopenharmony_ci}
74