08/2009 by Zadig.
Introduction:
After a first review of the everest project on the last post, here is a status of the first implemented features and the first issues that where encountered. The ui layout is now defined, symbols are available in a more user friendly way, disassembly is available, as well as call graphs. This is quite good for only few hours of coding!
The graphical layout of everest is the following: The top left part of the screen contains a select box that allows to switch between the loaded objects (even though the feature is not coded yet). Below it, still on the left part, is a list of available features families:
When a feature is selected, the middle part of the screen displays a dedicated panel composed of several tabs, specific to the feature. This should allow a natural navigation in the objects code for the reading/analyzing features.
The disassembly of a function is now available. The Rest api for this is
"/rest/obj/[obj_index]/sym/[sym_name]/disasm", where sym_name is the name of the
symbol to disassemble. The everest code to do this was dumped from the disasm
functions available in libstderesi/elf/disasm.c. These functions could not be used
as is mainly because they encode the output for a terminal, adding unicode
escape characters to add colors. Such codes are obvioulsy not recognized in
html.
Moreover symbols names are embraced with "<" and ">" characters that are
tag delimiters in html. So they must be replaced with there html encoding
equivalent. The problem is that the function resolving symbol names and adding
the delimiters is configured in a global way by calling
"asm_set_resolve_handler". This function is called in everest each time a new
disassembly is done, overriding the current one. It is called before each
disassembly because some other parts of eresi can also change it during runtime
(when generating a graph for example). This will need to be cleaned up.
Now that the disassembly is available, the next step on this feature will be adding hyperlinks to navigate in the code by just clicking on jumps and calls references.
Call graphs are already available in Eresi. So bringing this to Everest should
have been straightforward. However a lot of different solutions where
considered. The first thing was whether the graph should be generated
on the client or server side. I looked at Canviz that is a dot graph
generator in javascript. Its looks really promising but it was not chosen
because it runs very slowly on Opera (This should change with Opera 10), and is
based on Prototype while everest is
based on JQuery . However I suppose that a
port to JQuery should not be that difficult. Maybe later...
Back to the server side solution, there are several possibilities on the file
format. Eresi generates png by default. Since graphiz can generate svg files, I
looked at that solution because it would allow easy manipulation of it on the
client side (for all sort of interactions with the graph). Unfortunately the
needed svg library is not running on Haiku. So the easiest way is to keep with
the current png format. Some support for map files associated to it should
allow to have hyperlinks in the graphs.
After fighting with libstderesi and trying to use the calls that generate the graph, I ended up using revm_exec_str and revm_execmd to generate the graph the same way than typing "graph func myfunc". The advantage is that it is very simple, but the drawback is that the name and location of the generated files cannot be chosen. Every paths are hardcoded for the moment, but the Eresi environment information should be used in the future. This also means that the http server must serve this png files from another directory than the everest one. For the moment this was simply done by creating a link in the http root directory of everest pointing to the dot and png working directory of Eeresi (/tmp on my system). This is another point that will have to be handled in a clean way later.
Getting the graph is done in two steps. First the "/rest/obj/[obj_index]/sym/[sym_name]/graph" api is called to generate the graph. This api returns the path of the generated png in the "data" field of the http answer. Then we just have to set an image source to this path so that the browser retrieves and displays it.
A first work was done on the symbols panel to avoid doing Rest calls each time a
symbol tab is clicked. This is simply done by keeping the id of the selected
object, and reloading the data only if it is different from the last one. Also
to make this work correctly, the previously generated html code must not be lost
when switching to another panel. This is done quite easily since each panel has
its own div in the common "col_mid" div. Selecting a new panel just means hiding
all panels, and showing the selected one.
This method of caching previous requests will also be applied to the disassembly
and graph tabs since it seems quite efficient and is easy to implement.
That's all for this time, without snapshot. I want to write a minimum css theme before providing new ones. The first conclusion of this first coding step is that what was written in a few hours would have required at least 5 more time if written with a C/C++ framework. Considering that I am not an html/js expert this is really nice since it allows to think more on what features to add rather than how to implement things.
Zadig.