Skip to content

Instantly share code, notes, and snippets.

@osadalakmal
Created March 17, 2013 16:19
Show Gist options
  • Save osadalakmal/5182244 to your computer and use it in GitHub Desktop.
Save osadalakmal/5182244 to your computer and use it in GitHub Desktop.
c++ program for adding build tag section to a elf file
#include <elfio/elfio.hpp>
#include <libxml/parser.h>
#include <libxml/tree.h>
#include <iostream>
#include <time.h>
#include <string.h>
using namespace ELFIO;
static const char* xmlConfigFile = "buildtag.xml";
static const char* DATETIME_STR = "datetime";
static const int DATETIME_OPT = 0;
static const char* BUILDER_STR = "builder";
static const int BUILDER_OPT = 1;
static const char* GUID_STR = "guid";
static const int GUID_OPT = 2;
static const char* GIT_DESC = "git-describe";
static const int GIT_OPT = 3;
static struct {
bool isSet;
std::string formetStr;
} options[4] = {};
bool readConfig(const char *filename) {
LIBXML_TEST_VERSION
xmlDocPtr doc;
doc = xmlReadFile(filename, NULL, 0);
if (doc == NULL) {
fprintf(stderr, "Failed to parse %s\n", filename);
return false;
}
for (xmlNode *cur_node = xmlDocGetRootElement(doc)->children->next; cur_node; cur_node = cur_node->next) {
std::cout << (const char*)(cur_node->name) << std::endl;
if (cur_node->type == XML_ELEMENT_NODE) {
if (strstr(reinterpret_cast<const char*>(cur_node->name),DATETIME_STR) != NULL) {
options[DATETIME_OPT].isSet = true;
options[DATETIME_OPT].formetStr = std::string(reinterpret_cast<const char*>(cur_node->children->content));
} else if (strstr(reinterpret_cast<const char*>(cur_node->name),BUILDER_STR) != NULL) {
options[BUILDER_OPT].isSet = true;
} else if (strstr(reinterpret_cast<const char*>(cur_node->name),GUID_STR) != NULL) {
options[GUID_OPT].isSet = true;
} else if (strstr(reinterpret_cast<const char*>(cur_node->name),GIT_DESC) != NULL) {
options[GIT_OPT].isSet = true;
}
}
}
xmlFreeDoc(doc);
xmlCleanupParser();
return true;
}
int getNoteSection(elfio& reader) {
Elf_Half sec_num = reader.sections.size();
for(int i=static_cast<int>(sec_num); i--; i>0) {
if ((reader.sections[i]->get_type() == SHT_NOTE) &&
(reader.sections[i]->get_name() == ".note.gnu.build-id")) {
return i;
}
}
return 0;
}
void createTags(elfio& tagger, section*& noteSection) {
ELFIO::note_section_accessor noteAcc(tagger,noteSection);
char buffer[512] = {};
if (options[DATETIME_OPT].isSet) {
time_t rawtime;
struct tm* now;
time(&rawtime);
now = gmtime(&rawtime);
size_t nowLen = strftime(buffer,sizeof(buffer),options[DATETIME_OPT].formetStr.c_str(), now);
noteAcc.add_note(SHT_NOTE, "BuildTime", buffer, nowLen);
}
}
int main (int argc, char* argv[]) {
elfio tagger;
readConfig(xmlConfigFile);
tagger.load("a.out");
int noteSectionId = getNoteSection(tagger);
section* noteSection;
if (noteSectionId == 0) {
noteSection = tagger.sections.add("note.applicationid");
noteSection->set_type(SHT_NOTE);
noteSection->set_addr_align(1);
std::cout << "Adding new section\n";
} else {
std::cout << "Getting existing section " << noteSectionId << " \n";
noteSection = tagger.sections[noteSectionId];
}
createTags(tagger,noteSection);
tagger.set_entry( 0x08048000 );
tagger.save("a.1.out");
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment