1 /*
2  * Copyright (C) 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include <libelf64/elf64.h>
20 
21 #include <stdint.h>
22 #include <fstream>
23 #include <string>
24 #include <vector>
25 
26 #include <elf.h>
27 
28 namespace android {
29 namespace elf64 {
30 
31 // Class to write elf64 binaries to files. It provides methods
32 // to write the different parts of the efl64 binary:
33 //
34 // - Executable Header (Elf64_Ehdr)
35 // - Program Headers (Elf64_Phdr)
36 // - Section Headers (Elf64_Shdr)
37 // - Sections (content)
38 //
39 // The basic usage of the library is:
40 //
41 //       android::elf64::Elf64Binary elf64Binary;
42 //       // Populate elf64Binary
43 //       elf64Binary.ehdr.e_phoff = 0xBEEFFADE
44 //       std::string fileName("new_binary.so");
45 //       android::elf64::Elf64Writer::WriteElfFile(elf64Binary, fileName);
46 //
47 // If it is necessary to have more control about the different parts
48 // that need to be written or omitted, we can use:
49 //
50 //       android::elf64::Elf64Binary elf64Binary;
51 //       // Populate elf64Binary
52 //
53 //       std::string fileName("new_binary.so");
54 //       Elf64Writer elf64Writer(fileName);
55 //
56 //       elf64Writer.WriteHeader(elf64Binary.ehdr);
57 //       elf64Writer.WriteProgramHeaders(elf64Binary.phdrs, 0xBEEF);
58 //       elf64Writer.WriteSectionHeaders(elf64Binary.shdrs, 0xFADE);
59 //       elf64Writer.WriteSections(elf64Binary.sections, elf64Binary.shdrs);
60 //
61 class Elf64Writer {
62   public:
63     Elf64Writer(const std::string& fileName);
64 
65     void WriteHeader(const Elf64_Ehdr& ehdr);
66     void WriteProgramHeaders(const std::vector<Elf64_Phdr>& phdrs, const Elf64_Off phoff);
67     void WriteSectionHeaders(const std::vector<Elf64_Shdr>& shdrs, const Elf64_Off shoff);
68     void WriteSections(const std::vector<Elf64_Sc>& sections, const std::vector<Elf64_Shdr>& shdrs);
69 
70     static void WriteElf64File(const Elf64Binary& elf64Binary, const std::string& fileName);
71 
72   private:
73     std::ofstream elf64stream;
74     void Write(const char* const data, const std::streamsize size);
75 };
76 
77 }  // namespace elf64
78 }  // namespace android
79