mageec  0.1.0
MAchine Guided Energy Efficient Compilation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
elfhash.cpp
Go to the documentation of this file.
1 /* ELF Object Hasher
2  Copyright (C) 2013, 2014 Embecosm Limited and University of Bristol
3 
4  This file is part of MAGEEC.
5 
6  This program is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program. If not, see <http://www.gnu.org/licenses/>. */
18 
20 #include "mageec/elfhash.h"
21 #include "mageec/mageec.h"
22 #include <cstdlib>
23 #include <cstring>
24 #include <iostream>
25 #include <fcntl.h>
26 #include "libelf.h"
27 #include "gelf.h"
28 #include "gcrypt.h"
29 
30 
31 using namespace mageec;
32 
34 {
35  data = NULL;
36  datasize = 0;
37 }
38 
39 bool hashedelf::ignoredsection (char const *sectionname)
40 {
41  if (sectionname == NULL)
42  return true;
43  if (!strcmp (sectionname, ".note.gnu.build-id"))
44  return true;
45  if (!strcmp (sectionname, ".gnu.hash"))
46  return true;
47  if (!strcmp (sectionname, ".gnu.version"))
48  return true;
49  if (!strcmp (sectionname, ".gnu.version_r"))
50  return true;
51  return false;
52 }
53 
54 int hashedelf::hash (char const *filename)
55 {
56  Elf *elf;
57  Elf_Kind kind;
58  size_t sheaderindex;
59  Elf_Scn *section;
60  GElf_Shdr sechdr;
61  Elf_Data *elfdata;
62 
63  if (elf_version (EV_CURRENT) == EV_NONE)
64  return 1;
65 
66  int fd = open (filename, O_RDONLY, 0);
67  if (fd < 0)
68  return 1;
69 
70  elf = elf_begin (fd, ELF_C_READ, NULL);
71  if (elf == NULL)
72  return 1;
73 
74  kind = elf_kind (elf);
75  if (kind != ELF_K_ELF)
76  return 1;
77 
78  if (elf_getshdrstrndx (elf, &sheaderindex) != 0)
79  return 1;
80 
81  section = elf_nextscn (elf, NULL);
82 
83  while (section != NULL)
84  {
85  char *name;
86 
87  if (gelf_getshdr(section, &sechdr) != &sechdr)
88  return 1;
89 
90  name = elf_strptr (elf, sheaderindex, sechdr.sh_name);
91  if (name == NULL)
92  return 1;
93 
94  if ((sechdr.sh_flags & SHF_ALLOC) && !ignoredsection(name))
95  {
96  /* Add sectionname */
97  data = static_cast<unsigned char *>(realloc (data, datasize +
98  strlen(name)));
99  if (data == NULL)
100  return 1;
101  memcpy((data+datasize), name, strlen(name));
102  datasize += strlen(name);
103 
104  /* Add size and load address */
105  data = static_cast<unsigned char *>(realloc (data, datasize +
106  sizeof(sechdr.sh_size) +
107  sizeof(sechdr.sh_addr)));
108  if (data == NULL)
109  return 1;
110  memcpy((data+datasize), &sechdr.sh_size, sizeof(sechdr.sh_size));
111  memcpy((data+datasize+sizeof(sechdr.sh_size)), &sechdr.sh_addr,
112  sizeof(sechdr.sh_addr));
113  datasize += sizeof(sechdr.sh_size) + sizeof(sechdr.sh_addr);
114 
115  /* Add section data */
116  elfdata = elf_rawdata (section, NULL);
117  if (elfdata == NULL)
118  return 1;
119  if (elfdata->d_size > 0 && elfdata->d_buf != NULL) {
120  data = static_cast<unsigned char *>(realloc (data, datasize +
121  elfdata->d_size));
122  if (data == NULL)
123  return 1;
124  memcpy((data+datasize), elfdata->d_buf, elfdata->d_size);
125  datasize += elfdata->d_size;
126  }
127  }
128 
129  section = elf_nextscn (elf, section);
130  }
131 
132 
133  return 0;
134 }
135 
137 {
138  return hash_data (data, datasize);
139 }