From 4235ba32f2610ee2ed1e0c4bfca5c67835e9f97d Mon Sep 17 00:00:00 2001 From: Sean Silva Date: Fri, 21 Jun 2013 00:27:50 +0000 Subject: [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 --- tools/yaml2obj/yaml2elf.cpp | 57 ++++++++++++++++++++++++++------------------- 1 file changed, 33 insertions(+), 24 deletions(-) (limited to 'tools/yaml2obj') diff --git a/tools/yaml2obj/yaml2elf.cpp b/tools/yaml2obj/yaml2elf.cpp index a8eeeeacf1..cd6df144b7 100644 --- a/tools/yaml2obj/yaml2elf.cpp +++ b/tools/yaml2obj/yaml2elf.cpp @@ -168,9 +168,34 @@ public: }; } // end anonymous namespace -// FIXME: This function is hideous. The hideous ELF type names are hideous. -// Factor the ELF output into a class (templated on ELFT) and share some -// typedefs. +// FIXME: At this point it is fairly clear that we need to refactor these +// static functions into methods of a class sharing some typedefs. These +// ELF type names are insane. +template ::Elf_Sym> +static void addSymbols(const std::vector &Symbols, + ELFState &State, std::vector &Syms, + unsigned SymbolBinding) { + for (unsigned i = 0, e = Symbols.size(); i != e; ++i) { + const ELFYAML::Symbol &Sym = Symbols[i]; + Elf_Sym Symbol; + zero(Symbol); + if (!Sym.Name.empty()) + Symbol.st_name = State.getStringTable().addString(Sym.Name); + Symbol.setBindingAndType(SymbolBinding, Sym.Type); + unsigned Index; + if (State.getSN2I().lookupSection(Sym.Section, Index)) { + errs() << "error: Unknown section referenced: '" << Sym.Section + << "' by YAML symbol " << Sym.Name << ".\n"; + exit(1); + } + Symbol.st_shndx = Index; + Symbol.st_value = Sym.Value; + Symbol.st_size = Sym.Size; + Syms.push_back(Symbol); + } +} + template static void handleSymtabSectionHeader( const ELFYAML::Section &Sec, ELFState &State, @@ -180,9 +205,8 @@ static void handleSymtabSectionHeader( // TODO: Ensure that a manually specified `Link` field is diagnosed as an // error for SHT_SYMTAB. SHeader.sh_link = State.getDotStrTabSecNo(); - // TODO: Once we handle symbol binding, this should be one greater than - // symbol table index of the last local symbol. - SHeader.sh_info = 0; + // One greater than symbol table index of the last local symbol. + SHeader.sh_info = Sec.Symbols.Local.size() + 1; SHeader.sh_entsize = sizeof(Elf_Sym); std::vector Syms; @@ -192,24 +216,9 @@ static void handleSymtabSectionHeader( zero(Sym); Syms.push_back(Sym); } - for (unsigned i = 0, e = Sec.Symbols.size(); i != e; ++i) { - const ELFYAML::Symbol &Sym = Sec.Symbols[i]; - Elf_Sym Symbol; - zero(Symbol); - if (!Sym.Name.empty()) - Symbol.st_name = State.getStringTable().addString(Sym.Name); - Symbol.setBindingAndType(Sym.Binding, Sym.Type); - unsigned Index; - if (State.getSN2I().lookupSection(Sym.Section, Index)) { - errs() << "error: Unknown section referenced: '" << Sym.Section - << "' by YAML symbol " << Sym.Name << ".\n"; - exit(1); - } - Symbol.st_shndx = Index; - Symbol.st_value = Sym.Value; - Symbol.st_size = Sym.Size; - Syms.push_back(Symbol); - } + addSymbols(Sec.Symbols.Local, State, Syms, ELF::STB_LOCAL); + addSymbols(Sec.Symbols.Global, State, Syms, ELF::STB_GLOBAL); + addSymbols(Sec.Symbols.Weak, State, Syms, ELF::STB_WEAK); ContiguousBlobAccumulator &CBA = State.getSectionContentAccum(); SHeader.sh_offset = CBA.currentOffset(); -- cgit v1.2.3