From: Kai W. <kai...@gm...> - 2012-12-29 07:34:47
|
On Thu, Dec 27, 2012 at 01:09:18PM +0530, Joseph Koshy wrote: > > Some questions: > > > > * What is the nested symbol table used for? Could you give an example? > > as(1) has a macro facility (.altmacro) which supports 'local' identifiers. > When the macro definition is used, such local names expand to unique > IDs, different for each use of the macro. These local names go out of > scope when the macro ends, and can shadow symbols already seen in the > assembler source. I see. > > * Is it possible to customize the elftc_symbol_table_to_image? > > > > For example, ld(1) sometimes searchs symbols by name and symbol version. > > To achieve that, ld(1) stores symbol name is the form "symbol@version", > > "atoi@FBSD_1.0" for instance. When elftc_symbol_table_to_image is called, > > ld(1) will want the string "atoi" in the string table, not "atoi@FBSD_1.0". > > The iterate() API is intended for these kind of transformations. > > For example, the application could use the iterate() API to generate > a copy of the symbol table with the names transformed, and then use > elftc_symbol_table_to_image() on the transformed table: I see. My only concern is that for ld(1) the symbol table can be really huge, create another copy of symbol table might be expensive. > Alternatively, we could add a 'transformfn()' parameter to the > elftc_symbol_table_to_image() API. If non-null, the transformfn() would > be called for each entry, prior to the entry's (ELF) in-memory image > being created. This function could effect an in-place transformation > of the symbol. > > The revised prototype would then look like: > > Gelf_Sym * > elftc_symbol_table_to_image(Elftc_Symbol_Table *table, size_t *nentries, > int (*transformfn)(Elftc_Elf_Symbol *sym, void *cookie), > void *cookie, Elftc_String_Table **strtab); > > However, this way seems less general than the first. How about, we keep the current elftc_symbol_table_to_image as is, and add another more generic transform API: void * elftc_symbol_table_to_image_generic(Elftc_Symbol_Table *table, size_t *nentries, int (*transformfn)(Elftc_Elf_Symbol *sym, void *cookie, void *entry), size_t entsize, void *cookie, Elftc_String_Table **strtab); Rationale: * API returns untyped buffer. * `entsize' spcifies the entry size of the returned buffer. * `entry' points to the entry buffer where application provided `transformfn' should fill in. (The API advance the `entry' pointer internally, by adding `entsize') The idea is that elftc_symbol_table_to_image_generic can return an array of Elf32_Sym/Elf64_Sym instead of GElf_Sym. The returned array can be assigned to the `d_buf' field of an Elf_Data descriptor directly, thus avoid one more memory copy. (comparing to using gelf_update_sym() on returned GElf_Sym array) Also, ld(1) can use this API to transform symbol with customized name, as I mentioned in my preivous mail. > > * Is it possible to provide a sort API? e.g. > > elftc_symbol_table_sort(Elftc_Symbol_Table *table, > > int (*cmp)(Elftc_Symbol *s1, Elftc_Symbol *s2)) > > Good point. For tables with entries that have some kind of ordering > associated with them, we could also have a 'step()' API: > > Elftc_Symbol * > elftc_symbol_table_step(Elftc_Symbol_Table *table, > Elftc_Symbol *sym, int stepdirection); > > where 'stepdirection' would be one of ELFTC_STEP_NEXT | ELFTC_STEP_PREVIOUS. See my comments below. > There is another API that could be useful during disassembly: > > Elftc_Elf_Symbol * > elftc_symbol_table_lookup_value(Elftc_Symbol_Table *table, > uint64_t value, off_t &offset, int searchflags); > > This would return the symbol 'closest' to the specified value. > 'searchflags' could be ELFTC_SEARCH_FORWARD | ELFTC_SEARCH_BACKWARD. Good idea. This can be used by tools like addr2line(1) and ld(1) as well. > > * Is it possible to provide a "replace" API? > > e.g. elftc_symbol_table_replace(Elftc_Symbol_Table *table, > > Elftc_Symbol *s1, Elftc_Symbol *s2) > > > This API can be used when, for example, symbol resolving in ld(1). > > When application knows symbol s1 exists in the symbol table, it wants > > to replace s1 with s2 and expects that s2 will have the same > > position in the symbol table as s1. > > Could you clarify what the difference between a replace API and a > 'delete(s1)', 'insert(s2)' sequence would be? Do you need 's2' to be > associated with the same (ELF) symbol table index as 's1'? The `replace' API depends on the implementation, see below. And you're right, I want 's2' to have the same symbol table index as 's1'. > > * What kind of internal data structures are you going to use to > > implement symbol table and string table? > > I was thinking of some kind of hash table for name lookups for basic > symbol tables that have no concept of a sort order. For "Elftc_Elf_Symbol" > entries, we would need additional fields for dealing with ordering > of symbols. Suggestions welcome. I was thinking the symbol table is both a doublely linked list and a hash table. The table is iterated in insertion order, or sort order if the `sort' API has been called. The `replace' API make sure symbol `s2' has the same position in the linked list as symbol `s1', thus the same symbol index. This is useful for ld(1). If it's implemented as above, the `step' API can be used in sorted and unsorted tables? Thanks, Kai |