ROSE  0.9.6a
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ElfNote.C
Go to the documentation of this file.
1 /* ELF Note Sections (SgAsmElfNoteSection and related classes) */
2 
3 #include "sage3basic.h"
4 
6 void
8 {
9  ROSE_ASSERT(section->get_entries()!=NULL);
10  section->get_entries()->get_entries().push_back(this);
11  ROSE_ASSERT(section->get_entries()->get_entries().size()>0);
12  set_parent(section->get_entries());
13 
14  p_name = new SgAsmBasicString("");
15  p_name->set_parent(this);
16 }
17 
21 {
22  return p_name;
23 }
24 
26 void
28 {
29  if (name!=p_name) {
30  if (p_name) {
31  p_name->set_parent(NULL);
33  }
34  p_name = name;
35  if (p_name)
36  p_name->set_parent(this);
37  set_isModified(true);
38  }
39 }
40 
42 void
43 SgAsmElfNoteEntry::set_payload(const void *_buf, size_t nbytes)
44 {
45  const unsigned char *buf = (const unsigned char*)_buf;
46  p_payload.clear();
47  p_payload.reserve(nbytes);
48  for (size_t i=0; i<nbytes; i++)
49  p_payload.push_back(buf[i]);
50 }
51 
56 {
57  /* Find the section holding this note */
58  SgAsmElfNoteSection *notes = SageInterface::getEnclosingNode<SgAsmElfNoteSection>(this);
59  ROSE_ASSERT(notes!=NULL);
60  ROSE_ASSERT(at < notes->get_size());
61  SgAsmElfFileHeader *fhdr = dynamic_cast<SgAsmElfFileHeader*>(notes->get_header());
62  ROSE_ASSERT(fhdr!=NULL);
63 
64  /* Length of note entry name, including NUL termination */
65  uint32_t u32;
66  notes->read_content_local(at, &u32, 4);
67  size_t name_size = disk_to_host(fhdr->get_sex(), u32);
68  at += 4;
69 
70  /* Length of note entry description (i.e., the payload) */
71  notes->read_content_local(at, &u32, 4);
72  size_t payload_size = disk_to_host(fhdr->get_sex(), u32);
73  at += 4;
74 
75  /* Type of note */
76  notes->read_content_local(at, &u32, 4);
77  unsigned type = disk_to_host(fhdr->get_sex(), u32);
78  at += 4;
79 
80  /* NUL-terminated name */
81  std::string note_name = notes->read_content_local_str(at);
82  ROSE_ASSERT(note_name.size()+1 == name_size);
83  at += name_size;
84  at = (at+3) & ~0x3; /* payload is aligned on a four-byte offset */
85 
86  /* Set properties */
87  get_name()->set_string(note_name);
88  set_type(type);
89  p_payload = notes->read_content_local_ucl(at, payload_size);
90 
91  return at + payload_size;
92 }
93 
98 {
99  /* Find the section holding this note */
100  SgAsmElfNoteSection *notes = SageInterface::getEnclosingNode<SgAsmElfNoteSection>(this);
101  ROSE_ASSERT(notes!=NULL);
102  ROSE_ASSERT(at < notes->get_size());
103  SgAsmElfFileHeader *fhdr = dynamic_cast<SgAsmElfFileHeader*>(notes->get_header());
104  ROSE_ASSERT(fhdr!=NULL);
105 
106  /* Name size, including NUL termination */
107  uint32_t u32;
108  host_to_disk(fhdr->get_sex(), p_name->get_string().size()+1, &u32);
109  notes->write(f, at, 4, &u32);
110  at += 4;
111 
112  /* Payload size */
113  host_to_disk(fhdr->get_sex(), p_payload.size(), &u32);
114  notes->write(f, at, 4, &u32);
115  at += 4;
116 
117  /* Type */
118  host_to_disk(fhdr->get_sex(), p_type, &u32);
119  notes->write(f, at, 4, &u32);
120  at += 4;
121 
122  /* Name with NUL termination and padded to a multiple of four bytes */
123  std::string name = p_name->get_string();
124  while ((name.size()+1) % 4)
125  name += '\0';
126  notes->write(f, at, name.size()+1, name.c_str());
127  at += name.size()+1;
128 
129  /* Payload */
130  notes->write(f, at, p_payload);
131  at += p_payload.size();
132 
133  return at;
134 }
135 
139  rose_addr_t need = 12; /*namesize, payloadsize, type*/
140  need += p_name->get_string().size() + 1; /*name plus NUL terminator*/
141  need = (need+3) & ~0x3; /*pad to align payload on a four-byte offset */
142  need += p_payload.size();
143  return need;
144 }
145 
147 void
148 SgAsmElfNoteEntry::dump(FILE *f, const char *prefix, ssize_t idx) const
149 {
150  char p[4096];
151  if (idx>=0) {
152  sprintf(p, "%sElfNoteEntry[%zd]", prefix, idx);
153  } else {
154  sprintf(p, "%sElfNoteEntry", prefix);
155  }
156  const int w = std::max(1, DUMP_FIELD_WIDTH-(int)strlen(p));
157 
158  fprintf(f, "%s%-*s \"%s\"\n", p, w, "name", p_name->get_string(true).c_str());
159  fprintf(f, "%s%-*s %u\n", p, w, "type", p_type);
160  if (p_payload.size()>0) {
161  fprintf(f, "%s%-*s = %zu bytes\n", p, w, "extra", p_payload.size());
162  hexdump(f, 0, std::string(p)+"extra at ", p_payload);
163  }
164 }
165 
167 void
169 {
171  p_entries->set_parent(this);
172 }
173 
174 /* Parse existing notes */
177 {
179 
180  rose_addr_t at=0;
181  while (at < get_size()) {
182  SgAsmElfNoteEntry *note = new SgAsmElfNoteEntry(this);
183  at = note->parse(at);
184  }
185  return this;
186 }
187 
189 bool
191 {
192  bool reallocated = SgAsmElfSection::reallocate();
193 
194  /* How much space is needed by the notes? */
195  rose_addr_t need = 0;
196  for (size_t i=0; i<p_entries->get_entries().size(); i++) {
198  need += ent->calculate_size();
199  }
200 
201  /* Adjust the section/segment size */
202  if (need < get_size()) {
203  if (is_mapped()) {
204  ROSE_ASSERT(get_mapped_size()==get_size());
205  set_mapped_size(need);
206  }
207  set_size(need);
208  reallocated = true;
209  } else if (need > get_size()) {
211  reallocated = true;
212  }
213 
214  return reallocated;
215 }
216 
218 void
219 SgAsmElfNoteSection::unparse(std::ostream &f) const
220 {
222  ROSE_ASSERT(fhdr);
223 
224  rose_addr_t at = 0;
225  for (size_t i=0; i<p_entries->get_entries().size(); i++) {
227  at = ent->unparse(f, at);
228  }
229 }
230 
231 
233 void
234 SgAsmElfNoteSection::dump(FILE *f, const char *prefix, ssize_t idx) const
235 {
236  char p[4096];
237  if (idx>=0) {
238  sprintf(p, "%sElfNoteSection[%zd].", prefix, idx);
239  } else {
240  sprintf(p, "%sElfNoteSection.", prefix);
241  }
242 
243  SgAsmElfSection::dump(f, p, -1);
244 
245  for (size_t i=0; i<p_entries->get_entries().size(); i++) {
247  ent->dump(f, p, i);
248  }
249 }