void * SgAsmElfSectionTableEntry::encode(ByteOrder sex, Elf64SectionTableEntry_disk *disk) const { host_to_disk(sex, p_sh_name, &(disk->sh_name)); host_to_disk(sex, p_sh_type, &(disk->sh_type)); host_to_disk(sex, p_sh_flags, &(disk->sh_flags)); host_to_disk(sex, p_sh_addr, &(disk->sh_addr)); host_to_disk(sex, p_sh_offset, &(disk->sh_offset)); host_to_disk(sex, p_sh_size, &(disk->sh_size)); host_to_disk(sex, p_sh_link, &(disk->sh_link)); host_to_disk(sex, p_sh_info, &(disk->sh_info)); host_to_disk(sex, p_sh_addralign, &(disk->sh_addralign)); host_to_disk(sex, p_sh_entsize, &(disk->sh_entsize)); return disk; }
void * SgAsmElfSegmentTableEntry::encode(ByteOrder sex, Elf64SegmentTableEntry_disk *disk) const { host_to_disk(sex, p_type, &(disk->p_type)); host_to_disk(sex, p_offset, &(disk->p_offset)); host_to_disk(sex, p_vaddr, &(disk->p_vaddr)); host_to_disk(sex, p_paddr, &(disk->p_paddr)); host_to_disk(sex, p_filesz, &(disk->p_filesz)); host_to_disk(sex, p_memsz, &(disk->p_memsz)); host_to_disk(sex, p_flags, &(disk->p_flags)); host_to_disk(sex, p_align, &(disk->p_align)); return disk; }
/** Write a note at the specified offset to the section containing the note. Returns the offset for the first byte past the end * of the note. */ rose_addr_t SgAsmElfNoteEntry::unparse(std::ostream &f, rose_addr_t at) { /* Find the section holding this note */ SgAsmElfNoteSection *notes = SageInterface::getEnclosingNode<SgAsmElfNoteSection>(this); ROSE_ASSERT(notes!=NULL); ROSE_ASSERT(at < notes->get_size()); SgAsmElfFileHeader *fhdr = dynamic_cast<SgAsmElfFileHeader*>(notes->get_header()); ROSE_ASSERT(fhdr!=NULL); /* Name size, including NUL termination */ uint32_t u32; host_to_disk(fhdr->get_sex(), p_name->get_string().size()+1, &u32); notes->write(f, at, 4, &u32); at += 4; /* Payload size */ host_to_disk(fhdr->get_sex(), p_payload.size(), &u32); notes->write(f, at, 4, &u32); at += 4; /* Type */ host_to_disk(fhdr->get_sex(), p_type, &u32); notes->write(f, at, 4, &u32); at += 4; /* Name with NUL termination and padded to a multiple of four bytes */ std::string name = p_name->get_string(); while ((name.size()+1) % 4) name += '\0'; notes->write(f, at, name.size()+1, name.c_str()); at += name.size()+1; /* Payload */ notes->write(f, at, p_payload); at += p_payload.size(); return at; }
void * SgAsmElfSymbol::encode(ByteOrder sex, Elf64SymbolEntry_disk *disk) const { rose_addr_t st_name = p_name->get_offset(); ROSE_ASSERT(st_name!=SgAsmGenericString::unallocated); host_to_disk(sex, st_name, &(disk->st_name)); host_to_disk(sex, p_st_info, &(disk->st_info)); host_to_disk(sex, p_st_res1, &(disk->st_res1)); host_to_disk(sex, p_st_shndx, &(disk->st_shndx)); host_to_disk(sex, p_st_size, &(disk->st_size)); host_to_disk(sex, get_value(), &(disk->st_value)); return disk; }
/** Unparses the section into the optional output stream and returns the number of bytes written. If there is no output stream * we still go through the actions but don't write anything. This is the only way to determine the amount of memory required * to store the section since the section is run-length encoded. */ rose_addr_t SgAsmElfEHFrameSection::unparse(std::ostream *fp) const { SgAsmElfFileHeader *fhdr = get_elf_header(); ROSE_ASSERT(fhdr!=NULL); rose_addr_t at=0; uint32_t u32_disk; uint64_t u64_disk; for (size_t i=0; i<get_ci_entries()->get_entries().size(); i++) { rose_addr_t last_cie_offset = at; SgAsmElfEHFrameEntryCI *cie = get_ci_entries()->get_entries()[i]; std::string s = cie->unparse(this); if (s.size()<0xffffffff) { host_to_disk(fhdr->get_sex(), s.size(), &u32_disk); if (fp) write(*fp, at, 4, &u32_disk); at += 4; } else { u32_disk = 0xffffffff; if (fp) write(*fp, at, 4, &u32_disk); at += 4; host_to_disk(fhdr->get_sex(), s.size(), &u64_disk); if (fp) write(*fp, at, 8, &u64_disk); at += 8; } if (fp) write(*fp, at, s); at += s.size(); for (size_t j=0; j<cie->get_fd_entries()->get_entries().size(); j++) { SgAsmElfEHFrameEntryFD *fde = cie->get_fd_entries()->get_entries()[j]; std::string s = fde->unparse(this, cie); /* Record size, not counting run-length coded size field, but counting CIE back offset. */ rose_addr_t record_size = 4 + s.size(); if (record_size<0xffffffff) { host_to_disk(fhdr->get_sex(), record_size, &u32_disk); if (fp) write(*fp, at, 4, &u32_disk); at += 4; } else { u32_disk = 0xffffffff; if (fp) write(*fp, at, 4, &u32_disk); at += 4; host_to_disk(fhdr->get_sex(), record_size, &u64_disk); if (fp) write(*fp, at, 8, &u64_disk); at += 8; } /* CIE back offset. Number of bytes from the beginning of the current CIE record (including the Size fields) to * the beginning of the FDE record (excluding the Size fields but including the CIE back offset). */ rose_addr_t cie_back_offset = at - last_cie_offset; host_to_disk(fhdr->get_sex(), cie_back_offset, &u32_disk); if (fp) write(*fp, at, 4, &u32_disk); at += 4; /* The FDE record itself */ if (fp) write(*fp, at, s); at += s.size(); } } /* Write a zero length to indicate the end of the CIE list */ u32_disk = 0; if (fp) write(*fp, at, 4, &u32_disk); at += 4; return at; }