[llvm-commits] ELFReader.cpp update - Add support for References.
Michael Spencer
bigcheesegs at gmail.com
Fri Sep 14 15:15:20 PDT 2012
On Fri, Sep 14, 2012 at 2:15 PM, Sid Manning <sidneym at codeaurora.org> wrote:
>
> Update to ReaderELF.cpp, ELF.h and test directory.
>
> -- Adds a testcase to check relocations are emitted. Looks like
> TestingHelpers will need to to be updated in the near future for the many
> relocation types elf will likely support.
> -- Addresses style issues.
> -- Adds doxygen comments to Atoms classes and elaborates on some routines.
> -- Changes DefinedAtom's declaration of ELFReference to a reference.
> -- Some loops changed to c++11 style.
> -- findAtom uses DenseMap::lookup instead of looping.
> -- Uses the iterator added to ELF.h to step through the SHT_REL/RELA
> sections. Thanks, Michael Spencer for the iterator in ELF.h.
>
> Thanks,
>
>
>
> --
> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by
> The Linux Foundation
> Index: include/llvm/Object/ELF.h
> ===================================================================
> --- include/llvm/Object/ELF.h (revision 163925)
> +++ include/llvm/Object/ELF.h (working copy)
> +
> +private:
> // Records for each version index the corresponding Verdef or Vernaux entry.
> // This is filled the first time LoadVersionMap() is called.
> class VersionMapEntry : public PointerIntPair<const void*, 1> {
> @@ -597,6 +650,27 @@
> virtual dyn_iterator begin_dynamic_table() const;
> virtual dyn_iterator end_dynamic_table() const;
>
> + typedef ELFRelocationIterator<const Elf_Rela *> Elf_Rela_Iter;
> + typedef ELFRelocationIterator<const Elf_Rel *> Elf_Rel_Iter;
These shouldn't have the const and *. ELFRelocationIterator already adds them.
With them opeartor * actually returns const RelocT * const &. This is why you
needed the reinterpret_casts in the other code.
> +
> + virtual Elf_Rela_Iter beginELFRela(const Elf_Shdr *sec) const {
> + return Elf_Rela_Iter(sec, (const char *)(base() + sec->sh_offset));
> + };
> +
> + virtual Elf_Rela_Iter endELFRela(const Elf_Shdr *sec) const {
> + return Elf_Rela_Iter(sec, (const char *)
> + (base() + sec->sh_offset + sec->sh_size));
> + };
> +
> Index: lib/ReaderWriter/ELF/ReaderELF.cpp
> ===================================================================
> --- lib/ReaderWriter/ELF/ReaderELF.cpp (revision 163928)
> +++ lib/ReaderWriter/ELF/ReaderELF.cpp (working copy)
> @@ -14,8 +14,10 @@
>
> #include "lld/ReaderWriter/ReaderELF.h"
> #include "lld/Core/File.h"
> +#include "lld/Core/Reference.h"
>
> #include "llvm/ADT/ArrayRef.h"
> +#include "llvm/ADT/SmallString.h"
> #include "llvm/ADT/StringRef.h"
> #include "llvm/Object/ELF.h"
> #include "llvm/Object/ObjectFile.h"
> @@ -39,38 +41,120 @@
>
> namespace { // anonymous
>
> -// This atom class corresponds to absolute symbol
> +
> +///
> +/// Relocation References: Defined Atoms may contain
> +/// references that will need to be patched before
> +/// the executable is written.
> +///
This should match the style used elsewhere. No extra /// at the top and bottom
and it should have a \brief, which in this case would be all the text that is
currently there.
> +template <llvm::support::endianness target_endianness, bool is64Bits>
> +class ELFReference : public Reference {
> +
> + typedef llvm::object::Elf_Rel_Impl
> + <target_endianness, is64Bits, false> Elf_Rel;
> + typedef llvm::object::Elf_Rel_Impl
> + <target_endianness, is64Bits, true> Elf_Rela;
> +public:
> +
> + ELFReference(const Elf_Rela *R, uint64_t O, const Atom *T)
> + : _target(T)
> + , _targetSymbolIndex(R->getSymbol())
> + , _offsetInAtom(O)
> + , _addend(R->r_addend)
> + , _kind(R->getType()) {}
> +
> + ELFReference(const Elf_Rel *R, uint64_t O, const Atom *T)
> + : _target(T)
> + , _targetSymbolIndex(R->getSymbol())
> + , _offsetInAtom(O)
> + , _addend(0)
> + , _kind(R->getType()) {}
> +
> +
> + virtual uint64_t offsetInAtom() const {
> + return _offsetInAtom;
> + }
> +
> + virtual Kind kind() const {
> + return _kind;
> + }
> +
> + virtual void setKind(Kind K) {
> + _kind = K;
> + }
> +
> + virtual const Atom *target() const {
> + return _target;
> + }
> +
> +///
> +/// targetSymbolIndex: This is the symbol table index that contains
> +/// the target reference.
> +///
Comment style.
> + virtual uint64_t targetSymbolIndex() const {
> + return _targetSymbolIndex;
> + }
This shouldn't be virtual.
> +
> + virtual Addend addend() const {
> + return _addend;
> + }
> +
> + virtual void setAddend(Addend A) {
> + _addend = A;
> + }
> +
> + virtual void setTarget(const Atom *newAtom) {
> + _target = newAtom;
> + }
All of these virtual functions should be marked as final.
> +private:
> + const Atom *_target;
> + uint64_t _targetSymbolIndex;
> + uint64_t _offsetInAtom;
> + Addend _addend;
> + Kind _kind;
> +};
> +
> +
> +///
> +/// ELFAbsoluteAtom: These atoms store symbols that are fixed to a particular
> +/// address. This atom has no content its address will be used by the
> +/// Writer to fixup references that point to it.
> +///
Comment style.
> +template<llvm::support::endianness target_endianness, bool is64Bits>
> class ELFAbsoluteAtom: public AbsoluteAtom {
>
> public:
> ELFAbsoluteAtom(const File &F,
> llvm::StringRef N,
> uint64_t V)
> - : OwningFile(F)
> - , Name(N)
> - , Value(V)
> + : _owningFile(F)
> + , _name(N)
> + , _value(V)
> {}
>
> virtual const class File &file() const {
> - return OwningFile;
> + return _owningFile;
> }
>
> virtual llvm::StringRef name() const {
> - return Name;
> + return _name;
> }
>
> virtual uint64_t value() const {
> - return Value;
> + return _value;
> }
>
> private:
> - const File &OwningFile;
> - llvm::StringRef Name;
> - uint64_t Value;
> + const File &_owningFile;
> + llvm::StringRef _name;
> + uint64_t _value;
> };
>
> - std::map< const Elf_Shdr *, std::vector<const Elf_Sym *>> SectionSymbols;
> + std::map< const Elf_Shdr *, std::vector<const Elf_Sym *>> sectionSymbols;
>
> - llvm::object::symbol_iterator it(Obj->begin_symbols());
> - llvm::object::symbol_iterator ie(Obj->end_symbols());
> +// Handle: SHT_REL and SHT_RELA sections:
> +// Increment over the sections, when REL/RELA section types are
> +// found add the contents to the RelocationReferences map.
>
> + llvm::object::section_iterator sit(_objFile->begin_sections());
> + llvm::object::section_iterator sie(_objFile->end_sections());
> + for (; sit != sie; sit.increment(EC)) {
> + if (EC)
> + return;
> +
> + const Elf_Shdr *section = _objFile->getElfSection(sit);
> +
> + if (section->sh_type == llvm::ELF::SHT_RELA) {
> + llvm::StringRef sectionName;
> + if ((EC = _objFile->getSectionName(section, sectionName)))
> + return;
> + // Get rid of the leading .rela so Atoms can use their own section
> + // name to find the relocs.
> + sectionName = sectionName.drop_front(5);
> +
> + auto rai(_objFile->beginELFRela(section));
> + auto rae(_objFile->endELFRela(section));
> +
> + auto &Ref = _relocationAddendRefences[sectionName];
> + for (; rai != rae; rai++) {
> + Ref.push_back(reinterpret_cast<const Elf_Rela *>(&*rai));
This cast is incorrect and should be removed. See my comments from ELF.h.
> + }
> + }
> +
> + if (section->sh_type == llvm::ELF::SHT_REL) {
> + llvm::StringRef sectionName;
> + if ((EC = _objFile->getSectionName(section, sectionName)))
> + return;
> + // Get rid of the leading .rel so Atoms can use their own section
> + // name to find the relocs.
> + sectionName = sectionName.drop_front(4);
> +
> + auto ri(_objFile->beginELFRel(section));
> + auto re(_objFile->endELFRel(section));
> +
> + auto &Ref = _relocationReferences[sectionName];
> + for (; ri != re; ri++) {
> + Ref.push_back(reinterpret_cast<const Elf_Rel *>(&*ri));
Same as above.
> + }
> + }
> + }
> +
> +
> +// Increment over all the symbols collecting atoms and symbol
> +// names for later use.
> +
> + llvm::object::symbol_iterator it(_objFile->begin_symbols());
> + llvm::object::symbol_iterator ie(_objFile->end_symbols());
> +
- Michael Spencer
More information about the llvm-commits
mailing list