[lld] r189872 - [lld][ELF][Hexagon] add Init/Fini option for hexagon

Shankar Easwaran shankare at codeaurora.org
Tue Sep 3 15:44:42 PDT 2013


Author: shankare
Date: Tue Sep  3 17:44:42 2013
New Revision: 189872

URL: http://llvm.org/viewvc/llvm-project?rev=189872&view=rev
Log:
[lld][ELF][Hexagon] add Init/Fini option for hexagon

This adds init/fini support for Hexagon.

Added:
    lld/trunk/test/elf/Hexagon/Inputs/initfini-option.c
    lld/trunk/test/elf/Hexagon/Inputs/initfini-option.o
    lld/trunk/test/elf/Hexagon/initfini-option.test
Modified:
    lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.cpp
    lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.h

Modified: lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.cpp?rev=189872&r1=189871&r2=189872&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.cpp Tue Sep  3 17:44:42 2013
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "Atoms.h"
 #include "HexagonLinkingContext.h"
 
 #include "lld/Core/File.h"
@@ -19,9 +20,93 @@
 #include "llvm/ADT/StringSwitch.h"
 
 using namespace lld;
+using namespace lld::elf;
 
 #define LLD_CASE(name) .Case(#name, llvm::ELF::name)
 
+namespace {
+
+const uint8_t hexagonInitFiniAtomContent[4] = { 0 };
+
+// HexagonInitFini Atom
+class HexagonInitAtom : public InitFiniAtom {
+public:
+  HexagonInitAtom(const File &f, StringRef function)
+      : InitFiniAtom(f, ".init_array") {
+#ifndef NDEBUG
+    _name = "__init_fn_";
+    _name += function;
+#endif
+  }
+  virtual ArrayRef<uint8_t> rawContent() const {
+    return ArrayRef<uint8_t>(hexagonInitFiniAtomContent, 4);
+  }
+
+  virtual Alignment alignment() const { return Alignment(2); }
+};
+
+class HexagonFiniAtom : public InitFiniAtom {
+public:
+  HexagonFiniAtom(const File &f, StringRef function)
+      : InitFiniAtom(f, ".fini_array") {
+#ifndef NDEBUG
+    _name = "__fini_fn_";
+    _name += function;
+#endif
+  }
+  virtual ArrayRef<uint8_t> rawContent() const {
+    return ArrayRef<uint8_t>(hexagonInitFiniAtomContent, 4);
+  }
+  virtual Alignment alignment() const { return Alignment(2); }
+};
+
+class HexagonInitFiniFile : public SimpleFile {
+public:
+  HexagonInitFiniFile(const ELFLinkingContext &context):
+    SimpleFile(context, "command line option -init/-fini")
+  {}
+
+  void addInitFunction(StringRef name) {
+    Atom *initFunctionAtom = new (_allocator) SimpleUndefinedAtom(*this, name);
+    HexagonInitAtom *initAtom =
+           (new (_allocator) HexagonInitAtom(*this, name));
+    initAtom->addReference(llvm::ELF::R_HEX_32, 0, initFunctionAtom, 0);
+    initAtom->setOrdinal(_ordinal++);
+    addAtom(*initFunctionAtom);
+    addAtom(*initAtom);
+  }
+
+  void addFiniFunction(StringRef name) {
+    Atom *finiFunctionAtom = new (_allocator) SimpleUndefinedAtom(*this, name);
+    HexagonFiniAtom *finiAtom =
+           (new (_allocator) HexagonFiniAtom(*this, name));
+    finiAtom->addReference(llvm::ELF::R_HEX_32, 0, finiFunctionAtom, 0);
+    finiAtom->setOrdinal(_ordinal++);
+    addAtom(*finiFunctionAtom);
+    addAtom(*finiAtom);
+  }
+
+private:
+  llvm::BumpPtrAllocator _allocator;
+};
+}
+
+
+std::vector<std::unique_ptr<File>>
+  elf::HexagonLinkingContext::createInternalFiles(){
+  std::vector<std::unique_ptr<File> > result =
+    ELFLinkingContext::createInternalFiles();
+  std::unique_ptr<HexagonInitFiniFile>
+    initFiniFile(new HexagonInitFiniFile(*this));
+  for (auto ai:initFunctions())
+    initFiniFile->addInitFunction(ai);
+  for (auto ai:finiFunctions())
+    initFiniFile->addFiniFunction(ai);
+  result.push_back(std::move(initFiniFile));
+  return result;
+}
+
+
 ErrorOr<Reference::Kind>
 elf::HexagonLinkingContext::relocKindFromString(StringRef str) const {
   int32_t ret = llvm::StringSwitch<int32_t>(str) LLD_CASE(R_HEX_NONE)

Modified: lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.h?rev=189872&r1=189871&r2=189872&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.h Tue Sep  3 17:44:42 2013
@@ -61,6 +61,9 @@ public:
       return false;
     }
   }
+
+  /// \brief Create Internal files for Init/Fini
+  std::vector<std::unique_ptr<File>> createInternalFiles();
 };
 
 } // elf

Added: lld/trunk/test/elf/Hexagon/Inputs/initfini-option.c
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Hexagon/Inputs/initfini-option.c?rev=189872&view=auto
==============================================================================
--- lld/trunk/test/elf/Hexagon/Inputs/initfini-option.c (added)
+++ lld/trunk/test/elf/Hexagon/Inputs/initfini-option.c Tue Sep  3 17:44:42 2013
@@ -0,0 +1,13 @@
+#include <stdio.h>
+
+void init() {
+ printf("%s\n", __FUNCTION__);
+}
+
+void fini() {
+ printf("%s\n", __FUNCTION__);
+}
+
+int main() {
+}
+

Added: lld/trunk/test/elf/Hexagon/Inputs/initfini-option.o
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Hexagon/Inputs/initfini-option.o?rev=189872&view=auto
==============================================================================
Binary files lld/trunk/test/elf/Hexagon/Inputs/initfini-option.o (added) and lld/trunk/test/elf/Hexagon/Inputs/initfini-option.o Tue Sep  3 17:44:42 2013 differ

Added: lld/trunk/test/elf/Hexagon/initfini-option.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Hexagon/initfini-option.test?rev=189872&view=auto
==============================================================================
--- lld/trunk/test/elf/Hexagon/initfini-option.test (added)
+++ lld/trunk/test/elf/Hexagon/initfini-option.test Tue Sep  3 17:44:42 2013
@@ -0,0 +1,21 @@
+# This tests the functionality that lld is able to create
+# init_array/fini_array sections in the output ELF. This
+# corresponds to the the .init_array/.fini_array sections
+# in the output ELF. 
+
+RUN: lld -flavor gnu -target hexagon %p/Inputs/initfini-option.o  \
+RUN: -init init -fini fini --noinhibit-exec -emit-yaml -static -o %t
+RUN: FileCheck %s < %t
+
+CHECK:    content:         [ 00, 00, 00, 00 ]
+CHECK:    section-name:    .init_array
+CHECK:    references:      
+CHECK:      - kind:            R_HEX_32
+CHECK:        offset:          0
+CHECK:        target:          init
+CHECK:    content:         [ 00, 00, 00, 00 ]
+CHECK:    section-name:    .fini_array
+CHECK:    references:      
+CHECK:      - kind:            R_HEX_32
+CHECK:        offset:          0
+CHECK:        target:          fini





More information about the llvm-commits mailing list