llvm.org GIT mirror llvm / 4235ba3
[yaml2obj][ELF] Don't explicitly set `Binding` with STB_* Instead, just have 3 sub-lists, one for each of {STB_LOCAL,STB_GLOBAL,STB_WEAK}. This allows us to be a lot more explicit w.r.t. the symbol ordering in the object file, because if we allowed explicitly setting the STB_* `Binding` key for the symbol, then we might have ended up having to shuffle STB_LOCAL symbols to the front of the list, which is likely to cause confusion and potential for error. Also, this new approach is simpler ;) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@184506 91177308-0d34-0410-b5e6-96231b3b80d8 Sean Silva 7 years ago
5 changed file(s) with 99 addition(s) and 51 deletion(s). Raw diff Collapse all Expand all
3939 LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_SHT)
4040 // Just use 64, since it can hold 32-bit values too.
4141 LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_SHF)
42 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STB)
4342 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STT)
4443
4544 // For now, hardcode 64 bits everywhere that 32 or 64 would be needed
5453 };
5554 struct Symbol {
5655 StringRef Name;
57 ELF_STB Binding;
5856 ELF_STT Type;
5957 StringRef Section;
6058 llvm::yaml::Hex64 Value;
6159 llvm::yaml::Hex64 Size;
60 };
61 struct LocalGlobalWeakSymbols {
62 std::vector Local;
63 std::vector Global;
64 std::vector Weak;
6265 };
6366 struct Section {
6467 StringRef Name;
6972 StringRef Link;
7073 llvm::yaml::Hex64 AddressAlign;
7174 // For SHT_SYMTAB; should be empty otherwise.
72 std::vector Symbols;
75 LocalGlobalWeakSymbols Symbols;
7376 };
7477 struct Object {
7578 FileHeader Header;
121124 };
122125
123126 template <>
124 struct ScalarEnumerationTraits {
125 static void enumeration(IO &IO, ELFYAML::ELF_STB &Value);
126 };
127
128 template <>
129127 struct ScalarEnumerationTraits {
130128 static void enumeration(IO &IO, ELFYAML::ELF_STT &Value);
131129 };
138136 template <>
139137 struct MappingTraits {
140138 static void mapping(IO &IO, ELFYAML::Symbol &Symbol);
139 };
140
141 template <>
142 struct MappingTraits {
143 static void mapping(IO &IO, ELFYAML::LocalGlobalWeakSymbols &Symbols);
141144 };
142145
143146 template <>
277277 #undef BCase
278278 }
279279
280 void ScalarEnumerationTraits::enumeration(
281 IO &IO, ELFYAML::ELF_STB &Value) {
282 #define ECase(X) IO.enumCase(Value, #X, ELF::X);
283 ECase(STB_LOCAL)
284 ECase(STB_GLOBAL)
285 ECase(STB_WEAK)
286 #undef ECase
287 }
288
289280 void ScalarEnumerationTraits::enumeration(
290281 IO &IO, ELFYAML::ELF_STT &Value) {
291282 #define ECase(X) IO.enumCase(Value, #X, ELF::X);
312303
313304 void MappingTraits::mapping(IO &IO, ELFYAML::Symbol &Symbol) {
314305 IO.mapOptional("Name", Symbol.Name, StringRef());
315 IO.mapOptional("Binding", Symbol.Binding, ELFYAML::ELF_STB(0));
316306 IO.mapOptional("Type", Symbol.Type, ELFYAML::ELF_STT(0));
317307 IO.mapOptional("Section", Symbol.Section, StringRef());
318308 IO.mapOptional("Value", Symbol.Value, Hex64(0));
319309 IO.mapOptional("Size", Symbol.Size, Hex64(0));
310 }
311
312 void MappingTraits::mapping(
313 IO &IO, ELFYAML::LocalGlobalWeakSymbols &Symbols) {
314 IO.mapOptional("Local", Symbols.Local);
315 IO.mapOptional("Global", Symbols.Global);
316 IO.mapOptional("Weak", Symbols.Weak);
320317 }
321318
322319 void MappingTraits::mapping(IO &IO,
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: .data
9 Type: SHT_PROGBITS
10 Flags: [ SHF_ALLOC, SHF_WRITE ]
11 Content: "DEADBEEF"
12 - Name: .symtab
13 Type: SHT_SYMTAB
14 Symbols:
15 Local:
16 - Name: local_symbol
17 Type: STT_OBJECT
18 Section: .data
19 Global:
20 - Name: global_symbol
21 Type: STT_OBJECT
22 Section: .data
23 Weak:
24 - Name: weak_symbol
25 Type: STT_OBJECT
26 Section: .data
27
28 # CHECK: Symbol {
29 # CHECK: Name: (0)
30 # CHECK: Symbol {
31 # CHECK: Name: local_symbol
32 # CHECK: Binding: Local
33 # CHECK: Symbol {
34 # CHECK: Name: global_symbol
35 # CHECK: Binding: Global
36 # CHECK: Symbol {
37 # CHECK: Name: weak_symbol
38 # CHECK: Binding: Weak
1919 - Name: .symtab
2020 Type: SHT_SYMTAB
2121 Symbols:
22 - Name: main
23 Binding: STB_GLOBAL
24 Type: STT_FUNC
25 Section: .text
26 Value: 0x1
27 Size: 2
22 Global:
23 - Name: main
24 Type: STT_FUNC
25 Section: .text
26 Value: 0x1
27 Size: 2
2828
2929 # CHECK: Symbols [
3030 # CHECK-NEXT: Symbol {
167167 };
168168 } // end anonymous namespace
169169
170 // FIXME: This function is hideous. The hideous ELF type names are hideous.
171 // Factor the ELF output into a class (templated on ELFT) and share some
172 // typedefs.
173 template
174 static void handleSymtabSectionHeader(
175 const ELFYAML::Section &Sec, ELFState &State,
176 typename object::ELFObjectFile::Elf_Shdr &SHeader) {
177
178 typedef typename object::ELFObjectFile::Elf_Sym Elf_Sym;
179 // TODO: Ensure that a manually specified `Link` field is diagnosed as an
180 // error for SHT_SYMTAB.
181 SHeader.sh_link = State.getDotStrTabSecNo();
182 // TODO: Once we handle symbol binding, this should be one greater than
183 // symbol table index of the last local symbol.
184 SHeader.sh_info = 0;
185 SHeader.sh_entsize = sizeof(Elf_Sym);
186
187 std::vector Syms;
188 {
189 // Ensure STN_UNDEF is present
190 Elf_Sym Sym;
191 zero(Sym);
192 Syms.push_back(Sym);
193 }
194 for (unsigned i = 0, e = Sec.Symbols.size(); i != e; ++i) {
195 const ELFYAML::Symbol &Sym = Sec.Symbols[i];
170 // FIXME: At this point it is fairly clear that we need to refactor these
171 // static functions into methods of a class sharing some typedefs. These
172 // ELF type names are insane.
173 template
174 class Elf_Sym = typename object::ELFObjectFile::Elf_Sym>
175 static void addSymbols(const std::vector &Symbols,
176 ELFState &State, std::vector &Syms,
177 unsigned SymbolBinding) {
178 for (unsigned i = 0, e = Symbols.size(); i != e; ++i) {
179 const ELFYAML::Symbol &Sym = Symbols[i];
196180 Elf_Sym Symbol;
197181 zero(Symbol);
198182 if (!Sym.Name.empty())
199183 Symbol.st_name = State.getStringTable().addString(Sym.Name);
200 Symbol.setBindingAndType(Sym.Binding, Sym.Type);
184 Symbol.setBindingAndType(SymbolBinding, Sym.Type);
201185 unsigned Index;
202186 if (State.getSN2I().lookupSection(Sym.Section, Index)) {
203187 errs() << "error: Unknown section referenced: '" << Sym.Section
209193 Symbol.st_size = Sym.Size;
210194 Syms.push_back(Symbol);
211195 }
196 }
197
198 template
199 static void handleSymtabSectionHeader(
200 const ELFYAML::Section &Sec, ELFState &State,
201 typename object::ELFObjectFile::Elf_Shdr &SHeader) {
202
203 typedef typename object::ELFObjectFile::Elf_Sym Elf_Sym;
204 // TODO: Ensure that a manually specified `Link` field is diagnosed as an
205 // error for SHT_SYMTAB.
206 SHeader.sh_link = State.getDotStrTabSecNo();
207 // One greater than symbol table index of the last local symbol.
208 SHeader.sh_info = Sec.Symbols.Local.size() + 1;
209 SHeader.sh_entsize = sizeof(Elf_Sym);
210
211 std::vector Syms;
212 {
213 // Ensure STN_UNDEF is present
214 Elf_Sym Sym;
215 zero(Sym);
216 Syms.push_back(Sym);
217 }
218 addSymbols(Sec.Symbols.Local, State, Syms, ELF::STB_LOCAL);
219 addSymbols(Sec.Symbols.Global, State, Syms, ELF::STB_GLOBAL);
220 addSymbols(Sec.Symbols.Weak, State, Syms, ELF::STB_WEAK);
212221
213222 ContiguousBlobAccumulator &CBA = State.getSectionContentAccum();
214223 SHeader.sh_offset = CBA.currentOffset();