* Serialize the ELF file to the output buffer. Return < 0 on error, * 0 on success. */
| 1135 | * 0 on success. |
| 1136 | */ |
| 1137 | int elf_writer_serialize(struct elf_writer *ew, struct buffer *out) |
| 1138 | { |
| 1139 | Elf64_Half i; |
| 1140 | Elf64_Xword metadata_size; |
| 1141 | Elf64_Xword program_size; |
| 1142 | Elf64_Off shstroffset; |
| 1143 | size_t shstrlen; |
| 1144 | struct buffer metadata; |
| 1145 | struct buffer phdrs; |
| 1146 | struct buffer data; |
| 1147 | struct buffer *strtab; |
| 1148 | |
| 1149 | INFO("Writing %zu sections.\n", ew->num_secs); |
| 1150 | |
| 1151 | /* Perform any necessary work for special sections. */ |
| 1152 | fixup_symbol_table(ew); |
| 1153 | fixup_relocations(ew); |
| 1154 | |
| 1155 | /* Determine size of sections to be written. */ |
| 1156 | program_size = 0; |
| 1157 | /* Start with 1 byte for first byte of section header string table. */ |
| 1158 | shstrlen = 1; |
| 1159 | for (i = 0; i < ew->num_secs; i++) { |
| 1160 | struct elf_writer_section *sec = &ew->sections[i]; |
| 1161 | |
| 1162 | if (sec->shdr.sh_flags & SHF_ALLOC) { |
| 1163 | if (!section_consecutive(ew, i)) |
| 1164 | ew->ehdr.e_phnum++; |
| 1165 | } |
| 1166 | |
| 1167 | program_size += buffer_size(&sec->content); |
| 1168 | |
| 1169 | /* Keep track of the length sections' names. */ |
| 1170 | if (sec->name != NULL) { |
| 1171 | sec->shdr.sh_name = shstrlen; |
| 1172 | shstrlen += strlen(sec->name) + 1; |
| 1173 | } |
| 1174 | } |
| 1175 | ew->ehdr.e_shnum = ew->num_secs; |
| 1176 | metadata_size = 0; |
| 1177 | metadata_size += ew->ehdr.e_ehsize; |
| 1178 | metadata_size += (Elf64_Xword)ew->ehdr.e_shnum * ew->ehdr.e_shentsize; |
| 1179 | metadata_size += (Elf64_Xword)ew->ehdr.e_phnum * ew->ehdr.e_phentsize; |
| 1180 | shstroffset = metadata_size; |
| 1181 | /* Align up section header string size and metadata size to 4KiB */ |
| 1182 | metadata_size = ALIGN_UP(metadata_size + shstrlen, 4096); |
| 1183 | |
| 1184 | if (buffer_create(out, metadata_size + program_size, "elfout")) { |
| 1185 | ERROR("Could not create output buffer for ELF.\n"); |
| 1186 | return -1; |
| 1187 | } |
| 1188 | |
| 1189 | INFO("Created %zu output buffer for ELF file.\n", buffer_size(out)); |
| 1190 | |
| 1191 | /* |
| 1192 | * Write out ELF header. Section headers come right after ELF header |
| 1193 | * followed by the program headers. Buffers need to be created first |
| 1194 | * to do the writing. |
no test coverage detected