1 //===- Writer.cpp ---------------------------------------------------------===// 2 // 3 // The LLVM Linker 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "Chunks.h" 11 #include "Config.h" 12 #include "Error.h" 13 #include "SymbolTable.h" 14 #include "Writer.h" 15 16 #include "llvm/ADT/DenseMap.h" 17 #include "llvm/MC/StringTableBuilder.h" 18 #include "llvm/Support/FileOutputBuffer.h" 19 20 using namespace llvm; 21 using namespace llvm::ELF; 22 using namespace llvm::object; 23 24 using namespace lld; 25 using namespace lld::elf2; 26 27 static const int PageSize = 4096; 28 29 namespace { 30 // OutputSection represents a section in an output file. It's a 31 // container of chunks. OutputSection and Chunk are 1:N relationship. 32 // Chunks cannot belong to more than one OutputSections. The writer 33 // creates multiple OutputSections and assign them unique, 34 // non-overlapping file offsets and VAs. 35 template <class ELFT> class OutputSection { 36 public: 37 typedef typename llvm::object::ELFFile<ELFT>::uintX_t uintX_t; 38 typedef typename llvm::object::ELFFile<ELFT>::Elf_Shdr Elf_Shdr; 39 40 OutputSection(StringRef Name) : Name(Name) { 41 memset(&Header, 0, sizeof(Elf_Shdr)); 42 } 43 void setVA(uintX_t); 44 void setFileOffset(uintX_t); 45 void addSectionChunk(SectionChunk<ELFT> *C); 46 std::vector<Chunk *> &getChunks() { return Chunks; } 47 void writeHeaderTo(Elf_Shdr *SHdr); 48 StringRef getName() { return Name; } 49 void setNameOffset(uintX_t Offset) { Header.sh_name = Offset; } 50 51 // Returns the size of the section in the output file. 52 uintX_t getSize() { return Header.sh_size; } 53 uintX_t getFlags() { return Header.sh_flags; } 54 uintX_t getOffset() { return Header.sh_offset; } 55 56 private: 57 StringRef Name; 58 Elf_Shdr Header; 59 std::vector<Chunk *> Chunks; 60 }; 61 62 // The writer writes a SymbolTable result to a file. 63 template <class ELFT> class Writer { 64 public: 65 typedef typename llvm::object::ELFFile<ELFT>::uintX_t uintX_t; 66 typedef typename llvm::object::ELFFile<ELFT>::Elf_Shdr Elf_Shdr; 67 Writer(SymbolTable *T) : Symtab(T) {} 68 void run(); 69 70 private: 71 void createSections(); 72 void assignAddresses(); 73 void openFile(StringRef OutputPath); 74 void writeHeader(); 75 void writeSections(); 76 77 SymbolTable *Symtab; 78 std::unique_ptr<llvm::FileOutputBuffer> Buffer; 79 llvm::SpecificBumpPtrAllocator<OutputSection<ELFT>> CAlloc; 80 std::vector<OutputSection<ELFT> *> OutputSections; 81 82 uintX_t FileSize; 83 uintX_t SizeOfHeaders; 84 uintX_t SectionHeaderOff; 85 uintX_t StringTableOff; 86 unsigned StringTableIndex; 87 StringTableBuilder StrTabBuilder; 88 unsigned NumSections; 89 90 std::vector<std::unique_ptr<Chunk>> Chunks; 91 }; 92 } // anonymous namespace 93 94 namespace lld { 95 namespace elf2 { 96 97 template <class ELFT> 98 void writeResult(SymbolTable *Symtab) { Writer<ELFT>(Symtab).run(); } 99 100 template void writeResult<ELF32LE>(SymbolTable *); 101 template void writeResult<ELF32BE>(SymbolTable *); 102 template void writeResult<ELF64LE>(SymbolTable *); 103 template void writeResult<ELF64BE>(SymbolTable *); 104 105 } // namespace elf2 106 } // namespace lld 107 108 // The main function of the writer. 109 template <class ELFT> void Writer<ELFT>::run() { 110 createSections(); 111 assignAddresses(); 112 openFile(Config->OutputFile); 113 writeHeader(); 114 writeSections(); 115 error(Buffer->commit()); 116 } 117 118 template <class ELFT> void OutputSection<ELFT>::setVA(uintX_t VA) { 119 Header.sh_addr = VA; 120 } 121 122 template <class ELFT> void OutputSection<ELFT>::setFileOffset(uintX_t Off) { 123 if (Header.sh_size == 0) 124 return; 125 Header.sh_offset = Off; 126 } 127 128 template <class ELFT> 129 void OutputSection<ELFT>::addSectionChunk(SectionChunk<ELFT> *C) { 130 Chunks.push_back(C); 131 uintX_t Off = Header.sh_size; 132 Off = RoundUpToAlignment(Off, C->getAlign()); 133 C->setOutputSectionOff(Off); 134 Off += C->getSize(); 135 Header.sh_size = Off; 136 Header.sh_type = C->getSectionHdr()->sh_type; 137 Header.sh_flags |= C->getSectionHdr()->sh_flags; 138 } 139 140 template <class ELFT> void OutputSection<ELFT>::writeHeaderTo(Elf_Shdr *SHdr) { 141 *SHdr = Header; 142 } 143 144 namespace { 145 template <bool Is64Bits> struct SectionKey { 146 typedef typename std::conditional<Is64Bits, uint64_t, uint32_t>::type uintX_t; 147 StringRef Name; 148 uint32_t sh_type; 149 uintX_t sh_flags; 150 }; 151 } 152 namespace llvm { 153 template <bool Is64Bits> struct DenseMapInfo<SectionKey<Is64Bits>> { 154 static SectionKey<Is64Bits> getEmptyKey() { 155 return SectionKey<Is64Bits>{DenseMapInfo<StringRef>::getEmptyKey(), 0, 0}; 156 } 157 static SectionKey<Is64Bits> getTombstoneKey() { 158 return SectionKey<Is64Bits>{DenseMapInfo<StringRef>::getTombstoneKey(), 0, 159 0}; 160 } 161 static unsigned getHashValue(const SectionKey<Is64Bits> &Val) { 162 return hash_combine(Val.Name, Val.sh_type, Val.sh_flags); 163 } 164 static bool isEqual(const SectionKey<Is64Bits> &LHS, 165 const SectionKey<Is64Bits> &RHS) { 166 return DenseMapInfo<StringRef>::isEqual(LHS.Name, RHS.Name) && 167 LHS.sh_type == RHS.sh_type && LHS.sh_flags == RHS.sh_flags; 168 } 169 }; 170 } 171 172 // Create output section objects and add them to OutputSections. 173 template <class ELFT> void Writer<ELFT>::createSections() { 174 SmallDenseMap<SectionKey<ELFT::Is64Bits>, OutputSection<ELFT> *> Map; 175 for (std::unique_ptr<ObjectFileBase> &FileB : Symtab->ObjectFiles) { 176 auto &File = cast<ObjectFile<ELFT>>(*FileB); 177 for (SectionChunk<ELFT> *C : File.getChunks()) { 178 const Elf_Shdr *H = C->getSectionHdr(); 179 SectionKey<ELFT::Is64Bits> Key{C->getSectionName(), H->sh_type, 180 H->sh_flags}; 181 OutputSection<ELFT> *&Sec = Map[Key]; 182 if (!Sec) { 183 Sec = new (CAlloc.Allocate()) OutputSection<ELFT>(C->getSectionName()); 184 OutputSections.push_back(Sec); 185 } 186 Sec->addSectionChunk(C); 187 } 188 } 189 } 190 191 template <class ELFT> 192 static bool compSec(OutputSection<ELFT> *A, OutputSection<ELFT> *B) { 193 // Place SHF_ALLOC sections first. 194 return (A->getFlags() & SHF_ALLOC) && !(B->getFlags() & SHF_ALLOC); 195 } 196 197 // Visits all sections to assign incremental, non-overlapping RVAs and 198 // file offsets. 199 template <class ELFT> void Writer<ELFT>::assignAddresses() { 200 SizeOfHeaders = RoundUpToAlignment(sizeof(Elf_Ehdr_Impl<ELFT>), PageSize); 201 uintX_t VA = 0x1000; // The first page is kept unmapped. 202 uintX_t FileOff = SizeOfHeaders; 203 204 std::stable_sort(OutputSections.begin(), OutputSections.end(), compSec<ELFT>); 205 206 for (OutputSection<ELFT> *Sec : OutputSections) { 207 if (Sec->getFlags() & SHF_ALLOC) { 208 Sec->setVA(VA); 209 VA += RoundUpToAlignment(Sec->getSize(), PageSize); 210 } 211 Sec->setFileOffset(FileOff); 212 FileOff += RoundUpToAlignment(Sec->getSize(), 8); 213 StrTabBuilder.add(Sec->getName()); 214 } 215 216 // Regular sections. 217 NumSections = OutputSections.size(); 218 219 // First dummy section. 220 NumSections++; 221 222 // String table. 223 StrTabBuilder.add(".strtab"); 224 StringTableIndex = NumSections; 225 StringTableOff = FileOff; 226 StrTabBuilder.finalize(StringTableBuilder::ELF); 227 FileOff += StrTabBuilder.data().size(); 228 NumSections++; 229 230 FileOff += OffsetToAlignment(FileOff, ELFT::Is64Bits ? 8 : 4); 231 232 // Add space for section headers. 233 SectionHeaderOff = FileOff; 234 FileOff += NumSections * sizeof(Elf_Shdr_Impl<ELFT>); 235 FileSize = SizeOfHeaders + RoundUpToAlignment(FileOff - SizeOfHeaders, 8); 236 } 237 238 template <class ELFT> void Writer<ELFT>::writeHeader() { 239 uint8_t *Buf = Buffer->getBufferStart(); 240 auto *EHdr = reinterpret_cast<Elf_Ehdr_Impl<ELFT> *>(Buf); 241 EHdr->e_ident[EI_MAG0] = 0x7F; 242 EHdr->e_ident[EI_MAG1] = 0x45; 243 EHdr->e_ident[EI_MAG2] = 0x4C; 244 EHdr->e_ident[EI_MAG3] = 0x46; 245 EHdr->e_ident[EI_CLASS] = ELFT::Is64Bits ? ELFCLASS64 : ELFCLASS32; 246 EHdr->e_ident[EI_DATA] = ELFT::TargetEndianness == llvm::support::little 247 ? ELFDATA2LSB 248 : ELFDATA2MSB; 249 EHdr->e_ident[EI_VERSION] = EV_CURRENT; 250 EHdr->e_ident[EI_OSABI] = ELFOSABI_NONE; 251 252 EHdr->e_type = ET_EXEC; 253 auto &FirstObj = cast<ObjectFile<ELFT>>(*Symtab->ObjectFiles[0]); 254 EHdr->e_machine = FirstObj.getObj()->getHeader()->e_machine; 255 EHdr->e_version = EV_CURRENT; 256 EHdr->e_entry = 0x401000; 257 EHdr->e_phoff = sizeof(Elf_Ehdr_Impl<ELFT>); 258 EHdr->e_shoff = SectionHeaderOff; 259 EHdr->e_ehsize = sizeof(Elf_Ehdr_Impl<ELFT>); 260 EHdr->e_phentsize = sizeof(Elf_Phdr_Impl<ELFT>); 261 EHdr->e_phnum = 1; 262 EHdr->e_shentsize = sizeof(Elf_Shdr_Impl<ELFT>); 263 EHdr->e_shnum = NumSections; 264 EHdr->e_shstrndx = StringTableIndex; 265 266 auto PHdrs = reinterpret_cast<Elf_Phdr_Impl<ELFT> *>(Buf + EHdr->e_phoff); 267 PHdrs->p_type = PT_LOAD; 268 PHdrs->p_flags = PF_R | PF_X; 269 PHdrs->p_offset = 0x0000; 270 PHdrs->p_vaddr = 0x400000; 271 PHdrs->p_paddr = PHdrs->p_vaddr; 272 PHdrs->p_filesz = FileSize; 273 PHdrs->p_memsz = FileSize; 274 PHdrs->p_align = 0x4000; 275 276 auto SHdrs = reinterpret_cast<Elf_Shdr_Impl<ELFT> *>(Buf + EHdr->e_shoff); 277 // First entry is null. 278 ++SHdrs; 279 for (OutputSection<ELFT> *Sec : OutputSections) { 280 Sec->setNameOffset(StrTabBuilder.getOffset(Sec->getName())); 281 Sec->writeHeaderTo(SHdrs++); 282 } 283 284 // String table. 285 SHdrs->sh_name = StrTabBuilder.getOffset(".strtab"); 286 SHdrs->sh_type = SHT_STRTAB; 287 SHdrs->sh_flags = 0; 288 SHdrs->sh_addr = 0; 289 SHdrs->sh_offset = StringTableOff; 290 SHdrs->sh_size = StrTabBuilder.data().size(); 291 SHdrs->sh_link = 0; 292 SHdrs->sh_info = 0; 293 SHdrs->sh_addralign = 1; 294 SHdrs->sh_entsize = 0; 295 } 296 297 template <class ELFT> void Writer<ELFT>::openFile(StringRef Path) { 298 ErrorOr<std::unique_ptr<FileOutputBuffer>> BufferOrErr = 299 FileOutputBuffer::create(Path, FileSize, FileOutputBuffer::F_executable); 300 error(BufferOrErr, Twine("failed to open ") + Path); 301 Buffer = std::move(*BufferOrErr); 302 } 303 304 // Write section contents to a mmap'ed file. 305 template <class ELFT> void Writer<ELFT>::writeSections() { 306 uint8_t *Buf = Buffer->getBufferStart(); 307 for (OutputSection<ELFT> *Sec : OutputSections) { 308 uint8_t *SecBuf = Buf + Sec->getOffset(); 309 for (Chunk *C : Sec->getChunks()) 310 C->writeTo(SecBuf); 311 } 312 313 // String table. 314 StringRef Data = StrTabBuilder.data(); 315 memcpy(Buf + StringTableOff, Data.data(), Data.size()); 316 } 317