blob: 3c38431c78a45c02cd3d2db34f881f5029b61b84 [file] [log] [blame]
Mike Frysingerecb1dc82009-05-20 04:35:14 -04001/*
2 * Helper functions for working with the builtin symbol table
3 *
4 * Copyright (c) 2008-2009 Analog Devices Inc.
5 * Licensed under the GPL-2 or later.
6 */
7
8#include <common.h>
9
Bo Lv53277dd2023-04-17 13:34:32 +080010#if (IS_ENABLED(CONFIG_KALLSYMS))
11#include <asm/sections.h>
12#include <asm/global_data.h>
13DECLARE_GLOBAL_DATA_PTR;
14#endif
15
Mike Frysingerecb1dc82009-05-20 04:35:14 -040016/* We need the weak marking as this symbol is provided specially */
17extern const char system_map[] __attribute__((weak));
18
19/* Given an address, return a pointer to the symbol name and store
20 * the base address in caddr. So if the symbol map had an entry:
21 * 03fb9b7c_spi_cs_deactivate
22 * Then the following call:
23 * unsigned long base;
24 * const char *sym = symbol_lookup(0x03fb9b80, &base);
25 * Would end up setting the variables like so:
26 * base = 0x03fb9b7c;
27 * sym = "_spi_cs_deactivate";
28 */
Bo Lv53277dd2023-04-17 13:34:32 +080029#if (IS_ENABLED(CONFIG_KALLSYMS))
30const char *symbol_lookup(unsigned long addr, unsigned long *caddr, unsigned long *naddr)
31{
32 const char *sym, *csym;
33 unsigned long sym_addr;
Bo Lv96a66d02023-05-12 19:18:22 +080034 char sym_addr_tmp[17] = {0}; /* 17 bytes to avoid overflow */
Bo Lv53277dd2023-04-17 13:34:32 +080035 unsigned long text_start;
36 unsigned long text_end;
37
38 sym = system_map;
39 csym = NULL;
40 *caddr = 0;
41 *naddr = 0;
42 text_start = (ulong)&__image_copy_start - gd->reloc_off;
43 text_end = (ulong)&__rodata_start - gd->reloc_off;
44
45 /*
46 * within text section?
47 */
48 if (addr < text_start || addr > text_end)
49 return NULL;
50
51 while (*sym) {
52 memcpy(sym_addr_tmp, sym, 16);
53 sym_addr = simple_strtoul(sym_addr_tmp, NULL, 16);
54 sym = sym + 16;
55 if (sym_addr > addr) {
56 *naddr = sym_addr;
57 break;
58 }
59 *caddr = sym_addr;
60 csym = sym;
61 sym += strlen(sym) + 1;
62 }
63 /*
64 * the last symbol?
65 */
66 if (*sym == 0x00)
67 *naddr = text_end;
68
69 return csym;
70}
71#else
Mike Frysingerecb1dc82009-05-20 04:35:14 -040072const char *symbol_lookup(unsigned long addr, unsigned long *caddr)
73{
74 const char *sym, *csym;
75 char *esym;
76 unsigned long sym_addr;
77
78 sym = system_map;
79 csym = NULL;
80 *caddr = 0;
81
82 while (*sym) {
Simon Glass7e5f4602021-07-24 09:03:29 -060083 sym_addr = hextoul(sym, &esym);
Mike Frysingerecb1dc82009-05-20 04:35:14 -040084 sym = esym;
85 if (sym_addr > addr)
86 break;
87 *caddr = sym_addr;
88 csym = sym;
89 sym += strlen(sym) + 1;
90 }
91
92 return csym;
93}
Bo Lv53277dd2023-04-17 13:34:32 +080094#endif