llvm.org GIT mirror llvm / eb0c909
[yaml2obj][ELF] ELF Relocations Support. The patch implements support for both relocation record formats: Elf_Rel and Elf_Rela. It is possible to define relocation against symbol only. Relocations against sections will be implemented later. Now yaml2obj recognizes X86_64, MIPS and Hexagon relocation types. Example of relocation section specification: Sections: - Name: .text Type: SHT_PROGBITS Content: "0000000000000000" AddressAlign: 16 Flags: [SHF_ALLOC] - Name: .rel.text Type: SHT_REL Info: .text AddressAlign: 4 Relocations: - Offset: 0x1 Symbol: glob1 Type: R_MIPS_32 - Offset: 0x2 Symbol: glob2 Type: R_MIPS_CALL16 The patch reviewed by Michael Spencer, Sean Silva, Shankar Easwaran. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@206017 91177308-0d34-0410-b5e6-96231b3b80d8 Simon Atanasyan 5 years ago
4 changed file(s) with 535 addition(s) and 28 deletion(s). Raw diff Collapse all Expand all
3939 // Just use 64, since it can hold 32-bit values too.
4040 LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_EF)
4141 LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_SHT)
42 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_REL)
4243 // Just use 64, since it can hold 32-bit values too.
4344 LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_SHF)
4445 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STT)
6768 std::vector Weak;
6869 };
6970 struct Section {
71 enum class SectionKind { RawContent, Relocation };
72 SectionKind Kind;
7073 StringRef Name;
7174 ELF_SHT Type;
7275 ELF_SHF Flags;
7376 llvm::yaml::Hex64 Address;
77 StringRef Link;
78 StringRef Info;
79 llvm::yaml::Hex64 AddressAlign;
80 Section(SectionKind Kind) : Kind(Kind) {}
81 };
82 struct RawContentSection : Section {
7483 object::yaml::BinaryRef Content;
75 StringRef Link;
76 llvm::yaml::Hex64 AddressAlign;
84 RawContentSection() : Section(SectionKind::RawContent) {}
85 static bool classof(const Section *S) {
86 return S->Kind == SectionKind::RawContent;
87 }
88 };
89 struct Relocation {
90 uint32_t Offset;
91 uint32_t Addend;
92 ELF_REL Type;
93 StringRef Symbol;
94 };
95 struct RelocationSection : Section {
96 std::vector Relocations;
97 RelocationSection() : Section(SectionKind::Relocation) {}
98 static bool classof(const Section *S) {
99 return S->Kind == SectionKind::Relocation;
100 }
77101 };
78102 struct Object {
79103 FileHeader Header;
80 std::vector<Section> Sections;
104 std::vector<std::unique_ptr
> Sections;
81105 // Although in reality the symbols reside in a section, it is a lot
82106 // cleaner and nicer if we read them from the YAML as a separate
83107 // top-level key, which automatically ensures that invariants like there
88112 } // end namespace ELFYAML
89113 } // end namespace llvm
90114
91 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Section)
115 LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique_ptr)
92116 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Symbol)
117 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Relocation)
93118
94119 namespace llvm {
95120 namespace yaml {
140165 };
141166
142167 template <>
168 struct ScalarEnumerationTraits {
169 static void enumeration(IO &IO, ELFYAML::ELF_REL &Value);
170 };
171
172 template <>
143173 struct MappingTraits {
144174 static void mapping(IO &IO, ELFYAML::FileHeader &FileHdr);
145175 };
154184 static void mapping(IO &IO, ELFYAML::LocalGlobalWeakSymbols &Symbols);
155185 };
156186
157 template <>
158 struct MappingTraits {
159 static void mapping(IO &IO, ELFYAML::Section &Section);
187 template <> struct MappingTraits {
188 static void mapping(IO &IO, ELFYAML::Relocation &Rel);
189 };
190
191 template <>
192 struct MappingTraits> {
193 static void mapping(IO &IO, std::unique_ptr &Section);
160194 };
161195
162196 template <>
333333 #undef ECase
334334 }
335335
336 void ScalarEnumerationTraits::enumeration(
337 IO &IO, ELFYAML::ELF_REL &Value) {
338 const auto *Object = static_cast(IO.getContext());
339 assert(Object && "The IO context is not initialized");
340 #define ECase(X) IO.enumCase(Value, #X, ELF::X);
341 switch (Object->Header.Machine) {
342 case ELF::EM_X86_64:
343 ECase(R_X86_64_NONE)
344 ECase(R_X86_64_64)
345 ECase(R_X86_64_PC32)
346 ECase(R_X86_64_GOT32)
347 ECase(R_X86_64_PLT32)
348 ECase(R_X86_64_COPY)
349 ECase(R_X86_64_GLOB_DAT)
350 ECase(R_X86_64_JUMP_SLOT)
351 ECase(R_X86_64_RELATIVE)
352 ECase(R_X86_64_GOTPCREL)
353 ECase(R_X86_64_32)
354 ECase(R_X86_64_32S)
355 ECase(R_X86_64_16)
356 ECase(R_X86_64_PC16)
357 ECase(R_X86_64_8)
358 ECase(R_X86_64_PC8)
359 ECase(R_X86_64_DTPMOD64)
360 ECase(R_X86_64_DTPOFF64)
361 ECase(R_X86_64_TPOFF64)
362 ECase(R_X86_64_TLSGD)
363 ECase(R_X86_64_TLSLD)
364 ECase(R_X86_64_DTPOFF32)
365 ECase(R_X86_64_GOTTPOFF)
366 ECase(R_X86_64_TPOFF32)
367 ECase(R_X86_64_PC64)
368 ECase(R_X86_64_GOTOFF64)
369 ECase(R_X86_64_GOTPC32)
370 ECase(R_X86_64_GOT64)
371 ECase(R_X86_64_GOTPCREL64)
372 ECase(R_X86_64_GOTPC64)
373 ECase(R_X86_64_GOTPLT64)
374 ECase(R_X86_64_PLTOFF64)
375 ECase(R_X86_64_SIZE32)
376 ECase(R_X86_64_SIZE64)
377 ECase(R_X86_64_GOTPC32_TLSDESC)
378 ECase(R_X86_64_TLSDESC_CALL)
379 ECase(R_X86_64_TLSDESC)
380 ECase(R_X86_64_IRELATIVE)
381 break;
382 case ELF::EM_MIPS:
383 ECase(R_MIPS_NONE)
384 ECase(R_MIPS_16)
385 ECase(R_MIPS_32)
386 ECase(R_MIPS_REL32)
387 ECase(R_MIPS_26)
388 ECase(R_MIPS_HI16)
389 ECase(R_MIPS_LO16)
390 ECase(R_MIPS_GPREL16)
391 ECase(R_MIPS_LITERAL)
392 ECase(R_MIPS_GOT16)
393 ECase(R_MIPS_PC16)
394 ECase(R_MIPS_CALL16)
395 ECase(R_MIPS_GPREL32)
396 ECase(R_MIPS_UNUSED1)
397 ECase(R_MIPS_UNUSED2)
398 ECase(R_MIPS_SHIFT5)
399 ECase(R_MIPS_SHIFT6)
400 ECase(R_MIPS_64)
401 ECase(R_MIPS_GOT_DISP)
402 ECase(R_MIPS_GOT_PAGE)
403 ECase(R_MIPS_GOT_OFST)
404 ECase(R_MIPS_GOT_HI16)
405 ECase(R_MIPS_GOT_LO16)
406 ECase(R_MIPS_SUB)
407 ECase(R_MIPS_INSERT_A)
408 ECase(R_MIPS_INSERT_B)
409 ECase(R_MIPS_DELETE)
410 ECase(R_MIPS_HIGHER)
411 ECase(R_MIPS_HIGHEST)
412 ECase(R_MIPS_CALL_HI16)
413 ECase(R_MIPS_CALL_LO16)
414 ECase(R_MIPS_SCN_DISP)
415 ECase(R_MIPS_REL16)
416 ECase(R_MIPS_ADD_IMMEDIATE)
417 ECase(R_MIPS_PJUMP)
418 ECase(R_MIPS_RELGOT)
419 ECase(R_MIPS_JALR)
420 ECase(R_MIPS_TLS_DTPMOD32)
421 ECase(R_MIPS_TLS_DTPREL32)
422 ECase(R_MIPS_TLS_DTPMOD64)
423 ECase(R_MIPS_TLS_DTPREL64)
424 ECase(R_MIPS_TLS_GD)
425 ECase(R_MIPS_TLS_LDM)
426 ECase(R_MIPS_TLS_DTPREL_HI16)
427 ECase(R_MIPS_TLS_DTPREL_LO16)
428 ECase(R_MIPS_TLS_GOTTPREL)
429 ECase(R_MIPS_TLS_TPREL32)
430 ECase(R_MIPS_TLS_TPREL64)
431 ECase(R_MIPS_TLS_TPREL_HI16)
432 ECase(R_MIPS_TLS_TPREL_LO16)
433 ECase(R_MIPS_GLOB_DAT)
434 ECase(R_MIPS_COPY)
435 ECase(R_MIPS_JUMP_SLOT)
436 ECase(R_MICROMIPS_26_S1)
437 ECase(R_MICROMIPS_HI16)
438 ECase(R_MICROMIPS_LO16)
439 ECase(R_MICROMIPS_GOT16)
440 ECase(R_MICROMIPS_PC16_S1)
441 ECase(R_MICROMIPS_CALL16)
442 ECase(R_MICROMIPS_GOT_DISP)
443 ECase(R_MICROMIPS_GOT_PAGE)
444 ECase(R_MICROMIPS_GOT_OFST)
445 ECase(R_MICROMIPS_TLS_GD)
446 ECase(R_MICROMIPS_TLS_LDM)
447 ECase(R_MICROMIPS_TLS_DTPREL_HI16)
448 ECase(R_MICROMIPS_TLS_DTPREL_LO16)
449 ECase(R_MICROMIPS_TLS_TPREL_HI16)
450 ECase(R_MICROMIPS_TLS_TPREL_LO16)
451 ECase(R_MIPS_NUM)
452 ECase(R_MIPS_PC32)
453 break;
454 case ELF::EM_HEXAGON:
455 ECase(R_HEX_NONE)
456 ECase(R_HEX_B22_PCREL)
457 ECase(R_HEX_B15_PCREL)
458 ECase(R_HEX_B7_PCREL)
459 ECase(R_HEX_LO16)
460 ECase(R_HEX_HI16)
461 ECase(R_HEX_32)
462 ECase(R_HEX_16)
463 ECase(R_HEX_8)
464 ECase(R_HEX_GPREL16_0)
465 ECase(R_HEX_GPREL16_1)
466 ECase(R_HEX_GPREL16_2)
467 ECase(R_HEX_GPREL16_3)
468 ECase(R_HEX_HL16)
469 ECase(R_HEX_B13_PCREL)
470 ECase(R_HEX_B9_PCREL)
471 ECase(R_HEX_B32_PCREL_X)
472 ECase(R_HEX_32_6_X)
473 ECase(R_HEX_B22_PCREL_X)
474 ECase(R_HEX_B15_PCREL_X)
475 ECase(R_HEX_B13_PCREL_X)
476 ECase(R_HEX_B9_PCREL_X)
477 ECase(R_HEX_B7_PCREL_X)
478 ECase(R_HEX_16_X)
479 ECase(R_HEX_12_X)
480 ECase(R_HEX_11_X)
481 ECase(R_HEX_10_X)
482 ECase(R_HEX_9_X)
483 ECase(R_HEX_8_X)
484 ECase(R_HEX_7_X)
485 ECase(R_HEX_6_X)
486 ECase(R_HEX_32_PCREL)
487 ECase(R_HEX_COPY)
488 ECase(R_HEX_GLOB_DAT)
489 ECase(R_HEX_JMP_SLOT)
490 ECase(R_HEX_RELATIVE)
491 ECase(R_HEX_PLT_B22_PCREL)
492 ECase(R_HEX_GOTREL_LO16)
493 ECase(R_HEX_GOTREL_HI16)
494 ECase(R_HEX_GOTREL_32)
495 ECase(R_HEX_GOT_LO16)
496 ECase(R_HEX_GOT_HI16)
497 ECase(R_HEX_GOT_32)
498 ECase(R_HEX_GOT_16)
499 ECase(R_HEX_DTPMOD_32)
500 ECase(R_HEX_DTPREL_LO16)
501 ECase(R_HEX_DTPREL_HI16)
502 ECase(R_HEX_DTPREL_32)
503 ECase(R_HEX_DTPREL_16)
504 ECase(R_HEX_GD_PLT_B22_PCREL)
505 ECase(R_HEX_GD_GOT_LO16)
506 ECase(R_HEX_GD_GOT_HI16)
507 ECase(R_HEX_GD_GOT_32)
508 ECase(R_HEX_GD_GOT_16)
509 ECase(R_HEX_IE_LO16)
510 ECase(R_HEX_IE_HI16)
511 ECase(R_HEX_IE_32)
512 ECase(R_HEX_IE_GOT_LO16)
513 ECase(R_HEX_IE_GOT_HI16)
514 ECase(R_HEX_IE_GOT_32)
515 ECase(R_HEX_IE_GOT_16)
516 ECase(R_HEX_TPREL_LO16)
517 ECase(R_HEX_TPREL_HI16)
518 ECase(R_HEX_TPREL_32)
519 ECase(R_HEX_TPREL_16)
520 ECase(R_HEX_6_PCREL_X)
521 ECase(R_HEX_GOTREL_32_6_X)
522 ECase(R_HEX_GOTREL_16_X)
523 ECase(R_HEX_GOTREL_11_X)
524 ECase(R_HEX_GOT_32_6_X)
525 ECase(R_HEX_GOT_16_X)
526 ECase(R_HEX_GOT_11_X)
527 ECase(R_HEX_DTPREL_32_6_X)
528 ECase(R_HEX_DTPREL_16_X)
529 ECase(R_HEX_DTPREL_11_X)
530 ECase(R_HEX_GD_GOT_32_6_X)
531 ECase(R_HEX_GD_GOT_16_X)
532 ECase(R_HEX_GD_GOT_11_X)
533 ECase(R_HEX_IE_32_6_X)
534 ECase(R_HEX_IE_16_X)
535 ECase(R_HEX_IE_GOT_32_6_X)
536 ECase(R_HEX_IE_GOT_16_X)
537 ECase(R_HEX_IE_GOT_11_X)
538 ECase(R_HEX_TPREL_32_6_X)
539 ECase(R_HEX_TPREL_16_X)
540 ECase(R_HEX_TPREL_11_X)
541 break;
542 default:
543 llvm_unreachable("Unsupported architecture");
544 }
545 #undef ECase
546 }
547
336548 void MappingTraits::mapping(IO &IO,
337549 ELFYAML::FileHeader &FileHdr) {
338550 IO.mapRequired("Class", FileHdr.Class);
359571 IO.mapOptional("Weak", Symbols.Weak);
360572 }
361573
362 void MappingTraits::mapping(IO &IO,
363 ELFYAML::Section &Section) {
574 static void commonSectionMapping(IO &IO, ELFYAML::Section &Section) {
364575 IO.mapOptional("Name", Section.Name, StringRef());
365576 IO.mapRequired("Type", Section.Type);
366577 IO.mapOptional("Flags", Section.Flags, ELFYAML::ELF_SHF(0));
367578 IO.mapOptional("Address", Section.Address, Hex64(0));
579 IO.mapOptional("Link", Section.Link);
580 IO.mapOptional("Info", Section.Info);
581 IO.mapOptional("AddressAlign", Section.AddressAlign, Hex64(0));
582 }
583
584 static void sectionMapping(IO &IO, ELFYAML::RawContentSection &Section) {
585 commonSectionMapping(IO, Section);
368586 IO.mapOptional("Content", Section.Content);
369 IO.mapOptional("Link", Section.Link);
370 IO.mapOptional("AddressAlign", Section.AddressAlign, Hex64(0));
587 }
588
589 static void sectionMapping(IO &IO, ELFYAML::RelocationSection &Section) {
590 commonSectionMapping(IO, Section);
591 IO.mapOptional("Relocations", Section.Relocations);
592 }
593
594 void MappingTraits>::mapping(
595 IO &IO, std::unique_ptr &Section) {
596 ELFYAML::ELF_SHT sectionType;
597 if (IO.outputting())
598 sectionType = Section->Type;
599 IO.mapRequired("Type", sectionType);
600
601 switch (sectionType) {
602 case ELF::SHT_REL:
603 case ELF::SHT_RELA:
604 if (!IO.outputting())
605 Section.reset(new ELFYAML::RelocationSection());
606 sectionMapping(IO, *cast(Section.get()));
607 break;
608 default:
609 if (!IO.outputting())
610 Section.reset(new ELFYAML::RawContentSection());
611 sectionMapping(IO, *cast(Section.get()));
612 }
613 }
614
615 void MappingTraits::mapping(IO &IO,
616 ELFYAML::Relocation &Rel) {
617 IO.mapRequired("Offset", Rel.Offset);
618 IO.mapRequired("Symbol", Rel.Symbol);
619 IO.mapRequired("Type", Rel.Type);
620 IO.mapOptional("Addend", Rel.Addend);
371621 }
372622
373623 void MappingTraits::mapping(IO &IO, ELFYAML::Object &Object) {
624 assert(!IO.getContext() && "The IO context is initialized already");
625 IO.setContext(&Object);
374626 IO.mapRequired("FileHeader", Object.Header);
375627 IO.mapOptional("Sections", Object.Sections);
376628 IO.mapOptional("Symbols", Object.Symbols);
629 IO.setContext(nullptr);
377630 }
378631
379632 } // end namespace yaml
0 # RUN: yaml2obj -format=elf %s | llvm-readobj -sections -relocations - | FileCheck %s
1
2 !ELF
3 FileHeader: !FileHeader
4 Class: ELFCLASS32
5 Data: ELFDATA2MSB
6 Type: ET_REL
7 Machine: EM_MIPS
8
9 Sections:
10 - Name: .text
11 Type: SHT_PROGBITS
12 Content: "0000000000000000"
13 AddressAlign: 16
14 Flags: [SHF_ALLOC]
15
16 - Name: .rel.text
17 Type: SHT_REL
18 Info: .text
19 AddressAlign: 4
20 Relocations:
21 - Offset: 0x1
22 Symbol: glob1
23 Type: R_MIPS_32
24 - Offset: 0x1
25 Symbol: glob2
26 Type: R_MIPS_CALL16
27 - Offset: 0x2
28 Symbol: loc1
29 Type: R_MIPS_LO16
30
31 - Name: .rela.text
32 Type: SHT_RELA
33 Link: .symtab
34 Info: .text
35 AddressAlign: 4
36 Relocations:
37 - Offset: 0x1
38 Addend: 1
39 Symbol: glob1
40 Type: R_MIPS_32
41 - Offset: 0x1
42 Addend: 2
43 Symbol: glob2
44 Type: R_MIPS_CALL16
45 - Offset: 0x2
46 Addend: 3
47 Symbol: loc1
48 Type: R_MIPS_LO16
49
50 Symbols:
51 Local:
52 - Name: loc1
53 - Name: loc2
54 Global:
55 - Name: glob1
56 Section: .text
57 Value: 0x0
58 Size: 4
59 - Name: glob2
60 Weak:
61 - Name: weak1
62
63 # CHECK: Section {
64 # CHECK-NEXT: Index: 0
65 # CHECK: }
66 # CHECK: Section {
67 # CHECK-NEXT: Index: 1
68 # CHECK-NEXT: Name: .text (1)
69 # CHECK: }
70 # CHECK-NEXT: Section {
71 # CHECK-NEXT: Index: 2
72 # CHECK-NEXT: Name: .rel.text (7)
73 # CHECK-NEXT: Type: SHT_REL (0x9)
74 # CHECK-NEXT: Flags [ (0x0)
75 # CHECK-NEXT: ]
76 # CHECK-NEXT: Address: 0x0
77 # CHECK-NEXT: Offset: 0x160
78 # CHECK-NEXT: Size: 24
79 # CHECK-NEXT: Link: 4
80 # CHECK-NEXT: Info: 1
81 # CHECK-NEXT: AddressAlignment: 4
82 # CHECK-NEXT: EntrySize: 8
83 # CHECK-NEXT: }
84 # CHECK-NEXT: Section {
85 # CHECK-NEXT: Index: 3
86 # CHECK-NEXT: Name: .rela.text (17)
87 # CHECK-NEXT: Type: SHT_RELA (0x4)
88 # CHECK-NEXT: Flags [ (0x0)
89 # CHECK-NEXT: ]
90 # CHECK-NEXT: Address: 0x0
91 # CHECK-NEXT: Offset: 0x180
92 # CHECK-NEXT: Size: 36
93 # CHECK-NEXT: Link: 4
94 # CHECK-NEXT: Info: 1
95 # CHECK-NEXT: AddressAlignment: 4
96 # CHECK-NEXT: EntrySize: 12
97 # CHECK-NEXT: }
98 # CHECK-NEXT: Section {
99 # CHECK-NEXT: Index: 4
100 # CHECK-NEXT: Name: .symtab (28)
101 # CHECK: }
102 # CHECK-NEXT: Section {
103 # CHECK-NEXT: Index: 5
104 # CHECK-NEXT: Name: .strtab (36)
105 # CHECK: }
106 # CHECK: Relocations [
107 # CHECK-NEXT: Section (2) .rel.text {
108 # CHECK-NEXT: 0x1 R_MIPS_32 glob1 0x0
109 # CHECK-NEXT: 0x1 R_MIPS_CALL16 glob2 0x0
110 # CHECK-NEXT: 0x2 R_MIPS_LO16 loc1 0x0
111 # CHECK-NEXT: }
112 # CHECK-NEXT: Section (3) .rela.text {
113 # CHECK-NEXT: 0x1 R_MIPS_32 glob1 0x1
114 # CHECK-NEXT: 0x1 R_MIPS_CALL16 glob2 0x2
115 # CHECK-NEXT: 0x2 R_MIPS_LO16 loc1 0x3
116 # CHECK-NEXT: }
117 # CHECK-NEXT: ]
142142 typedef typename object::ELFFile::Elf_Ehdr Elf_Ehdr;
143143 typedef typename object::ELFFile::Elf_Shdr Elf_Shdr;
144144 typedef typename object::ELFFile::Elf_Sym Elf_Sym;
145 typedef typename object::ELFFile::Elf_Rel Elf_Rel;
146 typedef typename object::ELFFile::Elf_Rela Elf_Rela;
145147
146148 /// \brief The future ".strtab" section.
147149 StringTableBuilder DotStrtab;
150152 StringTableBuilder DotShStrtab;
151153
152154 NameToIdxMap SN2I;
155 NameToIdxMap SymN2I;
153156 const ELFYAML::Object &Doc;
154157
155158 bool buildSectionIndex();
159 bool buildSymbolIndex(std::size_t &StartIndex,
160 const std::vector &Symbols);
156161 void initELFHeader(Elf_Ehdr &Header);
157162 bool initSectionHeaders(std::vector &SHeaders,
158163 ContiguousBlobAccumulator &CBA);
163168 ContiguousBlobAccumulator &CBA);
164169 void addSymbols(const std::vector &Symbols,
165170 std::vector &Syms, unsigned SymbolBinding);
171 void writeSectionContent(Elf_Shdr &SHeader,
172 const ELFYAML::RawContentSection &Section,
173 ContiguousBlobAccumulator &CBA);
174 bool writeSectionContent(Elf_Shdr &SHeader,
175 const ELFYAML::RelocationSection &Section,
176 ContiguousBlobAccumulator &CBA);
166177
167178 // - SHT_NULL entry (placed first, i.e. 0'th entry)
168179 // - symbol table (.symtab) (placed third to last)
218229
219230 for (const auto &Sec : Doc.Sections) {
220231 zero(SHeader);
221 SHeader.sh_name = DotShStrtab.addString(Sec.Name);
222 SHeader.sh_type = Sec.Type;
223 SHeader.sh_flags = Sec.Flags;
224 SHeader.sh_addr = Sec.Address;
225
226 Sec.Content.writeAsBinary(CBA.getOSAndAlignedOffset(SHeader.sh_offset));
227 SHeader.sh_size = Sec.Content.binary_size();
228
229 if (!Sec.Link.empty()) {
232 SHeader.sh_name = DotShStrtab.addString(Sec->Name);
233 SHeader.sh_type = Sec->Type;
234 SHeader.sh_flags = Sec->Flags;
235 SHeader.sh_addr = Sec->Address;
236 SHeader.sh_addralign = Sec->AddressAlign;
237
238 if (!Sec->Link.empty()) {
230239 unsigned Index;
231 if (SN2I.lookup(Sec.Link, Index)) {
232 errs() << "error: Unknown section referenced: '" << Sec.Link
233 << "' at YAML section '" << Sec.Name << "'.\n";
234 return false;;
240 if (SN2I.lookup(Sec->Link, Index)) {
241 errs() << "error: Unknown section referenced: '" << Sec->Link
242 << "' at YAML section '" << Sec->Name << "'.\n";
243 return false;
235244 }
236245 SHeader.sh_link = Index;
237246 }
238 SHeader.sh_info = 0;
239 SHeader.sh_addralign = Sec.AddressAlign;
240 SHeader.sh_entsize = 0;
247
248 if (auto S = dyn_cast(Sec.get()))
249 writeSectionContent(SHeader, *S, CBA);
250 else if (auto S = dyn_cast(Sec.get())) {
251 if (S->Link.empty())
252 // For relocation section set link to .symtab by default.
253 SHeader.sh_link = getDotSymTabSecNo();
254
255 unsigned Index;
256 if (SN2I.lookup(S->Info, Index)) {
257 errs() << "error: Unknown section referenced: '" << S->Info
258 << "' at YAML section '" << S->Name << "'.\n";
259 return false;
260 }
261 SHeader.sh_info = Index;
262
263 if (!writeSectionContent(SHeader, *S, CBA))
264 return false;
265 } else
266 llvm_unreachable("Unknown section type");
267
241268 SHeaders.push_back(SHeader);
242269 }
243270 return true;
307334 }
308335 }
309336
337 template
338 void
339 ELFState::writeSectionContent(Elf_Shdr &SHeader,
340 const ELFYAML::RawContentSection &Section,
341 ContiguousBlobAccumulator &CBA) {
342 Section.Content.writeAsBinary(CBA.getOSAndAlignedOffset(SHeader.sh_offset));
343 SHeader.sh_entsize = 0;
344 SHeader.sh_size = Section.Content.binary_size();
345 }
346
347 template
348 bool
349 ELFState::writeSectionContent(Elf_Shdr &SHeader,
350 const ELFYAML::RelocationSection &Section,
351 ContiguousBlobAccumulator &CBA) {
352 if (Section.Type != llvm::ELF::SHT_REL &&
353 Section.Type != llvm::ELF::SHT_RELA) {
354 errs() << "error: Invalid relocation section type.\n";
355 return false;
356 }
357
358 bool IsRela = Section.Type == llvm::ELF::SHT_RELA;
359 SHeader.sh_entsize = IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel);
360 SHeader.sh_size = SHeader.sh_entsize * Section.Relocations.size();
361
362 auto &OS = CBA.getOSAndAlignedOffset(SHeader.sh_offset);
363
364 for (const auto &Rel : Section.Relocations) {
365 unsigned SymIdx;
366 if (SymN2I.lookup(Rel.Symbol, SymIdx)) {
367 errs() << "error: Unknown symbol referenced: '" << Rel.Symbol
368 << "' at YAML relocation.\n";
369 return false;
370 }
371
372 if (IsRela) {
373 Elf_Rela REntry;
374 zero(REntry);
375 REntry.r_offset = Rel.Offset;
376 REntry.r_addend = Rel.Addend;
377 REntry.setSymbolAndType(SymIdx, Rel.Type);
378 OS.write((const char *)&REntry, sizeof(REntry));
379 } else {
380 Elf_Rel REntry;
381 zero(REntry);
382 REntry.r_offset = Rel.Offset;
383 REntry.setSymbolAndType(SymIdx, Rel.Type);
384 OS.write((const char *)&REntry, sizeof(REntry));
385 }
386 }
387 return true;
388 }
389
310390 template bool ELFState::buildSectionIndex() {
311391 SN2I.addName(".symtab", getDotSymTabSecNo());
312392 SN2I.addName(".strtab", getDotStrTabSecNo());
313393 SN2I.addName(".shstrtab", getDotShStrTabSecNo());
314394
315395 for (unsigned i = 0, e = Doc.Sections.size(); i != e; ++i) {
316 StringRef Name = Doc.Sections[i].Name;
396 StringRef Name = Doc.Sections[i]->Name;
317397 if (Name.empty())
318398 continue;
319399 // "+ 1" to take into account the SHT_NULL entry.
327407 }
328408
329409 template
410 bool
411 ELFState::buildSymbolIndex(std::size_t &StartIndex,
412 const std::vector &Symbols) {
413 for (const auto &Sym : Symbols) {
414 ++StartIndex;
415 if (Sym.Name.empty())
416 continue;
417 if (SymN2I.addName(Sym.Name, StartIndex)) {
418 errs() << "error: Repeated symbol name: '" << Sym.Name << "'.\n";
419 return false;
420 }
421 }
422 return true;
423 }
424
425 template
330426 int ELFState::writeELF(raw_ostream &OS, const ELFYAML::Object &Doc) {
331427 ELFState State(Doc);
332428 if (!State.buildSectionIndex())
429 return 1;
430
431 std::size_t StartSymIndex = 0;
432 if (!State.buildSymbolIndex(StartSymIndex, Doc.Symbols.Local) ||
433 !State.buildSymbolIndex(StartSymIndex, Doc.Symbols.Global) ||
434 !State.buildSymbolIndex(StartSymIndex, Doc.Symbols.Weak))
333435 return 1;
334436
335437 Elf_Ehdr Header;