summaryrefslogtreecommitdiffstats
path: root/translate.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'translate.cxx')
-rw-r--r--translate.cxx46
1 files changed, 46 insertions, 0 deletions
diff --git a/translate.cxx b/translate.cxx
index e92c8483..bbd8a01b 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,25 @@ 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)
+ {
+ /* XXX: But see https://bugzilla.redhat.com/show_bug.cgi?id=465872;
+ dwfl_module_build_id was not intended to return the end address. */
+ 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 +4601,32 @@ 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;
+
+ /* XXX: kernel data boot-time relocation works differently from text.
+ This hack disables relocation altogether, but that's not necessarily
+ correct either. We may instead need a relocation basis different
+ from _stext, such as __start_notes. */
+ 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);