1 /* Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 * Use of this source code is governed by a BSD-style license that can be
3 * found in the LICENSE file. */
5 /* XRay symbol table */
13 #if defined(__GLIBC__)
17 #include "xray/xray_priv.h"
18 #define PNACL_STRING_OFFSET (0x10000000)
22 bool g_symtable_debug
= false;
24 struct XRayFrameInfo
{
32 struct XRayFrameInfo frames
[XRAY_MAX_FRAMES
];
36 struct XRaySymbolPoolNode
{
37 struct XRaySymbolPoolNode
* next
;
38 struct XRaySymbol symbols
[XRAY_SYMBOL_POOL_NODE_SIZE
];
42 struct XRaySymbolPool
{
43 struct XRaySymbolPoolNode
* head
;
44 struct XRaySymbolPoolNode
* current
;
49 struct XRaySymbolTable
{
51 struct XRayHashTable
* hash_table
;
52 struct XRayStringPool
* string_pool
;
53 struct XRaySymbolPool
* symbol_pool
;
57 const char* XRaySymbolGetName(struct XRaySymbol
* symbol
) {
58 return (NULL
== symbol
) ? "(null)" : symbol
->name
;
62 struct XRaySymbol
* XRaySymbolCreate(struct XRaySymbolPool
* sympool
,
65 struct XRaySymbol
* symbol
;
66 symbol
= XRaySymbolPoolAlloc(sympool
);
72 struct XRaySymbol
* XRaySymbolPoolAlloc(struct XRaySymbolPool
* sympool
) {
73 struct XRaySymbol
* symbol
;
74 if (sympool
->index
>= XRAY_SYMBOL_POOL_NODE_SIZE
) {
75 struct XRaySymbolPoolNode
* new_pool
;
76 new_pool
= (struct XRaySymbolPoolNode
*)XRayMalloc(sizeof(*new_pool
));
77 sympool
->current
->next
= new_pool
;
78 sympool
->current
= new_pool
;
81 symbol
= &sympool
->current
->symbols
[sympool
->index
];
87 struct XRaySymbolPool
* XRaySymbolPoolCreate() {
88 struct XRaySymbolPool
* sympool
;
89 struct XRaySymbolPoolNode
* node
;
90 sympool
= (struct XRaySymbolPool
*)XRayMalloc(sizeof(*sympool
));
91 node
= (struct XRaySymbolPoolNode
*)XRayMalloc(sizeof(*node
));
93 sympool
->current
= node
;
99 void XRaySymbolPoolFree(struct XRaySymbolPool
* pool
) {
100 struct XRaySymbolPoolNode
* n
= pool
->head
;
102 struct XRaySymbolPoolNode
* c
= n
;
110 int XRaySymbolTableGetCount(struct XRaySymbolTable
* symtab
) {
111 return XRayHashTableGetCount(symtab
->hash_table
);
115 struct XRaySymbol
* XRaySymbolTableAtIndex(struct XRaySymbolTable
* symtab
,
117 return (struct XRaySymbol
*)XRayHashTableAtIndex(symtab
->hash_table
, i
);
120 struct XRaySymbol
* XRaySymbolTableAdd(struct XRaySymbolTable
* symtab
,
121 struct XRaySymbol
* symbol
,
123 struct XRaySymbol
* sym
= (struct XRaySymbol
*)
124 XRayHashTableInsert(symtab
->hash_table
, symbol
, addr
);
125 symtab
->num_symbols
= XRayHashTableGetCount(symtab
->hash_table
);
129 struct XRaySymbol
* XRaySymbolTableAddByName(struct XRaySymbolTable
* symtab
,
130 const char* name
, uint32_t addr
) {
132 struct XRaySymbol
* symbol
;
133 char buffer
[XRAY_LINE_SIZE
];
134 const char* demangled_name
= XRayDemangle(buffer
, XRAY_LINE_SIZE
, name
);
135 /* record the demangled symbol name into the string pool */
136 recorded_name
= XRayStringPoolAppend(symtab
->string_pool
, demangled_name
);
137 if (g_symtable_debug
)
138 printf("adding symbol %s\n", recorded_name
);
139 /* construct a symbol and put it in the symbol table */
140 symbol
= XRaySymbolCreate(symtab
->symbol_pool
, recorded_name
);
141 return XRaySymbolTableAdd(symtab
, symbol
, addr
);
144 struct XRaySymbol
* XRaySymbolTableLookup(struct XRaySymbolTable
* symtab
,
146 void *x
= XRayHashTableLookup(symtab
->hash_table
, addr
);
147 struct XRaySymbol
* r
= (struct XRaySymbol
*)x
;
149 #if defined(__pnacl__)
151 /* Addresses are trimed to 24 bits for internal storage, so we need to
152 * add this offset back in order to get the real address.
154 addr
|= PNACL_STRING_OFFSET
;
155 const char* name
= (const char*)addr
;
156 struct XRaySymbol
* symbol
= XRaySymbolCreate(symtab
->symbol_pool
, name
);
157 r
= XRaySymbolTableAdd(symtab
, symbol
, addr
);
161 #if defined(__GLIBC__)
164 if (dladdr((const void*)addr
, &info
) != 0)
166 r
= XRaySymbolTableAddByName(symtab
, info
.dli_sname
, addr
);
173 /* Returns total number of symbols in the table. */
174 int XRaySymbolCount(struct XRaySymbolTable
* symtab
) {
175 return symtab
->num_symbols
;
179 /* Creates and inializes a symbol table. */
180 struct XRaySymbolTable
* XRaySymbolTableCreate(int size
) {
181 struct XRaySymbolTable
* symtab
;
182 symtab
= (struct XRaySymbolTable
*)XRayMalloc(sizeof(*symtab
));
183 symtab
->num_symbols
= 0;
184 symtab
->string_pool
= XRayStringPoolCreate();
185 symtab
->hash_table
= XRayHashTableCreate(size
);
186 symtab
->symbol_pool
= XRaySymbolPoolCreate();
191 /* Frees a symbol table. */
192 void XRaySymbolTableFree(struct XRaySymbolTable
* symtab
) {
193 XRayStringPoolFree(symtab
->string_pool
);
194 XRaySymbolPoolFree(symtab
->symbol_pool
);
195 XRayHashTableFree(symtab
->hash_table
);
196 symtab
->num_symbols
= 0;