[llvm-commits] [lld] r171127 - in /lld/trunk: include/lld/Core/DefinedAtom.h lib/ReaderWriter/ELF/AtomsELF.h lib/ReaderWriter/ELF/ReaderELF.cpp test/elf/phdr.objtxt test/elf/reloc.objtxt
Shankar Easwaran
shankare at codeaurora.org
Wed Dec 26 17:40:08 PST 2012
Author: shankare
Date: Wed Dec 26 19:40:08 2012
New Revision: 171127
URL: http://llvm.org/viewvc/llvm-project?rev=171127&view=rev
Log:
changes for the ELF Reader : split up into AtomsELF.h/Adding new permissions permRWX
Added:
lld/trunk/lib/ReaderWriter/ELF/AtomsELF.h
Modified:
lld/trunk/include/lld/Core/DefinedAtom.h
lld/trunk/lib/ReaderWriter/ELF/ReaderELF.cpp
lld/trunk/test/elf/phdr.objtxt
lld/trunk/test/elf/reloc.objtxt
Modified: lld/trunk/include/lld/Core/DefinedAtom.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/DefinedAtom.h?rev=171127&r1=171126&r2=171127&view=diff
==============================================================================
--- lld/trunk/include/lld/Core/DefinedAtom.h (original)
+++ lld/trunk/include/lld/Core/DefinedAtom.h Wed Dec 26 19:40:08 2012
@@ -147,8 +147,9 @@
enum ContentPermissions {
perm___ = 0, // mapped as unaccessible
permR__ = 8, // mapped read-only
- permR_X = 8 + 2, // mapped readable and executable
- permRW_ = 8 + 4, // mapped readable and writable
+ permRW_ = 8 + 2, // mapped readable and writable
+ permR_X = 8 + 4, // mapped readable and executable
+ permRWX = 8 + 4 + 2, // mapped readable and writable and executable
permRW_L = 8 + 4 + 1, // initially mapped r/w, then made read-only
// loader writable
};
Added: lld/trunk/lib/ReaderWriter/ELF/AtomsELF.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/AtomsELF.h?rev=171127&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/AtomsELF.h (added)
+++ lld/trunk/lib/ReaderWriter/ELF/AtomsELF.h Wed Dec 26 19:40:08 2012
@@ -0,0 +1,409 @@
+#ifndef LLD_ELFATOMS_H_
+#define LLD_ELFATOMS_H_
+
+#include "lld/Core/LLVM.h"
+#include <memory>
+#include <vector>
+
+namespace lld {
+/// \brief Relocation References: Defined Atoms may contain references that will
+/// need to be patched before the executable is written.
+template <llvm::support::endianness target_endianness, bool is64Bits>
+class ELFReference final : 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 *rela, uint64_t offset, const Atom *target)
+ : _target(target)
+ , _targetSymbolIndex(rela->getSymbol())
+ , _offsetInAtom(offset)
+ , _addend(rela->r_addend)
+ , _kind(rela->getType()) {}
+
+ ELFReference(const Elf_Rel *rel, uint64_t offset, const Atom *target)
+ : _target(target)
+ , _targetSymbolIndex(rel->getSymbol())
+ , _offsetInAtom(offset)
+ , _addend(0)
+ , _kind(rel->getType()) {}
+
+ virtual uint64_t offsetInAtom() const {
+ return _offsetInAtom;
+ }
+
+ virtual Kind kind() const {
+ return _kind;
+ }
+
+ virtual void setKind(Kind kind) {
+ _kind = kind;
+ }
+
+ virtual const Atom *target() const {
+ return _target;
+ }
+
+ /// \brief The symbol table index that contains the target reference.
+ uint64_t targetSymbolIndex() const {
+ return _targetSymbolIndex;
+ }
+
+ virtual Addend addend() const {
+ return _addend;
+ }
+
+ virtual void setAddend(Addend A) {
+ _addend = A;
+ }
+
+ virtual void setTarget(const Atom *newAtom) {
+ _target = newAtom;
+ }
+private:
+ const Atom *_target;
+ uint64_t _targetSymbolIndex;
+ uint64_t _offsetInAtom;
+ Addend _addend;
+ Kind _kind;
+};
+
+/// \brief 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.
+template<llvm::support::endianness target_endianness, bool is64Bits>
+class ELFAbsoluteAtom final : public AbsoluteAtom {
+ typedef llvm::object::Elf_Sym_Impl<target_endianness, is64Bits> Elf_Sym;
+
+public:
+ ELFAbsoluteAtom(const File &file,
+ llvm::StringRef name,
+ const Elf_Sym *symbol,
+ uint64_t value)
+ : _owningFile(file)
+ , _name(name)
+ , _symbol(symbol)
+ , _value(value)
+ {}
+
+ virtual const class File &file() const {
+ return _owningFile;
+ }
+
+ virtual Scope scope() const {
+ if (_symbol->st_other == llvm::ELF::STV_HIDDEN)
+ return scopeLinkageUnit;
+ if (_symbol->getBinding() == llvm::ELF::STB_LOCAL)
+ return scopeTranslationUnit;
+ else
+ return scopeGlobal;
+ }
+
+ virtual llvm::StringRef name() const {
+ return _name;
+ }
+
+ virtual uint64_t value() const {
+ return _value;
+ }
+
+private:
+ const File &_owningFile;
+ llvm::StringRef _name;
+ const Elf_Sym *_symbol;
+ uint64_t _value;
+};
+
+/// \brief ELFUndefinedAtom: These atoms store undefined symbols and are place
+/// holders that will be replaced by defined atoms later in the linking process.
+template<llvm::support::endianness target_endianness, bool is64Bits>
+class ELFUndefinedAtom final: public UndefinedAtom {
+ typedef llvm::object::Elf_Sym_Impl<target_endianness, is64Bits> Elf_Sym;
+
+public:
+ ELFUndefinedAtom(const File &file,
+ llvm::StringRef name,
+ const Elf_Sym *symbol)
+ : _owningFile(file)
+ , _name(name)
+ , _symbol(symbol)
+ {}
+
+ virtual const class File &file() const {
+ return _owningFile;
+ }
+
+ virtual llvm::StringRef name() const {
+ return _name;
+ }
+
+ // FIXME: What distinguishes a symbol in ELF that can help decide if the
+ // symbol is undefined only during build and not runtime? This will make us
+ // choose canBeNullAtBuildtime and canBeNullAtRuntime.
+ virtual CanBeNull canBeNull() const {
+ if (_symbol->getBinding() == llvm::ELF::STB_WEAK)
+ return CanBeNull::canBeNullAtBuildtime;
+ else
+ return CanBeNull::canBeNullNever;
+ }
+
+private:
+ const File &_owningFile;
+ llvm::StringRef _name;
+ const Elf_Sym *_symbol;
+};
+
+/// \brief This atom stores defined symbols and will contain either data or
+/// code.
+template<llvm::support::endianness target_endianness, bool is64Bits>
+class ELFDefinedAtom final: public DefinedAtom {
+ typedef llvm::object::Elf_Sym_Impl<target_endianness, is64Bits> Elf_Sym;
+ typedef llvm::object::Elf_Shdr_Impl<target_endianness, is64Bits> Elf_Shdr;
+
+public:
+ ELFDefinedAtom(const File &file,
+ llvm::StringRef symbolName,
+ llvm::StringRef sectionName,
+ const Elf_Sym *symbol,
+ const Elf_Shdr *section,
+ llvm::ArrayRef<uint8_t> contentData,
+ unsigned int referenceStart,
+ unsigned int referenceEnd,
+ std::vector<ELFReference
+ <target_endianness, is64Bits> *> &referenceList)
+
+ : _owningFile(file)
+ , _symbolName(symbolName)
+ , _sectionName(sectionName)
+ , _symbol(symbol)
+ , _section(section)
+ , _contentData(contentData)
+ , _referenceStartIndex(referenceStart)
+ , _referenceEndIndex(referenceEnd)
+ , _referenceList(referenceList) {
+ static uint64_t orderNumber = 0;
+ _ordinal = ++orderNumber;
+ }
+
+ virtual const class File &file() const {
+ return _owningFile;
+ }
+
+ virtual llvm::StringRef name() const {
+ return _symbolName;
+ }
+
+ virtual uint64_t ordinal() const {
+ return _ordinal;
+ }
+
+ virtual uint64_t size() const {
+ // Common symbols are not allocated in object files,
+ // so use st_size to tell how many bytes are required.
+ if ((_symbol->getType() == llvm::ELF::STT_COMMON)
+ || _symbol->st_shndx == llvm::ELF::SHN_COMMON)
+ return (uint64_t)_symbol->st_size;
+
+ return _contentData.size();
+ }
+
+ virtual Scope scope() const {
+ if (_symbol->st_other == llvm::ELF::STV_HIDDEN)
+ return scopeLinkageUnit;
+ else if (_symbol->getBinding() != llvm::ELF::STB_LOCAL)
+ return scopeGlobal;
+ else
+ return scopeTranslationUnit;
+ }
+
+ // FIXME: Need to revisit this in future.
+ virtual Interposable interposable() const {
+ return interposeNo;
+ }
+
+ // FIXME: What ways can we determine this in ELF?
+ virtual Merge merge() const {
+ if (_symbol->getBinding() == llvm::ELF::STB_WEAK)
+ return mergeAsWeak;
+
+ if ((_symbol->getType() == llvm::ELF::STT_COMMON)
+ || _symbol->st_shndx == llvm::ELF::SHN_COMMON)
+ return mergeAsTentative;
+
+ return mergeNo;
+ }
+
+ virtual ContentType contentType() const {
+
+ ContentType ret = typeUnknown;
+ uint64_t flags = _section->sh_flags;
+
+ if (_symbol->st_shndx == llvm::ELF::SHN_COMMON)
+ return typeZeroFill;
+
+ switch (_section->sh_type) {
+ case llvm::ELF::SHT_PROGBITS:
+ flags &= ~llvm::ELF::SHF_ALLOC;
+ flags &= ~llvm::ELF::SHF_GROUP;
+ switch (flags) {
+ case llvm::ELF::SHF_EXECINSTR:
+ case (llvm::ELF::SHF_WRITE|llvm::ELF::SHF_EXECINSTR):
+ ret = typeCode;
+ break;
+ case llvm::ELF::SHF_WRITE:
+ ret = typeData;
+ break;
+ case (llvm::ELF::SHF_MERGE|llvm::ELF::SHF_STRINGS):
+ case llvm::ELF::SHF_STRINGS:
+ ret = typeConstant;
+ break;
+ default:
+ ret = typeCode;
+ break;
+ }
+ break;
+ case llvm::ELF::SHT_NOBITS:
+ ret = typeZeroFill;
+ break;
+ case llvm::ELF::SHT_NULL:
+ if ((_symbol->getType() == llvm::ELF::STT_COMMON)
+ || _symbol->st_shndx == llvm::ELF::SHN_COMMON)
+ ret = typeZeroFill;
+ break;
+ }
+
+ return ret;
+ }
+
+ virtual Alignment alignment() const {
+ // Unallocated common symbols specify their alignment constraints in
+ // st_value.
+ if ((_symbol->getType() == llvm::ELF::STT_COMMON)
+ || _symbol->st_shndx == llvm::ELF::SHN_COMMON) {
+ return Alignment(llvm::Log2_64(_symbol->st_value));
+ }
+ return Alignment(llvm::Log2_64(_section->sh_addralign),
+ _symbol->st_value % _section->sh_addralign);
+ }
+
+ // Do we have a choice for ELF? All symbols live in explicit sections.
+ virtual SectionChoice sectionChoice() const {
+ if (_symbol->st_shndx > llvm::ELF::SHN_LORESERVE)
+ return sectionBasedOnContent;
+
+ return sectionCustomRequired;
+ }
+
+ virtual llvm::StringRef customSectionName() const {
+ if ((contentType() == typeZeroFill) ||
+ (_symbol->st_shndx == llvm::ELF::SHN_COMMON))
+ return ".bss";
+ return _sectionName;
+ }
+
+ // It isn't clear that __attribute__((used)) is transmitted to the ELF object
+ // file.
+ virtual DeadStripKind deadStrip() const {
+ return deadStripNormal;
+ }
+
+ virtual ContentPermissions permissions() const {
+ uint64_t flags = _section->sh_flags;
+ switch (_section->sh_type) {
+ // permRW_L is for sections modified by the runtime
+ // loader.
+ case llvm::ELF::SHT_REL:
+ case llvm::ELF::SHT_RELA:
+ return permRW_L;
+
+ case llvm::ELF::SHT_DYNAMIC:
+ case llvm::ELF::SHT_PROGBITS:
+ flags &= ~llvm::ELF::SHF_ALLOC;
+ flags &= ~llvm::ELF::SHF_GROUP;
+ switch (flags) {
+ // Code
+ case llvm::ELF::SHF_EXECINSTR:
+ return permR_X;
+ case (llvm::ELF::SHF_WRITE|llvm::ELF::SHF_EXECINSTR):
+ return permRWX;
+ // Data
+ case llvm::ELF::SHF_WRITE:
+ return permRW_;
+ // Strings
+ case llvm::ELF::SHF_MERGE:
+ case llvm::ELF::SHF_STRINGS:
+ return permR__;
+
+ default:
+ if (flags & llvm::ELF::SHF_WRITE)
+ return permRW_;
+ return permR__;
+ }
+
+ case llvm::ELF::SHT_NOBITS:
+ return permRW_;
+
+ default:
+ return perm___;
+ }
+ }
+
+ // Many non ARM architectures use ELF file format This not really a place to
+ // put a architecture specific method in an atom. A better approach is needed.
+ virtual bool isThumb() const {
+ return false;
+ }
+
+ // FIXME: Not Sure if ELF supports alias atoms. Find out more.
+ virtual bool isAlias() const {
+ return false;
+ }
+
+ virtual llvm::ArrayRef<uint8_t> rawContent() const {
+ return _contentData;
+ }
+
+ DefinedAtom::reference_iterator begin() const {
+ uintptr_t index = _referenceStartIndex;
+ const void *it = reinterpret_cast<const void*>(index);
+ return reference_iterator(*this, it);
+ }
+
+ DefinedAtom::reference_iterator end() const {
+ uintptr_t index = _referenceEndIndex;
+ const void *it = reinterpret_cast<const void*>(index);
+ return reference_iterator(*this, it);
+ }
+
+ const Reference *derefIterator(const void *It) const {
+ uintptr_t index = reinterpret_cast<uintptr_t>(It);
+ assert(index >= _referenceStartIndex);
+ assert(index < _referenceEndIndex);
+ return ((_referenceList)[index]);
+ }
+
+ void incrementIterator(const void*& It) const {
+ uintptr_t index = reinterpret_cast<uintptr_t>(It);
+ ++index;
+ It = reinterpret_cast<const void*>(index);
+ }
+
+private:
+
+ const File &_owningFile;
+ llvm::StringRef _symbolName;
+ llvm::StringRef _sectionName;
+ const Elf_Sym *_symbol;
+ const Elf_Shdr *_section;
+ /// \brief Holds the bits that make up the atom.
+ llvm::ArrayRef<uint8_t> _contentData;
+
+ uint64_t _ordinal;
+ unsigned int _referenceStartIndex;
+ unsigned int _referenceEndIndex;
+ std::vector<ELFReference<target_endianness, is64Bits> *> &_referenceList;
+};
+} // namespace lld
+#endif
Modified: lld/trunk/lib/ReaderWriter/ELF/ReaderELF.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/ReaderELF.cpp?rev=171127&r1=171126&r2=171127&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/ReaderELF.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/ReaderELF.cpp Wed Dec 26 19:40:08 2012
@@ -25,6 +25,7 @@
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Casting.h"
+#include "llvm/Support/Path.h"
#include "llvm/Support/ELF.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/ErrorHandling.h"
@@ -34,6 +35,7 @@
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/system_error.h"
+#include "AtomsELF.h"
#include <map>
#include <vector>
@@ -43,384 +45,6 @@
using llvm::support::endianness;
namespace {
-/// \brief Relocation References: Defined Atoms may contain references that will
-/// need to be patched before the executable is written.
-template <endianness target_endianness, bool is64Bits>
-class ELFReference final : 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 *rela, uint64_t offset, const Atom *target)
- : _target(target)
- , _targetSymbolIndex(rela->getSymbol())
- , _offsetInAtom(offset)
- , _addend(rela->r_addend)
- , _kind(rela->getType()) {}
-
- ELFReference(const Elf_Rel *rel, uint64_t offset, const Atom *target)
- : _target(target)
- , _targetSymbolIndex(rel->getSymbol())
- , _offsetInAtom(offset)
- , _addend(0)
- , _kind(rel->getType()) {}
-
- virtual uint64_t offsetInAtom() const {
- return _offsetInAtom;
- }
-
- virtual Kind kind() const {
- return _kind;
- }
-
- virtual void setKind(Kind kind) {
- _kind = kind;
- }
-
- virtual const Atom *target() const {
- return _target;
- }
-
- /// \brief The symbol table index that contains the target reference.
- uint64_t targetSymbolIndex() const {
- return _targetSymbolIndex;
- }
-
- virtual Addend addend() const {
- return _addend;
- }
-
- virtual void setAddend(Addend A) {
- _addend = A;
- }
-
- virtual void setTarget(const Atom *newAtom) {
- _target = newAtom;
- }
-private:
- const Atom *_target;
- uint64_t _targetSymbolIndex;
- uint64_t _offsetInAtom;
- Addend _addend;
- Kind _kind;
-};
-
-/// \brief 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.
-template<endianness target_endianness, bool is64Bits>
-class ELFAbsoluteAtom final : public AbsoluteAtom {
- typedef llvm::object::Elf_Sym_Impl<target_endianness, is64Bits> Elf_Sym;
-
-public:
- ELFAbsoluteAtom(const File &file,
- llvm::StringRef name,
- const Elf_Sym *symbol,
- uint64_t value)
- : _owningFile(file)
- , _name(name)
- , _symbol(symbol)
- , _value(value)
- {}
-
- virtual const class File &file() const {
- return _owningFile;
- }
-
- virtual Scope scope() const {
- if (_symbol->st_other == llvm::ELF::STV_HIDDEN)
- return scopeLinkageUnit;
- if (_symbol->getBinding() == llvm::ELF::STB_LOCAL)
- return scopeTranslationUnit;
- else
- return scopeGlobal;
- }
-
- virtual llvm::StringRef name() const {
- return _name;
- }
-
- virtual uint64_t value() const {
- return _value;
- }
-
-private:
- const File &_owningFile;
- llvm::StringRef _name;
- const Elf_Sym *_symbol;
- uint64_t _value;
-};
-
-/// \brief ELFUndefinedAtom: These atoms store undefined symbols and are place
-/// holders that will be replaced by defined atoms later in the linking process.
-template<endianness target_endianness, bool is64Bits>
-class ELFUndefinedAtom final: public UndefinedAtom {
- typedef llvm::object::Elf_Sym_Impl<target_endianness, is64Bits> Elf_Sym;
-
-public:
- ELFUndefinedAtom(const File &file,
- llvm::StringRef name,
- const Elf_Sym *symbol)
- : _owningFile(file)
- , _name(name)
- , _symbol(symbol)
- {}
-
- virtual const class File &file() const {
- return _owningFile;
- }
-
- virtual llvm::StringRef name() const {
- return _name;
- }
-
- // FIXME: What distinguishes a symbol in ELF that can help decide if the
- // symbol is undefined only during build and not runtime? This will make us
- // choose canBeNullAtBuildtime and canBeNullAtRuntime.
- virtual CanBeNull canBeNull() const {
- if (_symbol->getBinding() == llvm::ELF::STB_WEAK)
- return CanBeNull::canBeNullAtBuildtime;
- else
- return CanBeNull::canBeNullNever;
- }
-
-private:
- const File &_owningFile;
- llvm::StringRef _name;
- const Elf_Sym *_symbol;
-};
-
-/// \brief This atom stores defined symbols and will contain either data or
-/// code.
-template<endianness target_endianness, bool is64Bits>
-class ELFDefinedAtom final: public DefinedAtom {
- typedef llvm::object::Elf_Sym_Impl<target_endianness, is64Bits> Elf_Sym;
- typedef llvm::object::Elf_Shdr_Impl<target_endianness, is64Bits> Elf_Shdr;
-
-public:
- ELFDefinedAtom(const File &file,
- llvm::StringRef symbolName,
- llvm::StringRef sectionName,
- const Elf_Sym *symbol,
- const Elf_Shdr *section,
- llvm::ArrayRef<uint8_t> contentData,
- unsigned int referenceStart,
- unsigned int referenceEnd,
- std::vector<ELFReference
- <target_endianness, is64Bits> *> &referenceList)
-
- : _owningFile(file)
- , _symbolName(symbolName)
- , _sectionName(sectionName)
- , _symbol(symbol)
- , _section(section)
- , _contentData(contentData)
- , _referenceStartIndex(referenceStart)
- , _referenceEndIndex(referenceEnd)
- , _referenceList(referenceList) {
- static uint64_t orderNumber = 0;
- _ordinal = ++orderNumber;
- }
-
- virtual const class File &file() const {
- return _owningFile;
- }
-
- virtual llvm::StringRef name() const {
- return _symbolName;
- }
-
- virtual uint64_t ordinal() const {
- return _ordinal;
- }
-
- virtual uint64_t size() const {
- // Common symbols are not allocated in object files,
- // so use st_size to tell how many bytes are required.
- if ((_symbol->getType() == llvm::ELF::STT_COMMON)
- || _symbol->st_shndx == llvm::ELF::SHN_COMMON)
- return (uint64_t)_symbol->st_size;
-
- return _contentData.size();
- }
-
- virtual Scope scope() const {
- if (_symbol->st_other == llvm::ELF::STV_HIDDEN)
- return scopeLinkageUnit;
- else if (_symbol->getBinding() != llvm::ELF::STB_LOCAL)
- return scopeGlobal;
- else
- return scopeTranslationUnit;
- }
-
- // FIXME: Need to revisit this in future.
- virtual Interposable interposable() const {
- return interposeNo;
- }
-
- // FIXME: What ways can we determine this in ELF?
- virtual Merge merge() const {
- if (_symbol->getBinding() == llvm::ELF::STB_WEAK)
- return mergeAsWeak;
-
- if ((_symbol->getType() == llvm::ELF::STT_COMMON)
- || _symbol->st_shndx == llvm::ELF::SHN_COMMON)
- return mergeAsTentative;
-
- return mergeNo;
- }
-
- virtual ContentType contentType() const {
- ContentType ret = typeUnknown;
-
- switch (_section->sh_type) {
- case llvm::ELF::SHT_PROGBITS:
- case llvm::ELF::SHT_DYNAMIC:
- switch (_section->sh_flags & ~llvm::ELF::SHF_GROUP) {
- case (llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR
- | llvm::ELF::SHF_WRITE):
- ret = typeCode;
- break;
- case (llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR):
- ret = typeCode;
- break;
- case (llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE):
- ret = typeData;
- break;
- case llvm::ELF::SHF_ALLOC:
- case (llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_MERGE):
- case (llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_MERGE |
- llvm::ELF::SHF_STRINGS):
- ret = typeConstant;
- break;
- }
- break;
- case llvm::ELF::SHT_NOBITS:
- ret = typeZeroFill;
- break;
- case llvm::ELF::SHT_NULL:
- if ((_symbol->getType() == llvm::ELF::STT_COMMON)
- || _symbol->st_shndx == llvm::ELF::SHN_COMMON)
- ret = typeZeroFill;
- break;
- }
-
- return ret;
- }
-
- virtual Alignment alignment() const {
- // Unallocated common symbols specify their alignment constraints in
- // st_value.
- if ((_symbol->getType() == llvm::ELF::STT_COMMON)
- || _symbol->st_shndx == llvm::ELF::SHN_COMMON) {
- return Alignment(llvm::Log2_64(_symbol->st_value));
- }
- return Alignment(llvm::Log2_64(_section->sh_addralign));
- }
-
- // Do we have a choice for ELF? All symbols live in explicit sections.
- virtual SectionChoice sectionChoice() const {
- if (_symbol->st_shndx > llvm::ELF::SHN_LORESERVE)
- return sectionBasedOnContent;
-
- return sectionCustomRequired;
- }
-
- virtual llvm::StringRef customSectionName() const {
- return _sectionName;
- }
-
- // It isn't clear that __attribute__((used)) is transmitted to the ELF object
- // file.
- virtual DeadStripKind deadStrip() const {
- return deadStripNormal;
- }
-
- virtual ContentPermissions permissions() const {
- switch (_section->sh_type) {
- // permRW_L is for sections modified by the runtime loader.
- case llvm::ELF::SHT_REL:
- case llvm::ELF::SHT_RELA:
- return permRW_L;
-
- case llvm::ELF::SHT_DYNAMIC:
- case llvm::ELF::SHT_PROGBITS:
- switch (_section->sh_flags & ~llvm::ELF::SHF_GROUP) {
- case (llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR):
- return permR_X;
-
- case (llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE):
- return permRW_;
-
- case llvm::ELF::SHF_ALLOC:
- case (llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_MERGE):
- case (llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_MERGE
- | llvm::ELF::SHF_STRINGS):
- return permR__;
- }
- default:
- return perm___;
- }
- }
-
- // Many non ARM architectures use ELF file format This not really a place to
- // put a architecture specific method in an atom. A better approach is needed.
- virtual bool isThumb() const {
- return false;
- }
-
- // FIXME: Not Sure if ELF supports alias atoms. Find out more.
- virtual bool isAlias() const {
- return false;
- }
-
- virtual llvm::ArrayRef<uint8_t> rawContent() const {
- return _contentData;
- }
-
- DefinedAtom::reference_iterator begin() const {
- uintptr_t index = _referenceStartIndex;
- const void *it = reinterpret_cast<const void*>(index);
- return reference_iterator(*this, it);
- }
-
- DefinedAtom::reference_iterator end() const {
- uintptr_t index = _referenceEndIndex;
- const void *it = reinterpret_cast<const void*>(index);
- return reference_iterator(*this, it);
- }
-
- const Reference *derefIterator(const void *It) const {
- uintptr_t index = reinterpret_cast<uintptr_t>(It);
- assert(index >= _referenceStartIndex);
- assert(index < _referenceEndIndex);
- return ((_referenceList)[index]);
- }
-
- void incrementIterator(const void*& It) const {
- uintptr_t index = reinterpret_cast<uintptr_t>(It);
- ++index;
- It = reinterpret_cast<const void*>(index);
- }
-
-private:
-
- const File &_owningFile;
- llvm::StringRef _symbolName;
- llvm::StringRef _sectionName;
- const Elf_Sym *_symbol;
- const Elf_Shdr *_section;
- /// \brief Holds the bits that make up the atom.
- llvm::ArrayRef<uint8_t> _contentData;
-
- uint64_t _ordinal;
- unsigned int _referenceStartIndex;
- unsigned int _referenceEndIndex;
- std::vector<ELFReference<target_endianness, is64Bits> *> &_referenceList;
-};
-
// \brief Read a binary, find out based on the symbol table contents what kind
// of symbol it is and create corresponding atoms for it
template<endianness target_endianness, bool is64Bits>
@@ -636,7 +260,7 @@
<ELFDefinedAtom<target_endianness, is64Bits> > ())
ELFDefinedAtom<target_endianness, is64Bits>
(*this, symbolName, sectionName,
- *si, i.first, symbolData,
+ *si, i.first, symbolData,
referenceStart, _references.size(), _references);
_definedAtoms._atoms.push_back(newAtom);
Modified: lld/trunk/test/elf/phdr.objtxt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/phdr.objtxt?rev=171127&r1=171126&r2=171127&view=diff
==============================================================================
--- lld/trunk/test/elf/phdr.objtxt (original)
+++ lld/trunk/test/elf/phdr.objtxt Wed Dec 26 19:40:08 2012
@@ -2,15 +2,15 @@
ED: # Program Header 0
ED: 'p_flags', 0x00000005
-ED: 'p_filesz', 0x0000002a
+ED: 'p_filesz', 0x00000025
ED: # Program Header 1
ED: 'p_flags', 0x00000004
-ED: 'p_vaddr', 0x004010e0
-ED: 'p_memsz', 0x00000078
+ED: 'p_vaddr', 0x004010d9
+ED: 'p_memsz', 0x0000008b
ED: # Program Header 2
ED: 'p_flags', 0x00000006
-ED: 'p_vaddr', 0x00402158
-ED: 'p_memsz', 0x000000ac
+ED: 'p_vaddr', 0x00402164
+ED: 'p_memsz', 0x000000a0
ED: # Program Header 3
ED: 'p_flags', 0x00000006
ED: 'p_vaddr', 0x00404000
Modified: lld/trunk/test/elf/reloc.objtxt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/reloc.objtxt?rev=171127&r1=171126&r2=171127&view=diff
==============================================================================
--- lld/trunk/test/elf/reloc.objtxt (original)
+++ lld/trunk/test/elf/reloc.objtxt Wed Dec 26 19:40:08 2012
@@ -44,19 +44,19 @@
ELF-i386: target: puts
ELF-i386: - name: .comment
-ELF-i386: type: unknown
+ELF-i386: type: constant
ELF-i386: section-choice: custom-required
ELF-i386: section-name: .comment
ELF-i386: content: [ 00, 47, 43, 43, 3A, 20, 28, 47, 4E, 55, 29, 20,
ELF-i386: 34, 2E, 37, 2E, 30, 00 ]
ELF-i386: - name: .note.GNU-stack
-ELF-i386: type: unknown
+ELF-i386: type: code
ELF-i386: section-choice: custom-required
ELF-i386: section-name: .note.GNU-stack
ELF-i386: - name: .eh_frame
-ELF-i386: type: constant
+ELF-i386: type: code
ELF-i386: section-choice: custom-required
ELF-i386: section-name: .eh_frame
ELF-i386: content: [ 14, 00, 00, 00, 00, 00, 00, 00, 01, 7A, 52, 00,
More information about the llvm-commits
mailing list