/* * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include #include #include #include namespace android { namespace elf64 { void Elf64Writer::WriteElf64File(const Elf64Binary& elf64Binary, const std::string& fileName) { std::cout << "Writing ELF64 binary to file " << fileName << std::endl; Elf64Writer elf64Writer(fileName); elf64Writer.WriteHeader(elf64Binary.ehdr); elf64Writer.WriteProgramHeaders(elf64Binary.phdrs, elf64Binary.ehdr.e_phoff); elf64Writer.WriteSections(elf64Binary.sections, elf64Binary.shdrs); elf64Writer.WriteSectionHeaders(elf64Binary.shdrs, elf64Binary.ehdr.e_shoff); } Elf64Writer::Elf64Writer(const std::string& fileName) { elf64stream.open(fileName.c_str(), std::ofstream::out | std::ofstream::binary); if (!elf64stream) { std::cerr << "Failed to open the file: " << fileName << std::endl; exit(-1); } } void Elf64Writer::WriteHeader(const Elf64_Ehdr& ehdr) { Write((char*)&ehdr, sizeof(ehdr)); } void Elf64Writer::WriteProgramHeaders(const std::vector& phdrs, const Elf64_Off phoff) { elf64stream.seekp(phoff); for (int i = 0; i < phdrs.size(); i++) { Write((char*)&phdrs[i], sizeof(phdrs[i])); } } void Elf64Writer::WriteSectionHeaders(const std::vector& shdrs, const Elf64_Off shoff) { elf64stream.seekp(shoff); for (int i = 0; i < shdrs.size(); i++) { Write((char*)&shdrs[i], sizeof(shdrs[i])); } } void Elf64Writer::WriteSections(const std::vector& sections, const std::vector& shdrs) { for (int i = 0; i < sections.size(); i++) { if (shdrs[i].sh_type == SHT_NOBITS) { // Skip .bss section because it is empty. continue; } // Move the cursor position to offset provided by the section header. elf64stream.seekp(shdrs[i].sh_offset); Write(sections[i].data.data(), sections[i].size); } } void Elf64Writer::Write(const char* const data, const std::streamsize size) { elf64stream.write(data, size); if (!elf64stream) { std::cerr << "Failed to write [" << size << "] bytes" << std::endl; exit(-1); } } } // namespace elf64 } // namespace android