llvm.org GIT mirror llvm / afcf60f
[yaml2obj][ELF] Rudimentary symbol table support. Currently, we only output the name. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@184255 91177308-0d34-0410-b5e6-96231b3b80d8 Sean Silva 7 years ago
4 changed file(s) with 86 addition(s) and 2 deletion(s). Raw diff Collapse all Expand all
4848 ELF_EM Machine;
4949 llvm::yaml::Hex64 Entry;
5050 };
51 struct Symbol {
52 StringRef Name;
53 };
5154 struct Section {
5255 StringRef Name;
5356 ELF_SHT Type;
5659 object::yaml::BinaryRef Content;
5760 StringRef Link;
5861 llvm::yaml::Hex64 AddressAlign;
62 // For SHT_SYMTAB; should be empty otherwise.
63 std::vector Symbols;
5964 };
6065 struct Object {
6166 FileHeader Header;
6671 } // end namespace llvm
6772
6873 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Section)
74 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Symbol)
6975
7076 namespace llvm {
7177 namespace yaml {
106112 };
107113
108114 template <>
115 struct MappingTraits {
116 static void mapping(IO &IO, ELFYAML::Symbol &Symbol);
117 };
118
119 template <>
109120 struct MappingTraits {
110121 static void mapping(IO &IO, ELFYAML::Section &Section);
111122 };
259259 IO.mapOptional("Entry", FileHdr.Entry, Hex64(0));
260260 }
261261
262 void MappingTraits::mapping(IO &IO, ELFYAML::Symbol &Symbol) {
263 IO.mapOptional("Name", Symbol.Name, StringRef());
264 }
265
262266 void MappingTraits::mapping(IO &IO,
263267 ELFYAML::Section &Section) {
264268 IO.mapOptional("Name", Section.Name, StringRef());
268272 IO.mapOptional("Content", Section.Content);
269273 IO.mapOptional("Link", Section.Link);
270274 IO.mapOptional("AddressAlign", Section.AddressAlign, Hex64(0));
275 // TODO: Error if `Type` is SHT_SYMTAB and this is not present, or if
276 // `Type` is *not* SHT_SYMTAB and this *is* present. (By SHT_SYMTAB I
277 // also mean SHT_DYNSYM, but for simplicity right now we just do
278 // SHT_SYMTAB). Want to be able to share the predicate with consumers of
279 // this structure.
280 IO.mapOptional("Symbols", Section.Symbols);
271281 }
272282
273283 void MappingTraits::mapping(IO &IO, ELFYAML::Object &Object) {
0 # RUN: yaml2obj -format=elf %s | llvm-readobj -symbols - | FileCheck %s
1 !ELF
2 FileHeader:
3 Class: ELFCLASS64
4 Data: ELFDATA2LSB
5 Type: ET_REL
6 Machine: EM_X86_64
7 Sections:
8 - Name: .text
9 Type: SHT_PROGBITS
10 Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
11 - Name: .symtab
12 Type: SHT_SYMTAB
13 Symbols:
14 - Name: "" # TODO: Add STN_UNDEF automatically.
15 - Name: main
16
17 # CHECK: Symbols [
18 # CHECK-NEXT: Symbol {
19 # CHECK-NEXT: Name: (0)
20 # CHECK: Symbol {
21 # CHECK-NEXT: Name: main
130130 SHeader.sh_size = STB.size();
131131 STB.writeToStream(CBA.getOS());
132132 SHeader.sh_addralign = 1;
133 }
134
135 // FIXME: This function is hideous. Between the sheer number of parameters
136 // and the hideous ELF typenames, it's just a travesty. Factor the ELF
137 // output into a class (templated on ELFT) and share some typedefs.
138 template
139 static void handleSymtabSectionHeader(
140 const ELFYAML::Section &Sec,
141 const typename object::ELFObjectFile::Elf_Ehdr &Header,
142 typename object::ELFObjectFile::Elf_Shdr &SHeader,
143 StringTableBuilder &StrTab, ContiguousBlobAccumulator &CBA,
144 unsigned DotStrtabSecNo) {
145
146 typedef typename object::ELFObjectFile::Elf_Sym Elf_Sym;
147 // TODO: Ensure that a manually specified `Link` field is diagnosed as an
148 // error for SHT_SYMTAB.
149 SHeader.sh_link = DotStrtabSecNo;
150 // TODO: Once we handle symbol binding, this should be one greater than
151 // symbol table index of the last local symbol.
152 SHeader.sh_info = 0;
153 SHeader.sh_entsize = sizeof(Elf_Sym);
154
155 std::vector Syms;
156 // FIXME: Ensure STN_UNDEF entry is present.
157 for (unsigned i = 0, e = Sec.Symbols.size(); i != e; ++i) {
158 const ELFYAML::Symbol &Sym = Sec.Symbols[i];
159 Elf_Sym Symbol;
160 zero(Symbol);
161 if (!Sym.Name.empty())
162 Symbol.st_name = StrTab.addString(Sym.Name);
163 Syms.push_back(Symbol);
164 }
165
166 SHeader.sh_offset = CBA.currentOffset();
167 SHeader.sh_size = vectorDataSize(Syms);
168 writeVectorData(CBA.getOS(), Syms);
133169 }
134170
135171 template
180216 Header.e_shnum = Sections.size() + 2;
181217 // Place section header string table last.
182218 Header.e_shstrndx = Sections.size() + 1;
219 const unsigned DotStrtabSecNo = Sections.size();
183220
184221 SectionNameToIdxMap SN2I;
185222 for (unsigned i = 0, e = Sections.size(); i != e; ++i) {
201238 Header.e_ehsize + Header.e_shentsize * Header.e_shnum;
202239 ContiguousBlobAccumulator CBA(SectionContentBeginOffset, Buf);
203240 std::vector SHeaders;
241 StringTableBuilder DotStrTab;
204242 for (unsigned i = 0, e = Sections.size(); i != e; ++i) {
205243 const ELFYAML::Section &Sec = Sections[i];
206244 Elf_Shdr SHeader;
226264 SHeader.sh_info = 0;
227265 SHeader.sh_addralign = Sec.AddressAlign;
228266 SHeader.sh_entsize = 0;
267 // XXX: Really ugly right now. Need to put common state into a class.
268 if (Sec.Type == ELFYAML::ELF_SHT(SHT_SYMTAB))
269 handleSymtabSectionHeader(Sec, Header, SHeader, DotStrTab, CBA,
270 DotStrtabSecNo);
229271 SHeaders.push_back(SHeader);
230272 }
231273
232 // .strtab string table header. Currently emitted empty.
233 StringTableBuilder DotStrTab;
274 // .strtab string table header.
234275 Elf_Shdr DotStrTabSHeader;
235276 zero(DotStrTabSHeader);
236277 DotStrTabSHeader.sh_name = SHStrTab.addString(StringRef(".strtab"));