diff options
author | Wenji Huang <wenji.huang@oracle.com> | 2008-10-06 03:07:09 -0400 |
---|---|---|
committer | Wenji Huang <wenji.huang@oracle.com> | 2008-10-06 03:07:09 -0400 |
commit | 2949597251fea7f17a0e46c1c885e34b53395d18 (patch) | |
tree | 7628da32ea81a5bbaf10f31c7fd60006629db3d6 /translate.cxx | |
parent | 5311c037f83f66967f9de4cc66815f93940bb005 (diff) | |
download | systemtap-steved-2949597251fea7f17a0e46c1c885e34b53395d18.tar.gz systemtap-steved-2949597251fea7f17a0e46c1c885e34b53395d18.tar.xz systemtap-steved-2949597251fea7f17a0e46c1c885e34b53395d18.zip |
PR4886: check build-id if able.
This provides sanity check of debuginfo file based on build-id. Many cases are considered, whether build-id exists in debuginfo file or not, whether module is loaded or not, whether build-id exists in runtime kernel/module. It will do work when LD >= 2.18 and kernel >=2.6.23, otherwise no check.
Diffstat (limited to 'translate.cxx')
-rw-r--r-- | translate.cxx | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/translate.cxx b/translate.cxx index e92c8483..0ee51792 100644 --- a/translate.cxx +++ b/translate.cxx @@ -1113,6 +1113,7 @@ c_unparser::emit_module_init () o->newline(-1) << "}"; // XXX: perform buildid-based checking if able + o->newline() << "if (_stp_module_check()) rc = -EINVAL;"; o->newline(-1) << "}"; o->newline() << "if (rc) goto out;"; @@ -4413,6 +4414,23 @@ dump_unwindsyms (Dwfl_Module *m, int syments = dwfl_module_getsymtab(m); assert(syments); + //extract build-id from debuginfo file + int build_id_len = 0; + unsigned char *build_id_bits; + GElf_Addr build_id_vaddr; + + if ((build_id_len=dwfl_module_build_id(m, + (const unsigned char **)&build_id_bits, + &build_id_vaddr)) > 0) + { + if (c->session.verbose > 1) { + clog << "Found build-id in " << name + << ", length " << build_id_len; + clog << ", end at 0x" << hex << build_id_vaddr + << dec << endl; + } + } + // Look up the relocation basis for symbols int n = dwfl_module_relocations (m); @@ -4581,6 +4599,28 @@ dump_unwindsyms (Dwfl_Module *m, c->output << ".num_sections = sizeof(_stp_module_" << stpmod_idx << "_sections)/" << "sizeof(struct _stp_section), " << endl; + if (build_id_len > 0) { + c->output << ".build_id_bits = \"" ; + for (int j=0; j<build_id_len;j++) + c->output << "\\x" << hex + << (unsigned short) *(build_id_bits+j) << dec; + + c->output << "\", " << endl; + c->output << ".build_id_len = " << build_id_len << ", " << endl; + + if (modname == "kernel") + c->output << ".build_id_offset = 0x" << hex << build_id_vaddr + << dec << ", " << endl; + else + c->output << ".build_id_offset = 0x" << hex + << build_id_vaddr - base + << dec << ", " << endl; + } else + c->output << ".build_id_len = 0, " << endl; + + //initialize the note section representing unloaded + c->output << ".notes_sect = 0," << endl; + c->output << "};" << endl << endl; c->undone_unwindsym_modules.erase (modname); |