/** Returns info about the size of the entries based on information already available. Any or all arguments may be null * pointers if the caller is not interested in the value. */ rose_addr_t SgAsmElfSectionTable::calculate_sizes(size_t *entsize, size_t *required, size_t *optional, size_t *entcount) const { SgAsmElfFileHeader *fhdr = dynamic_cast<SgAsmElfFileHeader*>(get_header()); ROSE_ASSERT(fhdr!=NULL); size_t struct_size = 0; size_t extra_size = fhdr->get_shextrasz(); size_t entry_size = 0; size_t nentries = 0; /* Size of required part of each entry */ if (4==fhdr->get_word_size()) { struct_size = sizeof(SgAsmElfSectionTableEntry::Elf32SectionTableEntry_disk); } else if (8==fhdr->get_word_size()) { struct_size = sizeof(SgAsmElfSectionTableEntry::Elf64SectionTableEntry_disk); } else { throw FormatError("bad ELF word size"); } /* Entire entry should be at least large enough for the required part. */ entry_size = struct_size; /* Size of optional parts. If we've parsed the table then use the largest optional part, otherwise assume the entry from * the ELF File Header is correct. */ SgAsmGenericSectionPtrList sections = fhdr->get_sections()->get_sections(); for (size_t i=0; i<sections.size(); i++) { SgAsmElfSection *elfsec = dynamic_cast<SgAsmElfSection*>(sections[i]); if (elfsec && elfsec->get_section_entry()) { ROSE_ASSERT(elfsec->get_id()>=0); nentries = std::max(nentries, (size_t)elfsec->get_id()+1); extra_size = std::max(extra_size, elfsec->get_section_entry()->get_extra().size()); } } /* Total number of entries. Either we haven't parsed the section table yet (nor created the sections it defines) or we * have. In the former case we use the setting from the ELF File Header. Otherwise the table has to be large enough to * store the section with the largest ID (ID also serves as the index into the ELF Section Table). */ if (0==nentries) nentries = fhdr->get_e_shnum(); /* Return values */ if (entsize) *entsize = entry_size; if (required) *required = struct_size; if (optional) *optional = extra_size; if (entcount) *entcount = nentries; return entry_size * nentries; }
/** Attaches a previously unattached ELF Section to the section table. If @p section is an ELF String Section * (SgAsmElfStringSection) that contains an ELF String Table (SgAsmElfStringTable) and the ELF Section Table has no * associated string table then the @p section will be used as the string table to hold the section names. * * This method complements SgAsmElfSection::init_from_section_table. This method initializes the section table from the * section while init_from_section_table() initializes the section from the section table. * * Returns the new section table entry linked into the AST. */ SgAsmElfSectionTableEntry * SgAsmElfSectionTable::add_section(SgAsmElfSection *section) { ROSE_ASSERT(section!=NULL); ROSE_ASSERT(section->get_file()==get_file()); ROSE_ASSERT(section->get_header()==get_header()); ROSE_ASSERT(section->get_section_entry()==NULL); /* must not be in the section table yet */ SgAsmElfFileHeader *fhdr = dynamic_cast<SgAsmElfFileHeader*>(get_header()); ROSE_ASSERT(fhdr!=NULL); /* Assign an ID if there isn't one yet */ if (section->get_id()<0) { int id = fhdr->get_e_shnum(); fhdr->set_e_shnum(id+1); section->set_id(id); } /* If the supplied section is a string table and the ELF Section Table doesn't have a string table associated with it yet, * then use the supplied section as the string table to hold the names of the sections. When this happens, all sections * that are already defined in the ELF Section Table should have their names moved into the new string table. */ SgAsmElfStringSection *strsec = NULL; if (fhdr->get_e_shstrndx()==0) { strsec = dynamic_cast<SgAsmElfStringSection*>(section); if (strsec) { fhdr->set_e_shstrndx(section->get_id()); SgAsmGenericSectionList *all = fhdr->get_sections(); for (size_t i=0; i<all->get_sections().size(); i++) { SgAsmElfSection *s = dynamic_cast<SgAsmElfSection*>(all->get_sections()[i]); if (s && s->get_id()>=0 && s->get_section_entry()!=NULL) { s->allocate_name_to_storage(strsec); } } } } else { strsec = dynamic_cast<SgAsmElfStringSection*>(fhdr->get_section_by_id(fhdr->get_e_shstrndx())); ROSE_ASSERT(strsec!=NULL); } /* Make sure the name is in the correct string table */ if (strsec) section->allocate_name_to_storage(strsec); /* Create a new section table entry. */ SgAsmElfSectionTableEntry *shdr = new SgAsmElfSectionTableEntry; shdr->update_from_section(section); section->set_section_entry(shdr); return shdr; }