OLD | NEW |
1 //===- subzero/src/IceELFObjectWriter.cpp - ELF object file writer --------===// | 1 //===- subzero/src/IceELFObjectWriter.cpp - ELF object file writer --------===// |
2 // | 2 // |
3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 // | 9 // |
10 // This file defines the writer for ELF relocatable object files. | 10 // This file defines the writer for ELF relocatable object files. |
11 // | 11 // |
12 //===----------------------------------------------------------------------===// | 12 //===----------------------------------------------------------------------===// |
13 | 13 |
| 14 #include "llvm/Support/MathExtras.h" |
| 15 |
14 #include "assembler.h" | 16 #include "assembler.h" |
15 #include "IceDefs.h" | 17 #include "IceDefs.h" |
16 #include "IceELFObjectWriter.h" | 18 #include "IceELFObjectWriter.h" |
17 #include "IceELFSection.h" | 19 #include "IceELFSection.h" |
18 #include "IceELFStreamer.h" | 20 #include "IceELFStreamer.h" |
19 #include "IceGlobalContext.h" | 21 #include "IceGlobalContext.h" |
20 #include "IceGlobalInits.h" | 22 #include "IceGlobalInits.h" |
21 #include "IceOperand.h" | 23 #include "IceOperand.h" |
22 | 24 |
23 using namespace llvm::ELF; | 25 using namespace llvm::ELF; |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
96 T *ELFObjectWriter::createSection(const IceString &Name, Elf64_Word ShType, | 98 T *ELFObjectWriter::createSection(const IceString &Name, Elf64_Word ShType, |
97 Elf64_Xword ShFlags, Elf64_Xword ShAddralign, | 99 Elf64_Xword ShFlags, Elf64_Xword ShAddralign, |
98 Elf64_Xword ShEntsize) { | 100 Elf64_Xword ShEntsize) { |
99 assert(!SectionNumbersAssigned); | 101 assert(!SectionNumbersAssigned); |
100 T *NewSection = | 102 T *NewSection = |
101 new (Ctx.allocate<T>()) T(Name, ShType, ShFlags, ShAddralign, ShEntsize); | 103 new (Ctx.allocate<T>()) T(Name, ShType, ShFlags, ShAddralign, ShEntsize); |
102 ShStrTab->add(Name); | 104 ShStrTab->add(Name); |
103 return NewSection; | 105 return NewSection; |
104 } | 106 } |
105 | 107 |
| 108 ELFRelocationSection * |
| 109 ELFObjectWriter::createRelocationSection(bool IsELF64, |
| 110 const ELFSection *RelatedSection) { |
| 111 // Choice of RELA vs REL is actually separate from elf64 vs elf32, |
| 112 // but in practice we've only had .rela for elf64 (x86-64). |
| 113 // In the future, the two properties may need to be decoupled |
| 114 // and the ShEntSize can vary more. |
| 115 const Elf64_Word ShType = IsELF64 ? SHT_RELA : SHT_REL; |
| 116 IceString RelPrefix = IsELF64 ? ".rela" : ".rel"; |
| 117 IceString RelSectionName = RelPrefix + RelatedSection->getName(); |
| 118 const Elf64_Xword ShAlign = IsELF64 ? 8 : 4; |
| 119 const Elf64_Xword ShEntSize = |
| 120 IsELF64 ? sizeof(Elf64_Rela) : sizeof(Elf32_Rel); |
| 121 static_assert(sizeof(Elf64_Rela) == 24 && sizeof(Elf32_Rel) == 8, |
| 122 "Elf_Rel/Rela sizes cannot be derived from sizeof"); |
| 123 const Elf64_Xword ShFlags = 0; |
| 124 ELFRelocationSection *RelSection = createSection<ELFRelocationSection>( |
| 125 RelSectionName, ShType, ShFlags, ShAlign, ShEntSize); |
| 126 RelSection->setRelatedSection(RelatedSection); |
| 127 return RelSection; |
| 128 } |
| 129 |
106 template <typename UserSectionList> | 130 template <typename UserSectionList> |
107 void ELFObjectWriter::assignRelSectionNumInPairs(SizeT &CurSectionNumber, | 131 void ELFObjectWriter::assignRelSectionNumInPairs(SizeT &CurSectionNumber, |
108 UserSectionList &UserSections, | 132 UserSectionList &UserSections, |
109 RelSectionList &RelSections, | 133 RelSectionList &RelSections, |
110 SectionList &AllSections) { | 134 SectionList &AllSections) { |
111 RelSectionList::iterator RelIt = RelSections.begin(); | 135 RelSectionList::iterator RelIt = RelSections.begin(); |
112 RelSectionList::iterator RelE = RelSections.end(); | 136 RelSectionList::iterator RelE = RelSections.end(); |
113 for (ELFSection *UserSection : UserSections) { | 137 for (ELFSection *UserSection : UserSections) { |
114 UserSection->setNumber(CurSectionNumber++); | 138 UserSection->setNumber(CurSectionNumber++); |
115 UserSection->setNameStrIndex(ShStrTab->getIndex(UserSection->getName())); | 139 UserSection->setNameStrIndex(ShStrTab->getIndex(UserSection->getName())); |
(...skipping 27 matching lines...) Expand all Loading... |
143 assert(!SectionNumbersAssigned); | 167 assert(!SectionNumbersAssigned); |
144 SizeT CurSectionNumber = 0; | 168 SizeT CurSectionNumber = 0; |
145 NullSection->setNumber(CurSectionNumber++); | 169 NullSection->setNumber(CurSectionNumber++); |
146 // The rest of the fields are initialized to 0, and stay that way. | 170 // The rest of the fields are initialized to 0, and stay that way. |
147 AllSections.push_back(NullSection); | 171 AllSections.push_back(NullSection); |
148 | 172 |
149 assignRelSectionNumInPairs<TextSectionList>(CurSectionNumber, TextSections, | 173 assignRelSectionNumInPairs<TextSectionList>(CurSectionNumber, TextSections, |
150 RelTextSections, AllSections); | 174 RelTextSections, AllSections); |
151 assignRelSectionNumInPairs<DataSectionList>(CurSectionNumber, DataSections, | 175 assignRelSectionNumInPairs<DataSectionList>(CurSectionNumber, DataSections, |
152 RelDataSections, AllSections); | 176 RelDataSections, AllSections); |
153 assignRelSectionNumInPairs<DataSectionList>(CurSectionNumber, RoDataSections, | 177 for (ELFSection *BSSSection : BSSSections) { |
154 RelRoDataSections, AllSections); | 178 BSSSection->setNumber(CurSectionNumber++); |
| 179 BSSSection->setNameStrIndex(ShStrTab->getIndex(BSSSection->getName())); |
| 180 AllSections.push_back(BSSSection); |
| 181 } |
| 182 assignRelSectionNumInPairs<DataSectionList>(CurSectionNumber, RODataSections, |
| 183 RelRODataSections, AllSections); |
155 | 184 |
156 ShStrTab->setNumber(CurSectionNumber++); | 185 ShStrTab->setNumber(CurSectionNumber++); |
157 ShStrTab->setNameStrIndex(ShStrTab->getIndex(ShStrTab->getName())); | 186 ShStrTab->setNameStrIndex(ShStrTab->getIndex(ShStrTab->getName())); |
158 AllSections.push_back(ShStrTab); | 187 AllSections.push_back(ShStrTab); |
159 | 188 |
160 SymTab->setNumber(CurSectionNumber++); | 189 SymTab->setNumber(CurSectionNumber++); |
161 SymTab->setNameStrIndex(ShStrTab->getIndex(SymTab->getName())); | 190 SymTab->setNameStrIndex(ShStrTab->getIndex(SymTab->getName())); |
162 AllSections.push_back(SymTab); | 191 AllSections.push_back(SymTab); |
163 | 192 |
164 StrTab->setNumber(CurSectionNumber++); | 193 StrTab->setNumber(CurSectionNumber++); |
165 StrTab->setNameStrIndex(ShStrTab->getIndex(StrTab->getName())); | 194 StrTab->setNameStrIndex(ShStrTab->getIndex(StrTab->getName())); |
166 AllSections.push_back(StrTab); | 195 AllSections.push_back(StrTab); |
167 | 196 |
168 SymTab->setLinkNum(StrTab->getNumber()); | 197 SymTab->setLinkNum(StrTab->getNumber()); |
169 SymTab->setInfoNum(SymTab->getNumLocals()); | 198 SymTab->setInfoNum(SymTab->getNumLocals()); |
170 | 199 |
171 assignRelLinkNum(SymTab->getNumber(), RelTextSections); | 200 assignRelLinkNum(SymTab->getNumber(), RelTextSections); |
172 assignRelLinkNum(SymTab->getNumber(), RelDataSections); | 201 assignRelLinkNum(SymTab->getNumber(), RelDataSections); |
173 assignRelLinkNum(SymTab->getNumber(), RelRoDataSections); | 202 assignRelLinkNum(SymTab->getNumber(), RelRODataSections); |
174 SectionNumbersAssigned = true; | 203 SectionNumbersAssigned = true; |
175 } | 204 } |
176 | 205 |
177 Elf64_Off ELFObjectWriter::alignFileOffset(Elf64_Xword Align) { | 206 Elf64_Off ELFObjectWriter::alignFileOffset(Elf64_Xword Align) { |
178 assert(llvm::isPowerOf2_32(Align)); | 207 assert(llvm::isPowerOf2_32(Align)); |
179 Elf64_Off OffsetInFile = Str.tell(); | 208 Elf64_Off OffsetInFile = Str.tell(); |
180 Elf64_Xword Mod = OffsetInFile & (Align - 1); | 209 Elf64_Xword Mod = OffsetInFile & (Align - 1); |
181 if (Mod == 0) | 210 if (Mod == 0) |
182 return OffsetInFile; | 211 return OffsetInFile; |
183 Elf64_Xword AlignDiff = Align - Mod; | 212 Elf64_Xword AlignDiff = Align - Mod; |
184 Str.writeZeroPadding(AlignDiff); | 213 Str.writeZeroPadding(AlignDiff); |
185 OffsetInFile += AlignDiff; | 214 OffsetInFile += AlignDiff; |
186 assert((OffsetInFile & (Align - 1)) == 0); | 215 assert((OffsetInFile & (Align - 1)) == 0); |
187 return OffsetInFile; | 216 return OffsetInFile; |
188 } | 217 } |
189 | 218 |
190 void ELFObjectWriter::writeFunctionCode(const IceString &FuncName, | 219 void ELFObjectWriter::writeFunctionCode(const IceString &FuncName, |
191 bool IsInternal, const Assembler *Asm) { | 220 bool IsInternal, const Assembler *Asm) { |
192 assert(!SectionNumbersAssigned); | 221 assert(!SectionNumbersAssigned); |
193 ELFTextSection *Section = nullptr; | 222 ELFTextSection *Section = nullptr; |
| 223 ELFRelocationSection *RelSection = nullptr; |
194 // TODO(jvoung): handle ffunction-sections. | 224 // TODO(jvoung): handle ffunction-sections. |
195 IceString SectionName = ".text"; | 225 IceString SectionName = ".text"; |
196 if (TextSections.size() == 0) { | 226 bool IsELF64 = isELF64(Ctx.getTargetArch()); |
| 227 if (TextSections.empty()) { |
197 const Elf64_Xword ShFlags = SHF_ALLOC | SHF_EXECINSTR; | 228 const Elf64_Xword ShFlags = SHF_ALLOC | SHF_EXECINSTR; |
198 // TODO(jvoung): Should be bundle size. Grab it from that target? | 229 // TODO(jvoung): Should be bundle size. Grab it from that target? |
199 const Elf64_Xword ShAlign = 32; | 230 const Elf64_Xword ShAlign = 32; |
200 Section = createSection<ELFTextSection>(SectionName, SHT_PROGBITS, ShFlags, | 231 Section = createSection<ELFTextSection>(SectionName, SHT_PROGBITS, ShFlags, |
201 ShAlign, 0); | 232 ShAlign, 0); |
202 Elf64_Off OffsetInFile = alignFileOffset(Section->getSectionAlign()); | 233 Elf64_Off OffsetInFile = alignFileOffset(Section->getSectionAlign()); |
203 Section->setFileOffset(OffsetInFile); | 234 Section->setFileOffset(OffsetInFile); |
204 TextSections.push_back(Section); | 235 TextSections.push_back(Section); |
| 236 RelSection = createRelocationSection(IsELF64, Section); |
| 237 RelTextSections.push_back(RelSection); |
205 } else { | 238 } else { |
206 Section = TextSections[0]; | 239 Section = TextSections[0]; |
| 240 RelSection = RelTextSections[0]; |
207 } | 241 } |
208 RelocOffsetT OffsetInSection = Section->getCurrentSize(); | 242 RelocOffsetT OffsetInSection = Section->getCurrentSize(); |
209 // Function symbols are set to 0 size in the symbol table, | 243 // Function symbols are set to 0 size in the symbol table, |
210 // in contrast to data symbols which have a proper size. | 244 // in contrast to data symbols which have a proper size. |
211 SizeT SymbolSize = 0; | 245 SizeT SymbolSize = 0; |
212 Section->appendData(Str, Asm->getBufferView()); | 246 Section->appendData(Str, Asm->getBufferView()); |
213 uint8_t SymbolType; | 247 uint8_t SymbolType; |
214 uint8_t SymbolBinding; | 248 uint8_t SymbolBinding; |
215 if (IsInternal) { | 249 if (IsInternal) { |
216 SymbolType = STT_NOTYPE; | 250 SymbolType = STT_NOTYPE; |
217 SymbolBinding = STB_LOCAL; | 251 SymbolBinding = STB_LOCAL; |
218 } else { | 252 } else { |
219 SymbolType = STT_FUNC; | 253 SymbolType = STT_FUNC; |
220 SymbolBinding = STB_GLOBAL; | 254 SymbolBinding = STB_GLOBAL; |
221 } | 255 } |
222 SymTab->createDefinedSym(FuncName, SymbolType, SymbolBinding, Section, | 256 SymTab->createDefinedSym(FuncName, SymbolType, SymbolBinding, Section, |
223 OffsetInSection, SymbolSize); | 257 OffsetInSection, SymbolSize); |
224 StrTab->add(FuncName); | 258 StrTab->add(FuncName); |
225 | 259 |
226 // Create a relocation section for the text section if needed, and copy the | 260 // Create a relocation section for the text section if needed, and copy the |
227 // fixup information from per-function Assembler memory to the object | 261 // fixup information from per-function Assembler memory to the object |
228 // writer's memory, for writing later. | 262 // writer's memory, for writing later. |
229 if (!Asm->fixups().empty()) { | 263 if (!Asm->fixups().empty()) { |
230 bool IsELF64 = isELF64(Ctx.getTargetArch()); | |
231 IceString RelSectionName = IsELF64 ? ".rela" : ".rel"; | |
232 RelSectionName += SectionName; | |
233 ELFRelocationSection *RelSection = nullptr; | |
234 // TODO(jvoung): Make this more efficient if -ffunction-sections | |
235 // efficiency becomes a problem. | |
236 auto RSI = | |
237 std::find_if(RelTextSections.begin(), RelTextSections.end(), | |
238 [&RelSectionName](const ELFRelocationSection *S) | |
239 -> bool { return S->getName() == RelSectionName; }); | |
240 if (RSI != RelTextSections.end()) { | |
241 RelSection = *RSI; | |
242 } else { | |
243 const Elf64_Word ShType = IsELF64 ? SHT_RELA : SHT_REL; | |
244 const Elf64_Xword ShAlign = IsELF64 ? 8 : 4; | |
245 const Elf64_Xword ShEntSize = | |
246 IsELF64 ? sizeof(Elf64_Rela) : sizeof(Elf32_Rel); | |
247 static_assert(sizeof(Elf64_Rela) == 24 && sizeof(Elf32_Rel) == 8, | |
248 "Elf_Rel/Rela sizes cannot be derived from sizeof"); | |
249 const Elf64_Xword ShFlags = 0; | |
250 RelSection = createSection<ELFRelocationSection>( | |
251 RelSectionName, ShType, ShFlags, ShAlign, ShEntSize); | |
252 RelSection->setRelatedSection(Section); | |
253 RelTextSections.push_back(RelSection); | |
254 } | |
255 RelSection->addRelocations(OffsetInSection, Asm->fixups()); | 264 RelSection->addRelocations(OffsetInSection, Asm->fixups()); |
256 } | 265 } |
257 } | 266 } |
258 | 267 |
259 void ELFObjectWriter::writeDataInitializer(const IceString &VarName, | 268 namespace { |
260 const llvm::StringRef Data) { | 269 |
| 270 ELFObjectWriter::SectionType |
| 271 classifyGlobalSection(const VariableDeclaration *Var) { |
| 272 if (Var->getIsConstant()) |
| 273 return ELFObjectWriter::ROData; |
| 274 if (Var->hasNonzeroInitializer()) |
| 275 return ELFObjectWriter::Data; |
| 276 return ELFObjectWriter::BSS; |
| 277 } |
| 278 |
| 279 // TODO(jvoung): dedupe, use the GlobalContext version |
| 280 // https://codereview.chromium.org/870653002/diff/200001/src/IceGlobalContext.h |
| 281 bool matchSymbolName(const IceString &SymbolName, const IceString &Match) { |
| 282 return Match.empty() || Match == SymbolName; |
| 283 } |
| 284 |
| 285 // Partition the Vars list by SectionType into VarsBySection. |
| 286 // If TranslateOnly is non-empty, then only the TranslateOnly variable |
| 287 // is kept for emission. |
| 288 void partitionGlobalsBySection(const VariableDeclarationList &Vars, |
| 289 VariableDeclarationList VarsBySection[], |
| 290 const IceString &TranslateOnly) { |
| 291 for (auto Var : Vars) { |
| 292 if (matchSymbolName(Var->getName(), TranslateOnly)) { |
| 293 size_t Section = classifyGlobalSection(Var); |
| 294 assert(Section < ELFObjectWriter::SectionType::NumSectionTypes); |
| 295 VarsBySection[Section].push_back(Var); |
| 296 } |
| 297 } |
| 298 } |
| 299 |
| 300 } // end of anonymous namespace |
| 301 |
| 302 void ELFObjectWriter::writeDataSection(const VariableDeclarationList &Vars, |
| 303 FixupKind RelocationKind) { |
261 assert(!SectionNumbersAssigned); | 304 assert(!SectionNumbersAssigned); |
262 (void)Data; | 305 VariableDeclarationList VarsBySection[ELFObjectWriter::NumSectionTypes]; |
263 llvm_unreachable("TODO"); | 306 for (auto &SectionList : VarsBySection) |
264 StrTab->add(VarName); | 307 SectionList.reserve(Vars.size()); |
| 308 partitionGlobalsBySection(Vars, VarsBySection, Ctx.getFlags().TranslateOnly); |
| 309 bool IsELF64 = isELF64(Ctx.getTargetArch()); |
| 310 for (size_t I = ELFObjectWriter::BaseSectionType; |
| 311 I < ELFObjectWriter::NumSectionTypes; ++I) { |
| 312 writeDataOfType(static_cast<SectionType>(I), VarsBySection[I], |
| 313 RelocationKind, IsELF64); |
| 314 } |
| 315 } |
| 316 |
| 317 void ELFObjectWriter::writeDataOfType(SectionType SectionType, |
| 318 const VariableDeclarationList &Vars, |
| 319 FixupKind RelocationKind, bool IsELF64) { |
| 320 ELFDataSection *Section; |
| 321 ELFRelocationSection *RelSection; |
| 322 // TODO(jvoung): Handle fdata-sections. |
| 323 IceString SectionName; |
| 324 Elf64_Xword ShAddralign = 0; // Actual load-time alignment unknown for now. |
| 325 const Elf64_Xword ShEntsize = 0; // non-uniform data element size. |
| 326 // Lift this out, so it can be re-used if we do fdata-sections? |
| 327 switch (SectionType) { |
| 328 case SectionType::ROData: { |
| 329 SectionName = ".rodata"; |
| 330 // Only expecting to write the data sections all in one shot for now. |
| 331 assert(RODataSections.empty()); |
| 332 // Create the section. |
| 333 // A bunch of these properties can be looked up from a table |
| 334 // so make it into a defs file? |
| 335 const Elf64_Xword ShFlags = SHF_ALLOC; |
| 336 Section = createSection<ELFDataSection>(SectionName, SHT_PROGBITS, ShFlags, |
| 337 ShAddralign, ShEntsize); |
| 338 // Assume file offset doesn't need to be aligned by much (only the |
| 339 // sh_addralign is sensitive to the data alignment requirements) |
| 340 Section->setFileOffset(alignFileOffset(4)); |
| 341 RODataSections.push_back(Section); |
| 342 RelSection = createRelocationSection(IsELF64, Section); |
| 343 RelRODataSections.push_back(RelSection); |
| 344 break; |
| 345 } |
| 346 case SectionType::Data: { |
| 347 SectionName = ".data"; |
| 348 assert(DataSections.empty()); |
| 349 const Elf64_Xword ShFlags = SHF_ALLOC | SHF_WRITE; |
| 350 Section = createSection<ELFDataSection>(SectionName, SHT_PROGBITS, ShFlags, |
| 351 ShAddralign, ShEntsize); |
| 352 Section->setFileOffset(alignFileOffset(4)); |
| 353 DataSections.push_back(Section); |
| 354 RelSection = createRelocationSection(IsELF64, Section); |
| 355 RelDataSections.push_back(RelSection); |
| 356 break; |
| 357 } |
| 358 case SectionType::BSS: { |
| 359 SectionName = ".bss"; |
| 360 assert(BSSSections.empty()); |
| 361 const Elf64_Xword ShFlags = SHF_ALLOC | SHF_WRITE; |
| 362 Section = createSection<ELFDataSection>(SectionName, SHT_NOBITS, ShFlags, |
| 363 ShAddralign, ShEntsize); |
| 364 Section->setFileOffset(alignFileOffset(4)); |
| 365 BSSSections.push_back(Section); |
| 366 break; |
| 367 } |
| 368 case SectionType::NumSectionTypes: |
| 369 llvm_unreachable("Unknown SectionType"); |
| 370 break; |
| 371 } |
| 372 |
| 373 const uint8_t SymbolType = STT_OBJECT; |
| 374 bool WritePadding = SectionType != SectionType::BSS; |
| 375 for (auto *Var : Vars) { |
| 376 Elf64_Xword Align = Var->getAlignment(); |
| 377 |
| 378 Section->padToAlignment(Str, WritePadding, Align); |
| 379 ShAddralign = std::max(ShAddralign, Align); |
| 380 |
| 381 SizeT SymbolSize = Var->getNumBytes(); |
| 382 bool IsExternal = Var->isExternal() || Ctx.getFlags().DisableInternal; |
| 383 const uint8_t SymbolBinding = IsExternal ? STB_GLOBAL : STB_LOCAL; |
| 384 IceString MangledName = Var->mangleName(&Ctx); |
| 385 SymTab->createDefinedSym(MangledName, SymbolType, SymbolBinding, Section, |
| 386 Section->getCurrentSize(), SymbolSize); |
| 387 StrTab->add(MangledName); |
| 388 if (!Var->hasNonzeroInitializer()) { |
| 389 assert(SectionType == SectionType::BSS || |
| 390 SectionType == SectionType::ROData); |
| 391 if (SectionType == SectionType::ROData) |
| 392 Section->appendZeros(Str, SymbolSize); |
| 393 else |
| 394 Section->setSize(Section->getCurrentSize() + SymbolSize); |
| 395 } else { |
| 396 assert(SectionType != SectionType::BSS); |
| 397 for (VariableDeclaration::Initializer *Init : Var->getInitializers()) { |
| 398 switch (Init->getKind()) { |
| 399 case VariableDeclaration::Initializer::DataInitializerKind: { |
| 400 const auto Data = llvm::cast<VariableDeclaration::DataInitializer>( |
| 401 Init)->getContents(); |
| 402 Section->appendData(Str, llvm::StringRef(Data.data(), Data.size())); |
| 403 break; |
| 404 } |
| 405 case VariableDeclaration::Initializer::ZeroInitializerKind: |
| 406 Section->appendZeros(Str, Init->getNumBytes()); |
| 407 break; |
| 408 case VariableDeclaration::Initializer::RelocInitializerKind: { |
| 409 const auto Reloc = |
| 410 llvm::cast<VariableDeclaration::RelocInitializer>(Init); |
| 411 AssemblerFixup NewFixup; |
| 412 NewFixup.set_position(Section->getCurrentSize()); |
| 413 NewFixup.set_kind(RelocationKind); |
| 414 const bool SuppressMangling = true; |
| 415 NewFixup.set_value(Ctx.getConstantSym( |
| 416 Reloc->getOffset(), Reloc->getDeclaration()->mangleName(&Ctx), |
| 417 SuppressMangling)); |
| 418 RelSection->addRelocation(NewFixup); |
| 419 Section->appendRelocationOffset(Str, RelSection->isRela(), |
| 420 Reloc->getOffset()); |
| 421 break; |
| 422 } |
| 423 } |
| 424 } |
| 425 } |
| 426 } |
| 427 Section->setAlignment(ShAddralign); |
265 } | 428 } |
266 | 429 |
267 void ELFObjectWriter::writeInitialELFHeader() { | 430 void ELFObjectWriter::writeInitialELFHeader() { |
268 assert(!SectionNumbersAssigned); | 431 assert(!SectionNumbersAssigned); |
269 const Elf64_Off DummySHOffset = 0; | 432 const Elf64_Off DummySHOffset = 0; |
270 const SizeT DummySHStrIndex = 0; | 433 const SizeT DummySHStrIndex = 0; |
271 const SizeT DummyNumSections = 0; | 434 const SizeT DummyNumSections = 0; |
272 if (isELF64(Ctx.getTargetArch())) { | 435 if (isELF64(Ctx.getTargetArch())) { |
273 writeELFHeaderInternal<true>(DummySHOffset, DummySHStrIndex, | 436 writeELFHeaderInternal<true>(DummySHOffset, DummySHStrIndex, |
274 DummyNumSections); | 437 DummyNumSections); |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
338 // between entries. | 501 // between entries. |
339 assert(WriteAmt % Align == 0); | 502 assert(WriteAmt % Align == 0); |
340 // Check that we write the full PrimType. | 503 // Check that we write the full PrimType. |
341 assert(WriteAmt == sizeof(typename ConstType::PrimType)); | 504 assert(WriteAmt == sizeof(typename ConstType::PrimType)); |
342 const Elf64_Xword ShFlags = SHF_ALLOC | SHF_MERGE; | 505 const Elf64_Xword ShFlags = SHF_ALLOC | SHF_MERGE; |
343 std::string SecBuffer; | 506 std::string SecBuffer; |
344 llvm::raw_string_ostream SecStrBuf(SecBuffer); | 507 llvm::raw_string_ostream SecStrBuf(SecBuffer); |
345 SecStrBuf << ".rodata.cst" << WriteAmt; | 508 SecStrBuf << ".rodata.cst" << WriteAmt; |
346 ELFDataSection *Section = createSection<ELFDataSection>( | 509 ELFDataSection *Section = createSection<ELFDataSection>( |
347 SecStrBuf.str(), SHT_PROGBITS, ShFlags, Align, WriteAmt); | 510 SecStrBuf.str(), SHT_PROGBITS, ShFlags, Align, WriteAmt); |
348 RoDataSections.push_back(Section); | 511 RODataSections.push_back(Section); |
349 SizeT OffsetInSection = 0; | 512 SizeT OffsetInSection = 0; |
350 // The symbol table entry doesn't need to know the defined symbol's | 513 // The symbol table entry doesn't need to know the defined symbol's |
351 // size since this is in a section with a fixed Entry Size. | 514 // size since this is in a section with a fixed Entry Size. |
352 const SizeT SymbolSize = 0; | 515 const SizeT SymbolSize = 0; |
353 Section->setFileOffset(alignFileOffset(Align)); | 516 Section->setFileOffset(alignFileOffset(Align)); |
354 | 517 |
355 // Write the data. | 518 // Write the data. |
356 for (Constant *C : Pool) { | 519 for (Constant *C : Pool) { |
357 auto Const = llvm::cast<ConstType>(C); | 520 auto Const = llvm::cast<ConstType>(C); |
358 std::string SymBuffer; | 521 std::string SymBuffer; |
(...skipping 16 matching lines...) Expand all Loading... |
375 // We may need to instantiate constant pools for integers as well | 538 // We may need to instantiate constant pools for integers as well |
376 // if we do constant-pooling of large integers to remove them | 539 // if we do constant-pooling of large integers to remove them |
377 // from the instruction stream (fewer bytes controlled by an attacker). | 540 // from the instruction stream (fewer bytes controlled by an attacker). |
378 template void ELFObjectWriter::writeConstantPool<ConstantFloat>(Type Ty); | 541 template void ELFObjectWriter::writeConstantPool<ConstantFloat>(Type Ty); |
379 | 542 |
380 template void ELFObjectWriter::writeConstantPool<ConstantDouble>(Type Ty); | 543 template void ELFObjectWriter::writeConstantPool<ConstantDouble>(Type Ty); |
381 | 544 |
382 void ELFObjectWriter::writeAllRelocationSections(bool IsELF64) { | 545 void ELFObjectWriter::writeAllRelocationSections(bool IsELF64) { |
383 writeRelocationSections(IsELF64, RelTextSections); | 546 writeRelocationSections(IsELF64, RelTextSections); |
384 writeRelocationSections(IsELF64, RelDataSections); | 547 writeRelocationSections(IsELF64, RelDataSections); |
385 writeRelocationSections(IsELF64, RelRoDataSections); | 548 writeRelocationSections(IsELF64, RelRODataSections); |
386 } | 549 } |
387 | 550 |
388 void ELFObjectWriter::writeRelocationSections(bool IsELF64, | 551 void ELFObjectWriter::writeRelocationSections(bool IsELF64, |
389 RelSectionList &RelSections) { | 552 RelSectionList &RelSections) { |
390 for (ELFRelocationSection *RelSec : RelSections) { | 553 for (ELFRelocationSection *RelSec : RelSections) { |
391 Elf64_Off Offset = alignFileOffset(RelSec->getSectionAlign()); | 554 Elf64_Off Offset = alignFileOffset(RelSec->getSectionAlign()); |
392 RelSec->setFileOffset(Offset); | 555 RelSec->setFileOffset(Offset); |
393 RelSec->setSize(RelSec->getSectionDataSize(Ctx, SymTab)); | 556 RelSec->setSize(RelSec->getSectionDataSize(Ctx, SymTab)); |
394 if (IsELF64) { | 557 if (IsELF64) { |
395 RelSec->writeData<true>(Ctx, Str, SymTab); | 558 RelSec->writeData<true>(Ctx, Str, SymTab); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
444 if (IsELF64) { | 607 if (IsELF64) { |
445 writeELFHeaderInternal<true>(ShOffset, ShStrTab->getNumber(), | 608 writeELFHeaderInternal<true>(ShOffset, ShStrTab->getNumber(), |
446 AllSections.size()); | 609 AllSections.size()); |
447 } else { | 610 } else { |
448 writeELFHeaderInternal<false>(ShOffset, ShStrTab->getNumber(), | 611 writeELFHeaderInternal<false>(ShOffset, ShStrTab->getNumber(), |
449 AllSections.size()); | 612 AllSections.size()); |
450 } | 613 } |
451 } | 614 } |
452 | 615 |
453 } // end of namespace Ice | 616 } // end of namespace Ice |
OLD | NEW |