ROSE  0.9.6a
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ElfSection.C
Go to the documentation of this file.
1 /* ELF Sections (SgAsmElfSection and related classes) */
2 
3 #include "sage3basic.h"
4 
6 void
8 {
9  set_synthesized(false);
11 }
12 
19 {
20  ROSE_ASSERT(shdr);
21  ROSE_ASSERT(strsec);
22  ROSE_ASSERT(id>=0);
23 
24  /* Purpose */
25  switch (shdr->get_sh_type()) {
28  break;
31  break;
35  break;
36  default:
38  break;
39  }
40 
41  /* File mapping */
42  set_offset(shdr->get_sh_offset());
45  set_size(0);
46  } else {
47  set_size(shdr->get_sh_size());
48  }
50  grab_content();
51 
52  /* Memory mapping */
53  if (shdr->get_sh_addr() > 0) {
55  set_mapped_actual_va(0); /*will be assigned by Loader*/
57  set_mapped_rperm(true);
58  set_mapped_wperm((shdr->get_sh_flags() & 0x01) == 0x01);
59  set_mapped_xperm((shdr->get_sh_flags() & 0x04) == 0x04);
61  } else {
63  set_mapped_actual_va(0); /*will be assigned by Loader*/
64  set_mapped_size(0);
65  set_mapped_rperm(false);
66  set_mapped_wperm(false);
67  set_mapped_xperm(false);
69  }
70 
71  /* Name. This has to be near the end because possibly strsec==this, in which case we have to call set_size() to extend the
72  * section to be large enough before we can try to look up the name. */
73  set_id(id);
74  set_name(new SgAsmStoredString(strsec->get_strtab(), shdr->get_sh_name()));
75 
76  /* Add section table entry to section */
77  set_section_entry(shdr);
78  shdr->set_parent(this);
79 
80  return this;
81 }
82 
86 {
87  if (!mmap_only) {
88  /* Purpose */
90 
91  /* File mapping */
92  set_offset(shdr->get_offset());
93  set_size(shdr->get_filesz());
95  grab_content();
96 
97  /* Name */
98  char name[128];
99  switch (shdr->get_type()) {
100  case SgAsmElfSegmentTableEntry::PT_LOAD: strcpy(name, "LOAD"); break;
101  case SgAsmElfSegmentTableEntry::PT_DYNAMIC: strcpy(name, "DYNAMIC"); break;
102  case SgAsmElfSegmentTableEntry::PT_INTERP: strcpy(name, "INTERP"); break;
103  case SgAsmElfSegmentTableEntry::PT_NOTE: strcpy(name, "NOTE"); break;
104  case SgAsmElfSegmentTableEntry::PT_SHLIB: strcpy(name, "SHLIB"); break;
105  case SgAsmElfSegmentTableEntry::PT_PHDR: strcpy(name, "PHDR"); break;
106  case SgAsmElfSegmentTableEntry::PT_TLS: strcpy(name, "TLS"); break;
107  case SgAsmElfSegmentTableEntry::PT_GNU_EH_FRAME: strcpy(name, "EH_FRAME"); break;
108  case SgAsmElfSegmentTableEntry::PT_GNU_STACK: strcpy(name, "GNU_STACK"); break;
109  case SgAsmElfSegmentTableEntry::PT_GNU_RELRO: strcpy(name, "GNU_RELRO"); break;
110  case SgAsmElfSegmentTableEntry::PT_PAX_FLAGS: strcpy(name, "PAX_FLAGS"); break;
111  case SgAsmElfSegmentTableEntry::PT_SUNWBSS: strcpy(name, "SUNWBSS"); break;
112  case SgAsmElfSegmentTableEntry::PT_SUNWSTACK: strcpy(name, "SUNWSTACK"); break;
113  default: sprintf(name, "PT_0x%08x", shdr->get_type()); break;
114  }
115  sprintf(name+strlen(name), "#%zu", shdr->get_index());
116  set_name(new SgAsmBasicString(name));
117  }
118 
119  /* Memory mapping */
121  set_mapped_actual_va(0); /*will be assigned by Loader*/
122  set_mapped_size(shdr->get_memsz());
127 
128  /* Add segment table entry to section */
129  set_segment_entry(shdr);
130  shdr->set_parent(this);
131 
132  return this;
133 }
134 
138 {
139  return dynamic_cast<SgAsmElfFileHeader*>(get_header());
140 }
141 
161 SgAsmElfSection::calculate_sizes(size_t r32size, size_t r64size, /*size of required parts*/
162  const std::vector<size_t> &optsizes, /*size of optional parts and number of parts parsed*/
163  size_t *entsize, size_t *required, size_t *optional, size_t *entcount) const
164 {
165  size_t struct_size = 0;
166  size_t extra_size = 0;
167  size_t entry_size = 0;
168  size_t nentries = 0;
170 
171  /* Assume ELF Section Table Entry is correct for now for the size of each entry in the table. */
172  ROSE_ASSERT(get_section_entry()!=NULL);
173  entry_size = get_section_entry()->get_sh_entsize();
174 
175  /* Size of required part of each entry */
176  if (0==r32size && 0==r64size) {
177  /* Probably called by four-argument SgAsmElfSection::calculate_sizes and we don't know the sizes of the required parts
178  * because there isn't a parser for this type of section, or the section doesn't contain a table. In the latter case
179  * the ELF Section Table has a zero sh_entsize and we'll treat the section as if it were a table with one huge entry.
180  * Otherwise we'll assume that the struct size is the same as the sh_entsize and there's no optional data. */
181  struct_size = entry_size>0 ? entry_size : get_size();
182  } else if (4==fhdr->get_word_size()) {
183  struct_size = r32size;
184  } else if (8==fhdr->get_word_size()) {
185  struct_size = r64size;
186  } else {
187  throw FormatError("bad ELF word size");
188  }
189 
190  /* Entire entry should be at least large enough for the required part. This also takes care of the case when the ELF
191  * Section Table Entry has a zero-valued sh_entsize */
192  entry_size = std::max(entry_size, struct_size);
193 
194  /* Size of optional parts. If we've parsed the table then use the largest optional part, otherwise assume the entry from
195  * the ELF Section Table is correct. */
196  nentries = optsizes.size();
197  if (nentries>0) {
198  for (size_t i=0; i<nentries; i++) {
199  extra_size = std::max(extra_size, optsizes[i]);
200  }
201  entry_size = std::min(entry_size, struct_size+extra_size);
202  } else {
203  extra_size = entry_size - struct_size;
204  nentries = entry_size>0 ? get_size() / entry_size : 0;
205  }
206 
207  /* Return values */
208  if (entsize)
209  *entsize = entry_size;
210  if (required)
211  *required = struct_size;
212  if (optional)
213  *optional = extra_size;
214  if (entcount)
215  *entcount = nentries;
216  return entry_size * nentries;
217 }
218 
228 SgAsmElfSection::calculate_sizes(size_t *entsize, size_t *required, size_t *optional, size_t *entcount) const
229 {
230  return calculate_sizes(0, 0, std::vector<size_t>(), entsize, required, optional, entcount);
231 }
232 
234 bool
236 {
237  bool reallocated = false;
240 
241  /* Change section size if this section was defined in the ELF Section Table */
242  if (sechdr!=NULL) {
243  rose_addr_t need = calculate_sizes(NULL, NULL, NULL, NULL);
244  if (need < get_size()) {
245  if (is_mapped()) {
246  ROSE_ASSERT(get_mapped_size()==get_size());
247  set_mapped_size(need);
248  }
249  set_size(need);
250  reallocated = true;
251  } else if (need > get_size()) {
253  reallocated = true;
254  }
255  }
256 
257  /* Update entry in the ELF Section Table and/or ELF Segment Table */
258  if (sechdr)
259  sechdr->update_from_section(this);
260  if (seghdr)
261  seghdr->update_from_section(this);
262 
263  return reallocated;
264 }
265 
267 void
268 SgAsmElfSection::dump(FILE *f, const char *prefix, ssize_t idx) const
269 {
270  char p[4096];
271  if (idx>=0) {
272  sprintf(p, "%sElfSection[%zd].", prefix, idx);
273  } else {
274  sprintf(p, "%sElfSection.", prefix);
275  }
276  int w = std::max(1, DUMP_FIELD_WIDTH-(int)strlen(p));
277 
278  SgAsmGenericSection::dump(f, p, -1);
279 
280  if (get_section_entry())
281  get_section_entry()->dump(f, p, -1);
282  if (get_segment_entry())
283  get_segment_entry()->dump(f, p, -1);
284 
285  if (p_linked_section) {
286  fprintf(f, "%s%-*s = [%d] \"%s\"\n", p, w, "linked_to",
288  } else {
289  fprintf(f, "%s%-*s = NULL\n", p, w, "linked_to");
290  }
291 
292  if (variantT() == V_SgAsmElfSection) //unless a base class
293  hexdump(f, 0, std::string(p)+"data at ", p_data);
294 }