00001
00002 #if !defined(_dwarf_walker_h_)
00003 #define _dwarf_walker_h_
00004
00005 #include "elf.h"
00006 #include "libelf.h"
00007 #include "libdwarf.h"
00008 #include <stack>
00009 #include <vector>
00010 #include <string>
00011 #include <set>
00012 #include "dyntypes.h"
00013 #include "VariableLocation.h"
00014 #include "Type.h"
00015
00016 namespace Dyninst {
00017 namespace SymtabAPI {
00018
00019
00020
00021 class Symtab;
00022 class Module;
00023 class Object;
00024 class Function;
00025 class typeCommon;
00026 class typeEnum;
00027 class fieldListType;
00028 class typeCollection;
00029 class Type;
00030
00031 class DwarfWalker {
00032 typedef std::vector<std::pair<Address, Address> > range_set_t;
00033 typedef boost::shared_ptr<std::vector<std::pair<Address, Address> > > range_set_ptr;
00034
00035 struct Contexts {
00036 struct Context {
00037 Function *func;
00038 typeCommon *commonBlock;
00039 typeEnum *enumType;
00040 fieldListType *enclosure;
00041 bool parseSibling;
00042 bool parseChild;
00043 Dwarf_Die entry;
00044 Dwarf_Die specEntry;
00045 Dwarf_Die abstractEntry;
00046 Dwarf_Off offset;
00047 Dwarf_Half tag;
00048 Address base;
00049 range_set_ptr ranges;
00050 Context() :
00051 func(NULL), commonBlock(NULL),
00052 enumType(NULL), enclosure(NULL),
00053 parseSibling(true), parseChild(true),
00054 base(0) {};
00055 };
00056
00057 std::stack<Context> c;
00058 void push();
00059 void pop();
00060 Function *curFunc() { return c.top().func; }
00061 typeCommon * curCommon() { return c.top().commonBlock; }
00062 typeEnum *curEnum() { return c.top().enumType; }
00063 fieldListType *curEnclosure() { return c.top().enclosure; }
00064 bool parseSibling() { return c.top().parseSibling; }
00065 bool parseChild() { return c.top().parseChild; }
00066 Dwarf_Die entry() { return c.top().entry; }
00067 Dwarf_Die specEntry() { return c.top().specEntry; }
00068 Dwarf_Die abstractEntry() { return c.top().abstractEntry; }
00069 Dwarf_Off offset() { return c.top().offset; }
00070 Dwarf_Half tag() { return c.top().tag; }
00071 Address base() { return c.top().base; }
00072 range_set_ptr ranges() { return c.top().ranges; }
00073
00074 void setFunc(Function *f);
00075 void setCommon(typeCommon *tc) { c.top().commonBlock = tc; }
00076 void setEnum(typeEnum *e) { c.top().enumType = e; }
00077 void setEnclosure(fieldListType *f) { c.top().enclosure = f; }
00078 void setParseSibling(bool p) { c.top().parseSibling = p; }
00079 void setParseChild(bool p) { c.top().parseChild = p; }
00080 void setEntry(Dwarf_Die e) { c.top().entry = e; }
00081 void setSpecEntry(Dwarf_Die e) { c.top().specEntry = e; }
00082 void setAbstractEntry(Dwarf_Die e) { c.top().abstractEntry = e; }
00083 void setOffset(Dwarf_Off o) { c.top().offset = o; }
00084 void setTag(Dwarf_Tag t) { c.top().tag = t; }
00085 void setBase(Address a) { c.top().base = a; }
00086 void setRange(std::pair<Address, Address> range) {
00087 if (!c.top().ranges)
00088 c.top().ranges = range_set_ptr(new std::vector<std::pair<Address, Address> >);
00089 c.top().ranges->push_back(range);
00090 }
00091 void clearRanges() {
00092 c.top().ranges = range_set_ptr();
00093 }
00094 void clearFunc();
00095 };
00096
00097 public:
00098 typedef enum {
00099 NoError
00100
00101 } Error;
00102
00103 DwarfWalker(Symtab *symtab, Dwarf_Debug &dbg);
00104
00105 ~DwarfWalker();
00106
00107 bool parse();
00108
00109 private:
00110 bool setup(Dwarf_Die dieEntry,
00111 Dwarf_Off modOffset,
00112 Address lowpc);
00113
00114
00115 bool parseModule(Module *&fixUnknownMod);
00116
00117
00118
00119
00120 bool parse_int(Dwarf_Die entry, bool parseSiblings);
00121
00122 bool parseSubprogram();
00123 bool parseLexicalBlock();
00124 bool parseCommonBlock();
00125 bool parseConstant();
00126 bool parseVariable();
00127 bool parseFormalParam();
00128 bool parseBaseType();
00129 bool parseTypedef();
00130 bool parseArray();
00131 bool parseSubrange();
00132 bool parseEnum();
00133 bool parseInheritance();
00134 bool parseStructUnionClass();
00135 bool parseEnumEntry();
00136 bool parseMember();
00137 bool parseConstPackedVolatile();
00138 bool parseTypeReferences();
00139
00140
00141 Function *curFunc() { return contexts_.curFunc(); }
00142 typeCommon *curCommon() { return contexts_.curCommon(); }
00143 typeEnum *curEnum() { return contexts_.curEnum(); }
00144 fieldListType *curEnclosure() { return contexts_.curEnclosure(); }
00145
00146 void setFunc(Function *f) { contexts_.setFunc(f); }
00147 void setCommon(typeCommon *c) { contexts_.setCommon(c); }
00148 void setEnum(typeEnum *e) { contexts_.setEnum(e); }
00149 void setEnclosure(fieldListType *f) { contexts_.setEnclosure(f); }
00150
00151
00152 std::string &curName() { return name_; }
00153 bool nameDefined() { return name_ != ""; }
00154
00155 Object *obj();
00156 Symtab *symtab() { return symtab_; }
00157 Module *mod() { return mod_; }
00158 std::vector<std::string> &srcFiles() { return srcFiles_; }
00159 typeCollection *tc() { return tc_; }
00160 Dwarf_Debug &dbg() { return dbg_; }
00161
00162 bool parseSibling() { return contexts_.parseSibling(); }
00163 bool parseChild() { return contexts_.parseChild(); }
00164 void setParseSibling(bool p) { return contexts_.setParseSibling(p); }
00165 void setParseChild(bool p) { return contexts_.setParseChild(p); }
00166
00167 Dwarf_Half tag() { return contexts_.tag(); }
00168 Dwarf_Off offset() { return contexts_.offset(); }
00169 Dwarf_Die entry() { return contexts_.entry(); }
00170
00171
00172 Dwarf_Die specEntry() { return contexts_.specEntry(); }
00173
00174
00175 Dwarf_Die abstractEntry() { return contexts_.abstractEntry(); }
00176 void clearRanges() { contexts_.clearRanges(); }
00177 bool hasRanges() { return contexts_.ranges() != NULL; }
00178 range_set_t::iterator ranges_begin() { return contexts_.ranges()->begin(); }
00179 range_set_t::iterator ranges_end() { return contexts_.ranges()->end(); }
00180
00181
00182 unsigned long id() { return (unsigned long) (offset() - compile_offset); }
00183
00184 void setEntry(Dwarf_Die entry);
00185 void setSpecEntry(Dwarf_Die se) { contexts_.setSpecEntry(se); }
00186 void setAbstractEntry(Dwarf_Die se) { contexts_.setAbstractEntry(se); }
00187 void setTag(Dwarf_Half tag) { contexts_.setTag(tag); }
00188 void setOffset(Dwarf_Off offset) { contexts_.setOffset(offset); }
00189 void setRange(std::pair<Address, Address> range) { contexts_.setRange(range); }
00190
00191 bool buildSrcFiles(Dwarf_Die entry);
00192 bool hasDeclaration(bool &decl);
00193 bool findTag();
00194 bool findOffset();
00195 bool handleAbstractOrigin(bool &isAbstractOrigin);
00196 bool handleSpecification(bool &hasSpec);
00197 bool findFuncName();
00198 bool findFunction(bool &found);
00199 bool findBaseAddr();
00200 bool getFrameBase();
00201 bool getReturnType(bool hasSpecification, Type *&returnType);
00202 bool addFuncToContainer(Type *returnType);
00203 bool findType(Type *&, bool defaultToVoid);
00204 bool getLineInformation(Dwarf_Unsigned &variableLineNo,
00205 bool &hasLineNumber,
00206 std::string &filename);
00207 bool findName(std::string &);
00208 void removeFortranUnderscore(std::string &);
00209 bool findSize(unsigned &size);
00210 bool findVisibility(visibility_t &visibility);
00211 bool findValue(long &value, bool &valid);
00212 bool fixName(std::string &name, Type *type);
00213 bool fixBitFields(std::vector<VariableLocation> &locs, long &size);
00214 bool findEntryToUse(Dwarf_Half attr, bool &found, Dwarf_Die &entry);
00215 bool parseSubrangeAUX(Dwarf_Die entry,
00216 std::string &lobound,
00217 std::string &hibound);
00218 bool decodeLocationList(Dwarf_Half attr,
00219 Address *initialVal,
00220 std::vector<VariableLocation> &locs);
00221 bool checkForConstantOrExpr(Dwarf_Half attr,
00222 Dwarf_Attribute &locationAttribute,
00223 bool &constant,
00224 bool &expr,
00225 Dwarf_Half &form);
00226 bool findConstant(Dwarf_Half attr, Address &value);
00227 bool findConstantWithForm(Dwarf_Attribute &attr,
00228 Dwarf_Half form,
00229 Address &value);
00230 bool decodeConstantLocation(Dwarf_Attribute &attr, Dwarf_Half form,
00231 std::vector<VariableLocation> &locs);
00232 bool constructConstantVariableLocation(Address value,
00233 std::vector<VariableLocation> &locs);
00234 typeArray *parseMultiDimensionalArray(Dwarf_Die firstRange,
00235 Type *elementType);
00236 bool decipherBound(Dwarf_Attribute boundAttribute, std::string &name);
00237
00238 bool decodeExpression(Dwarf_Attribute &attr,
00239 std::vector<VariableLocation> &locs);
00240
00241 bool decodeLocationListForStaticOffsetOrAddress(Dwarf_Locdesc **locationList,
00242 Dwarf_Signed listLength,
00243 std::vector<VariableLocation>& locs,
00244 Address * initialStackValue = NULL);
00245 void deallocateLocationList(Dwarf_Locdesc *locationList,
00246 Dwarf_Signed listLength);
00247 void deallocateLocationList(Dwarf_Locdesc **locationList,
00248 Dwarf_Signed listLength);
00249
00250
00251
00252 void clearFunc() { contexts_.clearFunc(); }
00253
00254
00255
00256 std::map<Dwarf_Off, fieldListType *> enclosureMap;
00257
00258 std::set<Function *> parsedFuncs;
00259
00260 Contexts contexts_;
00261
00262 Dwarf_Debug &dbg_;
00263 Module *mod_;
00264 Symtab *symtab_;
00265 std::vector<std::string> srcFiles_;
00266 typeCollection *tc_;
00267
00268 std::string name_;
00269
00270
00271 Address modLow;
00272 Address modHigh;
00273 Dwarf_Unsigned cu_header_length;
00274 Dwarf_Half version;
00275 Dwarf_Unsigned abbrev_offset;
00276 Dwarf_Half addr_size;
00277 Dwarf_Half offset_size;
00278 Dwarf_Half extension_size;
00279 Dwarf_Sig8 signature;
00280 Dwarf_Unsigned typeoffset;
00281 Dwarf_Unsigned next_cu_header;
00282
00283
00284
00285 Dwarf_Off compile_offset;
00286
00287 };
00288
00289 };
00290 };
00291
00292 #endif