[PATCH] [ELF] Handle __init_array{start, end} correctly.

Davide Italiano davide at freebsd.org
Tue Mar 10 18:50:31 PDT 2015


Hi ruiu, shankar.easwaran,

I noticed that lld handles __init_array{start, end} incorrectly.

## GNU ld
 % objdump -t ./ld | grep __init_array
00000000010cc000 l       .ctors 0000000000000000              .hidden
__init_array_end
00000000010cc000 l       .ctors 0000000000000000              .hidden
__init_array_start

### lld
% objdump -t ./bin/lld |grep __init_array
0000000000000000 g     O *ABS*  0000000000000000 __init_array_start
0000000000000000 g     O *ABS*  0000000000000000 __init_array_end

This patch is an attempt to fix.
If you agree with the approach, I'll change __fini_array and __preinit_array as well, and add tests.

REPOSITORY
  rL LLVM

http://reviews.llvm.org/D8241

Files:
  lib/ReaderWriter/ELF/Atoms.h
  lib/ReaderWriter/ELF/ELFFile.h
  lib/ReaderWriter/ELF/ExecutableWriter.h

Index: lib/ReaderWriter/ELF/Atoms.h
===================================================================
--- lib/ReaderWriter/ELF/Atoms.h
+++ lib/ReaderWriter/ELF/Atoms.h
@@ -844,6 +844,33 @@
   ArrayRef<uint8_t> rawContent() const override { return ArrayRef<uint8_t>(); }
 };
 
+class InitArrayAtom : public SimpleELFDefinedAtom {
+  StringRef _name;
+  StringRef _section;
+
+public:
+  InitArrayAtom(const File &f, StringRef symName, StringRef secName)
+      : SimpleELFDefinedAtom(f), _name(symName), _section(secName) {}
+
+  StringRef name() const override { return _name; };
+
+  Scope scope() const override { return scopeGlobal; };
+
+  SectionChoice sectionChoice() const override { return sectionCustomRequired; }
+
+  StringRef customSectionName() const override { return _section; }
+
+  ContentType contentType() const override { return typeData; }
+
+  uint64_t size() const override { return 0; }
+
+  ContentPermissions permissions() const override { return permRW_; }
+
+  Alignment alignment() const override { return Alignment(0); }
+
+  ArrayRef<uint8_t> rawContent() const override { return ArrayRef<uint8_t>(); }
+};
+
 class InitFiniAtom : public SimpleELFDefinedAtom {
   StringRef _section;
 
Index: lib/ReaderWriter/ELF/ELFFile.h
===================================================================
--- lib/ReaderWriter/ELF/ELFFile.h
+++ lib/ReaderWriter/ELF/ELFFile.h
@@ -470,10 +470,15 @@
     return *newAtom;
   }
 
-  // cannot add atoms to C Runtime file
-  virtual void addAtom(const Atom &) {
-    llvm_unreachable("cannot add atoms to Runtime files");
+  /// \brief add default atom
+  virtual void addAtom(const Atom &atom) {
+    if (auto *defAtom = dyn_cast<DefinedAtom>(&atom)) {
+      this->_definedAtoms._atoms.push_back(defAtom);
+    } else {
+      llvm_unreachable("can't add this atom");
+    }
   }
+  llvm::BumpPtrAllocator _alloc;
 };
 
 template <class ELFT>
Index: lib/ReaderWriter/ELF/ExecutableWriter.h
===================================================================
--- lib/ReaderWriter/ELF/ExecutableWriter.h
+++ lib/ReaderWriter/ELF/ExecutableWriter.h
@@ -81,14 +81,18 @@
 template<class ELFT>
 void ExecutableWriter<ELFT>::addDefaultAtoms() {
   _runtimeFile->addUndefinedAtom(this->_context.entrySymbolName());
+  _runtimeFile->addAtom(*new (_runtimeFile->_alloc)
+    InitArrayAtom(*_runtimeFile, "__init_array_start", ".init_array"));
+  _runtimeFile->addAtom(*new (_runtimeFile->_alloc)
+    InitArrayAtom(*_runtimeFile, "__init_array_end", ".init_array"));
+
+  // XXX: These aren't absolute atoms and need to be fixed.
   _runtimeFile->addAbsoluteAtom("__bss_start");
   _runtimeFile->addAbsoluteAtom("__bss_end");
   _runtimeFile->addAbsoluteAtom("_end");
   _runtimeFile->addAbsoluteAtom("end");
   _runtimeFile->addAbsoluteAtom("__preinit_array_start");
   _runtimeFile->addAbsoluteAtom("__preinit_array_end");
-  _runtimeFile->addAbsoluteAtom("__init_array_start");
-  _runtimeFile->addAbsoluteAtom("__init_array_end");
   if (this->_context.isRelaOutputFormat()) {
     _runtimeFile->addAbsoluteAtom("__rela_iplt_start");
     _runtimeFile->addAbsoluteAtom("__rela_iplt_end");
@@ -145,7 +149,6 @@
   };
 
   startEnd("preinit_array", ".preinit_array");
-  startEnd("init_array", ".init_array");
   if (this->_context.isRelaOutputFormat())
     startEnd("rela_iplt", ".rela.plt");
   else

EMAIL PREFERENCES
  http://reviews.llvm.org/settings/panel/emailpreferences/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D8241.21669.patch
Type: text/x-patch
Size: 3361 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150311/ac87daa1/attachment.bin>


More information about the llvm-commits mailing list