aboutsummaryrefslogtreecommitdiff
path: root/src/common/linux/module.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/linux/module.cc')
-rw-r--r--src/common/linux/module.cc46
1 files changed, 46 insertions, 0 deletions
diff --git a/src/common/linux/module.cc b/src/common/linux/module.cc
index bd0ae9f9..f6373895 100644
--- a/src/common/linux/module.cc
+++ b/src/common/linux/module.cc
@@ -52,6 +52,9 @@ Module::~Module() {
for (vector<Function *>::iterator it = functions_.begin();
it != functions_.end(); it++)
delete *it;
+ for (vector<StackFrameEntry *>::iterator it = stack_frame_entries_.begin();
+ it != stack_frame_entries_.end(); it++)
+ delete *it;
}
void Module::SetLoadAddress(Address address) {
@@ -67,6 +70,10 @@ void Module::AddFunctions(vector<Function *>::iterator begin,
functions_.insert(functions_.end(), begin, end);
}
+void Module::AddStackFrameEntry(StackFrameEntry *stack_frame_entry) {
+ stack_frame_entries_.push_back(stack_frame_entry);
+}
+
void Module::GetFunctions(vector<Function *> *vec,
vector<Function *>::iterator i) {
vec->insert(i, functions_.begin(), functions_.end());
@@ -111,6 +118,10 @@ void Module::GetFiles(vector<File *> *vec) {
vec->push_back(it->second);
}
+void Module::GetStackFrameEntries(vector<StackFrameEntry *> *vec) {
+ *vec = stack_frame_entries_;
+}
+
void Module::AssignSourceIds() {
// First, give every source file an id of -1.
for (FileByNameMap::iterator file_it = files_.begin();
@@ -144,6 +155,18 @@ bool Module::ReportError() {
return false;
}
+bool Module::WriteRuleMap(const RuleMap &rule_map, FILE *stream) {
+ for (RuleMap::const_iterator it = rule_map.begin();
+ it != rule_map.end(); it++) {
+ if (it != rule_map.begin() &&
+ 0 > putc(' ', stream))
+ return false;
+ if (0 > fprintf(stream, "%s: %s", it->first.c_str(), it->second.c_str()))
+ return false;
+ }
+ return true;
+}
+
bool Module::Write(FILE *stream) {
if (0 > fprintf(stream, "MODULE %s %s %s %s\n",
os_.c_str(), architecture_.c_str(), id_.c_str(),
@@ -183,6 +206,29 @@ bool Module::Write(FILE *stream) {
return ReportError();
}
+ // Write out 'STACK CFI INIT' and 'STACK CFI' records.
+ vector<StackFrameEntry *>::const_iterator frame_it;
+ for (frame_it = stack_frame_entries_.begin();
+ frame_it != stack_frame_entries_.end(); frame_it++) {
+ StackFrameEntry *entry = *frame_it;
+ if (0 > fprintf(stream, "STACK CFI INIT %llx %llx ",
+ (unsigned long long) entry->address - load_address_,
+ (unsigned long long) entry->size)
+ || !WriteRuleMap(entry->initial_rules, stream)
+ || 0 > putc('\n', stream))
+ return ReportError();
+
+ // Write out this entry's delta rules as 'STACK CFI' records.
+ for (RuleChangeMap::const_iterator delta_it = entry->rule_changes.begin();
+ delta_it != entry->rule_changes.end(); delta_it++) {
+ if (0 > fprintf(stream, "STACK CFI %llx ",
+ (unsigned long long) delta_it->first - load_address_)
+ || !WriteRuleMap(delta_it->second, stream)
+ || 0 > putc('\n', stream))
+ return ReportError();
+ }
+ }
+
return true;
}