llvm.org GIT mirror llvm / 0f417c5
[yaml2obj][obj2yaml] - Support SHT_GNU_versym (.gnu.version) section. This patch adds support for parsing dumping the .gnu.version section. Description of the section is: https://refspecs.linuxfoundation.org/LSB_1.3.0/gLSB/gLSB/symversion.html#SYMVERTBL Differential revision: https://reviews.llvm.org/D58280 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@354338 91177308-0d34-0410-b5e6-96231b3b80d8 George Rimar 8 months ago
6 changed file(s) with 206 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
121121 Relocation,
122122 NoBits,
123123 Verneed,
124 Symver,
124125 MipsABIFlags
125126 };
126127 SectionKind Kind;
188189
189190 static bool classof(const Section *S) {
190191 return S->Kind == SectionKind::Verneed;
192 }
193 };
194
195 struct SymverSection : Section {
196 std::vector Entries;
197
198 SymverSection() : Section(SectionKind::Symver) {}
199
200 static bool classof(const Section *S) {
201 return S->Kind == SectionKind::Symver;
191202 }
192203 };
193204
871871 IO.mapOptional("Size", Section.Size, Hex64(0));
872872 }
873873
874 static void sectionMapping(IO &IO, ELFYAML::SymverSection &Section) {
875 commonSectionMapping(IO, Section);
876 IO.mapRequired("Entries", Section.Entries);
877 }
878
874879 static void sectionMapping(IO &IO, ELFYAML::VerneedSection &Section) {
875880 commonSectionMapping(IO, Section);
876881 IO.mapRequired("Info", Section.Info);
954959 Section.reset(new ELFYAML::MipsABIFlags());
955960 sectionMapping(IO, *cast(Section.get()));
956961 break;
962 case ELF::SHT_GNU_versym:
963 if (!IO.outputting())
964 Section.reset(new ELFYAML::SymverSection());
965 sectionMapping(IO, *cast(Section.get()));
966 break;
957967 case ELF::SHT_GNU_verneed:
958968 if (!IO.outputting())
959969 Section.reset(new ELFYAML::VerneedSection());
0 # RUN: yaml2obj %s -o %t
1 # RUN: obj2yaml %t | FileCheck %s
2
3 ## Check we are able to yamalize the SHT_GNU_versym section.
4
5 # CHECK: --- !ELF
6 # CHECK-NEXT: FileHeader:
7 # CHECK-NEXT: Class: ELFCLASS64
8 # CHECK-NEXT: Data: ELFDATA2LSB
9 # CHECK-NEXT: Type: ET_EXEC
10 # CHECK-NEXT: Machine: EM_X86_64
11 # CHECK-NEXT: Entry: 0x0000000000201000
12 # CHECK-NEXT: Sections:
13 # CHECK-NEXT: - Name: .gnu.version
14 # CHECK-NEXT: Type: SHT_GNU_versym
15 # CHECK-NEXT: Flags: [ SHF_ALLOC ]
16 # CHECK-NEXT: Address: 0x0000000000200210
17 # CHECK-NEXT: Link: .dynsym
18 # CHECK-NEXT: AddressAlign: 0x0000000000000002
19 # CHECK-NEXT: EntSize: 0x0000000000000002
20 # CHECK-NEXT: Entries: [ 0, 3, 4 ]
21 # CHECK-NEXT: Symbols: {}
22 # CHECK-NEXT: DynamicSymbols:
23 # CHECK-NEXT: Global:
24 # CHECK-NEXT: - Name: f1
25 # CHECK-NEXT: - Name: f2
26
27 --- !ELF
28 FileHeader:
29 Class: ELFCLASS64
30 Data: ELFDATA2LSB
31 Type: ET_EXEC
32 Machine: EM_X86_64
33 Entry: 0x0000000000201000
34 Sections:
35 - Name: .gnu.version
36 Type: SHT_GNU_versym
37 Flags: [ SHF_ALLOC ]
38 Address: 0x0000000000200210
39 Link: .dynsym
40 AddressAlign: 0x0000000000000002
41 EntSize: 0x0000000000000002
42 Entries: [ 0, 3, 4 ]
43 DynamicSymbols:
44 Global:
45 - Name: f1
46 - Name: f2
47 ...
0 # RUN: yaml2obj %s -o %t
1 # RUN: llvm-readelf -V %t | FileCheck %s
2
3 ## Check we are able to produce a valid SHT_GNU_versym
4 ## section from its description.
5
6 # CHECK: Version symbols {
7 # CHECK-NEXT: Section Name: .gnu.version
8 # CHECK-NEXT: Address: 0x200210
9 # CHECK-NEXT: Offset: 0x240
10 # CHECK-NEXT: Link: 6
11 # CHECK-NEXT: Symbols [
12 # CHECK-NEXT: Symbol {
13 # CHECK-NEXT: Version: 0
14 # CHECK-NEXT: Name:
15 # CHECK-NEXT: }
16 # CHECK-NEXT: Symbol {
17 # CHECK-NEXT: Version: 3
18 # CHECK-NEXT: Name: f1@v1
19 # CHECK-NEXT: }
20 # CHECK-NEXT: Symbol {
21 # CHECK-NEXT: Version: 4
22 # CHECK-NEXT: Name: f2@v2
23 # CHECK-NEXT: }
24 # CHECK-NEXT: ]
25 # CHECK-NEXT: }
26 # CHECK-NEXT: SHT_GNU_verdef {
27 # CHECK-NEXT: }
28 # CHECK-NEXT: SHT_GNU_verneed {
29 # CHECK-NEXT: Dependency {
30 # CHECK-NEXT: Version: 1
31 # CHECK-NEXT: Count: 2
32 # CHECK-NEXT: FileName: dso.so.0
33 # CHECK-NEXT: Entry {
34 # CHECK-NEXT: Hash: 1937
35 # CHECK-NEXT: Flags: 0x0
36 # CHECK-NEXT: Index: 3
37 # CHECK-NEXT: Name: v1
38 # CHECK-NEXT: }
39 # CHECK-NEXT: Entry {
40 # CHECK-NEXT: Hash: 1938
41 # CHECK-NEXT: Flags: 0x0
42 # CHECK-NEXT: Index: 4
43 # CHECK-NEXT: Name: v2
44 # CHECK-NEXT: }
45 # CHECK-NEXT: }
46 # CHECK-NEXT: }
47
48 --- !ELF
49 FileHeader:
50 Class: ELFCLASS64
51 Data: ELFDATA2LSB
52 Type: ET_EXEC
53 Machine: EM_X86_64
54 Entry: 0x0000000000201000
55 Sections:
56 - Name: .gnu.version
57 Type: SHT_GNU_versym
58 Flags: [ SHF_ALLOC ]
59 Address: 0x0000000000200210
60 Link: .dynsym
61 AddressAlign: 0x0000000000000002
62 EntSize: 0x0000000000000002
63 Entries: [ 0, 3, 4 ]
64 - Name: .gnu.version_r
65 Type: SHT_GNU_verneed
66 Flags: [ SHF_ALLOC ]
67 Address: 0x0000000000200250
68 Link: .dynstr
69 AddressAlign: 0x0000000000000004
70 Info: 0x0000000000000001
71 Dependencies:
72 - Version: 1
73 File: dso.so.0
74 Entries:
75 - Name: v1
76 Hash: 1937
77 Flags: 0
78 Other: 3
79 - Name: v2
80 Hash: 1938
81 Flags: 0
82 Other: 4
83 DynamicSymbols:
84 Global:
85 - Name: f1
86 - Name: f2
87 ...
5656 ErrorOr
5757 dumpContentSection(const Elf_Shdr *Shdr);
5858 ErrorOr dumpNoBitsSection(const Elf_Shdr *Shdr);
59 ErrorOr dumpSymverSection(const Elf_Shdr *Shdr);
5960 ErrorOr dumpVerneedSection(const Elf_Shdr *Shdr);
6061 ErrorOr dumpGroup(const Elf_Shdr *Shdr);
6162 ErrorOr dumpMipsABIFlags(const Elf_Shdr *Shdr);
184185 Y->Sections.push_back(std::unique_ptr(S.get()));
185186 break;
186187 }
188 case ELF::SHT_GNU_versym: {
189 ErrorOr S = dumpSymverSection(&Sec);
190 if (std::error_code EC = S.getError())
191 return EC;
192 Y->Sections.push_back(std::unique_ptr(S.get()));
193 break;
194 }
187195 case ELF::SHT_GNU_verneed: {
188196 ErrorOr S = dumpVerneedSection(&Sec);
189197 if (std::error_code EC = S.getError())
446454 if (std::error_code EC = dumpCommonSection(Shdr, *S))
447455 return EC;
448456 S->Size = Shdr->sh_size;
457
458 return S.release();
459 }
460
461 template
462 ErrorOr
463 ELFDumper::dumpSymverSection(const Elf_Shdr *Shdr) {
464 typedef typename ELFT::Half Elf_Half;
465
466 auto S = make_unique();
467 if (std::error_code EC = dumpCommonSection(Shdr, *S))
468 return EC;
469
470 auto VersionsOrErr = Obj.template getSectionContentsAsArray(Shdr);
471 if (!VersionsOrErr)
472 return errorToErrorCode(VersionsOrErr.takeError());
473 for (const Elf_Half &E : *VersionsOrErr)
474 S->Entries.push_back(E);
449475
450476 return S.release();
451477 }
154154 const ELFYAML::RelocationSection &Section,
155155 ContiguousBlobAccumulator &CBA);
156156 bool writeSectionContent(Elf_Shdr &SHeader, const ELFYAML::Group &Group,
157 ContiguousBlobAccumulator &CBA);
158 bool writeSectionContent(Elf_Shdr &SHeader,
159 const ELFYAML::SymverSection &Section,
157160 ContiguousBlobAccumulator &CBA);
158161 bool writeSectionContent(Elf_Shdr &SHeader,
159162 const ELFYAML::VerneedSection &Section,
302305 CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign);
303306 } else if (auto S = dyn_cast(Sec.get())) {
304307 writeSectionContent(SHeader, *S, CBA);
308 } else if (auto S = dyn_cast(Sec.get())) {
309 writeSectionContent(SHeader, *S, CBA);
305310 } else if (auto S = dyn_cast(Sec.get())) {
306311 writeSectionContent(SHeader, *S, CBA);
307312 } else
568573
569574 template
570575 bool ELFState::writeSectionContent(Elf_Shdr &SHeader,
576 const ELFYAML::SymverSection &Section,
577 ContiguousBlobAccumulator &CBA) {
578 typedef typename ELFT::Half Elf_Half;
579
580 raw_ostream &OS =
581 CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign);
582 for (uint16_t V : Section.Entries) {
583 Elf_Half Version = (Elf_Half)V;
584 OS.write((const char *)&Version, sizeof(Elf_Half));
585 }
586
587 SHeader.sh_size = Section.Entries.size() * sizeof(Elf_Half);
588 SHeader.sh_entsize = sizeof(Elf_Half);
589 return true;
590 }
591
592 template
593 bool ELFState::writeSectionContent(Elf_Shdr &SHeader,
571594 const ELFYAML::VerneedSection &Section,
572595 ContiguousBlobAccumulator &CBA) {
573596 typedef typename ELFT::Verneed Elf_Verneed;