[lld] r286799 - [ELF] Convert StringTableSection to input section

Eugene Leviant via llvm-commits llvm-commits at lists.llvm.org
Mon Nov 14 01:16:01 PST 2016


Author: evgeny777
Date: Mon Nov 14 03:16:00 2016
New Revision: 286799

URL: http://llvm.org/viewvc/llvm-project?rev=286799&view=rev
Log:
[ELF] Convert StringTableSection to input section

Differential revision: https://reviews.llvm.org/D26549

Modified:
    lld/trunk/ELF/OutputSections.cpp
    lld/trunk/ELF/OutputSections.h
    lld/trunk/ELF/SyntheticSections.cpp
    lld/trunk/ELF/SyntheticSections.h
    lld/trunk/ELF/Writer.cpp

Modified: lld/trunk/ELF/OutputSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=286799&r1=286798&r2=286799&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.cpp (original)
+++ lld/trunk/ELF/OutputSections.cpp Mon Nov 14 03:16:00 2016
@@ -415,15 +415,15 @@ template <class ELFT> void DynamicSectio
   // Add strings to .dynstr early so that .dynstr's size will be
   // fixed early.
   for (StringRef S : Config->AuxiliaryList)
-    Add({DT_AUXILIARY, Out<ELFT>::DynStrTab->addString(S)});
+    Add({DT_AUXILIARY, In<ELFT>::DynStrTab->addString(S)});
   if (!Config->RPath.empty())
     Add({Config->EnableNewDtags ? DT_RUNPATH : DT_RPATH,
-         Out<ELFT>::DynStrTab->addString(Config->RPath)});
+         In<ELFT>::DynStrTab->addString(Config->RPath)});
   for (SharedFile<ELFT> *F : Symtab<ELFT>::X->getSharedFiles())
     if (F->isNeeded())
-      Add({DT_NEEDED, Out<ELFT>::DynStrTab->addString(F->getSoName())});
+      Add({DT_NEEDED, In<ELFT>::DynStrTab->addString(F->getSoName())});
   if (!Config->SoName.empty())
-    Add({DT_SONAME, Out<ELFT>::DynStrTab->addString(Config->SoName)});
+    Add({DT_SONAME, In<ELFT>::DynStrTab->addString(Config->SoName)});
 
   // Set DT_FLAGS and DT_FLAGS_1.
   uint32_t DtFlags = 0;
@@ -455,7 +455,7 @@ template <class ELFT> void DynamicSectio
   if (this->Size)
     return; // Already finalized.
 
-  this->Link = Out<ELFT>::DynStrTab->SectionIndex;
+  this->Link = In<ELFT>::DynStrTab->OutSec->SectionIndex;
 
   if (Out<ELFT>::RelaDyn->hasRelocs()) {
     bool IsRela = Config->Rela;
@@ -483,8 +483,8 @@ template <class ELFT> void DynamicSectio
 
   Add({DT_SYMTAB, Out<ELFT>::DynSymTab});
   Add({DT_SYMENT, sizeof(Elf_Sym)});
-  Add({DT_STRTAB, Out<ELFT>::DynStrTab});
-  Add({DT_STRSZ, Out<ELFT>::DynStrTab->Size});
+  Add({DT_STRTAB, In<ELFT>::DynStrTab});
+  Add({DT_STRSZ, In<ELFT>::DynStrTab->getSize()});
   if (Out<ELFT>::GnuHashTab)
     Add({DT_GNU_HASH, Out<ELFT>::GnuHashTab});
   if (Out<ELFT>::HashTab)
@@ -650,6 +650,15 @@ template <class ELFT> void OutputSection
         this->Link = D->OutSec->SectionIndex;
     }
   }
+
+  // Recalculate input section offsets if we own any synthetic section
+  for (auto *SS : In<ELFT>::SyntheticSections)
+    if (SS && this == SS->OutSec) {
+      this->Size = 0;
+      assignOffsets();
+      break;
+    }
+
   if (Type != SHT_RELA && Type != SHT_REL)
     return;
   this->Link = Out<ELFT>::SymTab->SectionIndex;
@@ -1052,40 +1061,6 @@ template <class ELFT> void MergeOutputSe
 }
 
 template <class ELFT>
-StringTableSection<ELFT>::StringTableSection(StringRef Name, bool Dynamic)
-    : OutputSectionBase(Name, SHT_STRTAB, Dynamic ? (uintX_t)SHF_ALLOC : 0),
-      Dynamic(Dynamic) {
-  // ELF string tables start with a NUL byte, so 1.
-  this->Size = 1;
-}
-
-// Adds a string to the string table. If HashIt is true we hash and check for
-// duplicates. It is optional because the name of global symbols are already
-// uniqued and hashing them again has a big cost for a small value: uniquing
-// them with some other string that happens to be the same.
-template <class ELFT>
-unsigned StringTableSection<ELFT>::addString(StringRef S, bool HashIt) {
-  if (HashIt) {
-    auto R = StringMap.insert(std::make_pair(S, this->Size));
-    if (!R.second)
-      return R.first->second;
-  }
-  unsigned Ret = this->Size;
-  this->Size = this->Size + S.size() + 1;
-  Strings.push_back(S);
-  return Ret;
-}
-
-template <class ELFT> void StringTableSection<ELFT>::writeTo(uint8_t *Buf) {
-  // ELF string tables start with NUL byte, so advance the pointer by one.
-  ++Buf;
-  for (StringRef S : Strings) {
-    memcpy(Buf, S.data(), S.size());
-    Buf += S.size() + 1;
-  }
-}
-
-template <class ELFT>
 typename ELFT::uint DynamicReloc<ELFT>::getOffset() const {
   if (OutputSec)
     return OutputSec->Addr + OffsetInSec;
@@ -1148,7 +1123,7 @@ template <class ELFT> void SymbolTableSe
     return; // Already finalized.
 
   this->Size = getNumSymbols() * sizeof(Elf_Sym);
-  this->Link = StrTabSec.SectionIndex;
+  this->Link = StrTabSec.OutSec->SectionIndex;
   this->Info = NumLocals + 1;
 
   if (Config->Relocatable) {
@@ -1300,12 +1275,12 @@ static StringRef getFileDefName() {
 }
 
 template <class ELFT> void VersionDefinitionSection<ELFT>::finalize() {
-  FileDefNameOff = Out<ELFT>::DynStrTab->addString(getFileDefName());
+  FileDefNameOff = In<ELFT>::DynStrTab->addString(getFileDefName());
   for (VersionDefinition &V : Config->VersionDefinitions)
-    V.NameOff = Out<ELFT>::DynStrTab->addString(V.Name);
+    V.NameOff = In<ELFT>::DynStrTab->addString(V.Name);
 
   this->Size = (sizeof(Elf_Verdef) + sizeof(Elf_Verdaux)) * getVerDefNum();
-  this->Link = Out<ELFT>::DynStrTab->SectionIndex;
+  this->Link = In<ELFT>::DynStrTab->OutSec->SectionIndex;
 
   // sh_info should be set to the number of definitions. This fact is missed in
   // documentation, but confirmed by binutils community:
@@ -1389,13 +1364,13 @@ void VersionNeedSection<ELFT>::addSymbol
   // to create one by adding it to our needed list and creating a dynstr entry
   // for the soname.
   if (F->VerdefMap.empty())
-    Needed.push_back({F, Out<ELFT>::DynStrTab->addString(F->getSoName())});
+    Needed.push_back({F, In<ELFT>::DynStrTab->addString(F->getSoName())});
   typename SharedFile<ELFT>::NeededVer &NV = F->VerdefMap[SS->Verdef];
   // If we don't already know that we need an Elf_Vernaux for this Elf_Verdef,
   // prepare to create one by allocating a version identifier and creating a
   // dynstr entry for the version name.
   if (NV.Index == 0) {
-    NV.StrTab = Out<ELFT>::DynStrTab->addString(
+    NV.StrTab = In<ELFT>::DynStrTab->addString(
         SS->file()->getStringTable().data() + SS->Verdef->getAux()->vda_name);
     NV.Index = NextIndex++;
   }
@@ -1438,7 +1413,7 @@ template <class ELFT> void VersionNeedSe
 }
 
 template <class ELFT> void VersionNeedSection<ELFT>::finalize() {
-  this->Link = Out<ELFT>::DynStrTab->SectionIndex;
+  this->Link = In<ELFT>::DynStrTab->OutSec->SectionIndex;
   this->Info = Needed.size();
   unsigned Size = Needed.size() * sizeof(Elf_Verneed);
   for (std::pair<SharedFile<ELFT> *, size_t> &P : Needed)
@@ -1590,11 +1565,6 @@ template class MergeOutputSection<ELF32B
 template class MergeOutputSection<ELF64LE>;
 template class MergeOutputSection<ELF64BE>;
 
-template class StringTableSection<ELF32LE>;
-template class StringTableSection<ELF32BE>;
-template class StringTableSection<ELF64LE>;
-template class StringTableSection<ELF64BE>;
-
 template class SymbolTableSection<ELF32LE>;
 template class SymbolTableSection<ELF32BE>;
 template class SymbolTableSection<ELF64LE>;

Modified: lld/trunk/ELF/OutputSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.h?rev=286799&r1=286798&r2=286799&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.h (original)
+++ lld/trunk/ELF/OutputSections.h Mon Nov 14 03:16:00 2016
@@ -54,7 +54,6 @@ public:
     Plt,
     Regular,
     Reloc,
-    StrTable,
     SymTable,
     VersDef,
     VersNeed,
@@ -424,26 +423,6 @@ private:
   llvm::DenseMap<std::pair<ArrayRef<uint8_t>, SymbolBody *>, CieRecord> CieMap;
 };
 
-template <class ELFT>
-class StringTableSection final : public OutputSectionBase {
-
-public:
-  typedef typename ELFT::uint uintX_t;
-  StringTableSection(StringRef Name, bool Dynamic);
-  unsigned addString(StringRef S, bool HashIt = true);
-  void writeTo(uint8_t *Buf) override;
-  bool isDynamic() const { return Dynamic; }
-  Kind getKind() const override { return StrTable; }
-  static bool classof(const OutputSectionBase *B) {
-    return B->getKind() == StrTable;
-  }
-
-private:
-  const bool Dynamic;
-  llvm::DenseMap<StringRef, unsigned> StringMap;
-  std::vector<StringRef> Strings;
-};
-
 template <class ELFT> class HashTableSection final : public OutputSectionBase {
   typedef typename ELFT::Word Elf_Word;
 
@@ -600,9 +579,6 @@ template <class ELFT> struct Out {
   static PltSection<ELFT> *Plt;
   static RelocationSection<ELFT> *RelaDyn;
   static RelocationSection<ELFT> *RelaPlt;
-  static StringTableSection<ELFT> *DynStrTab;
-  static StringTableSection<ELFT> *ShStrTab;
-  static StringTableSection<ELFT> *StrTab;
   static SymbolTableSection<ELFT> *DynSymTab;
   static SymbolTableSection<ELFT> *SymTab;
   static VersionDefinitionSection<ELFT> *VerDef;
@@ -664,9 +640,6 @@ template <class ELFT> uint8_t *Out<ELFT>
 template <class ELFT> PltSection<ELFT> *Out<ELFT>::Plt;
 template <class ELFT> RelocationSection<ELFT> *Out<ELFT>::RelaDyn;
 template <class ELFT> RelocationSection<ELFT> *Out<ELFT>::RelaPlt;
-template <class ELFT> StringTableSection<ELFT> *Out<ELFT>::DynStrTab;
-template <class ELFT> StringTableSection<ELFT> *Out<ELFT>::ShStrTab;
-template <class ELFT> StringTableSection<ELFT> *Out<ELFT>::StrTab;
 template <class ELFT> SymbolTableSection<ELFT> *Out<ELFT>::DynSymTab;
 template <class ELFT> SymbolTableSection<ELFT> *Out<ELFT>::SymTab;
 template <class ELFT> VersionDefinitionSection<ELFT> *Out<ELFT>::VerDef;

Modified: lld/trunk/ELF/SyntheticSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.cpp?rev=286799&r1=286798&r2=286799&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.cpp (original)
+++ lld/trunk/ELF/SyntheticSections.cpp Mon Nov 14 03:16:00 2016
@@ -642,6 +642,38 @@ template <class ELFT> void GotPltSection
   }
 }
 
+template <class ELFT>
+StringTableSection<ELFT>::StringTableSection(StringRef Name, bool Dynamic)
+    : SyntheticSection<ELFT>(Dynamic ? (uintX_t)SHF_ALLOC : 0, SHT_STRTAB, 1,
+                             Name),
+      Dynamic(Dynamic) {}
+
+// Adds a string to the string table. If HashIt is true we hash and check for
+// duplicates. It is optional because the name of global symbols are already
+// uniqued and hashing them again has a big cost for a small value: uniquing
+// them with some other string that happens to be the same.
+template <class ELFT>
+unsigned StringTableSection<ELFT>::addString(StringRef S, bool HashIt) {
+  if (HashIt) {
+    auto R = StringMap.insert(std::make_pair(S, this->Size));
+    if (!R.second)
+      return R.first->second;
+  }
+  unsigned Ret = this->Size;
+  this->Size = this->Size + S.size() + 1;
+  Strings.push_back(S);
+  return Ret;
+}
+
+template <class ELFT> void StringTableSection<ELFT>::writeTo(uint8_t *Buf) {
+  // ELF string tables start with NUL byte, so advance the pointer by one.
+  ++Buf;
+  for (StringRef S : Strings) {
+    memcpy(Buf, S.data(), S.size());
+    Buf += S.size() + 1;
+  }
+}
+
 template InputSection<ELF32LE> *elf::createCommonSection();
 template InputSection<ELF32BE> *elf::createCommonSection();
 template InputSection<ELF64LE> *elf::createCommonSection();
@@ -711,3 +743,8 @@ template class elf::GotPltSection<ELF32L
 template class elf::GotPltSection<ELF32BE>;
 template class elf::GotPltSection<ELF64LE>;
 template class elf::GotPltSection<ELF64BE>;
+
+template class elf::StringTableSection<ELF32LE>;
+template class elf::StringTableSection<ELF32BE>;
+template class elf::StringTableSection<ELF64LE>;
+template class elf::StringTableSection<ELF64BE>;

Modified: lld/trunk/ELF/SyntheticSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.h?rev=286799&r1=286798&r2=286799&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.h (original)
+++ lld/trunk/ELF/SyntheticSections.h Mon Nov 14 03:16:00 2016
@@ -218,6 +218,26 @@ private:
   std::vector<const SymbolBody *> Entries;
 };
 
+template <class ELFT>
+class StringTableSection final : public SyntheticSection<ELFT> {
+public:
+  typedef typename ELFT::uint uintX_t;
+  StringTableSection(StringRef Name, bool Dynamic);
+  unsigned addString(StringRef S, bool HashIt = true);
+  void writeTo(uint8_t *Buf) override;
+  size_t getSize() const override { return Size; }
+  bool isDynamic() const { return Dynamic; }
+
+private:
+  const bool Dynamic;
+
+  // ELF string tables start with a NUL byte, so 1.
+  uintX_t Size = 1;
+
+  llvm::DenseMap<StringRef, unsigned> StringMap;
+  std::vector<StringRef> Strings;
+};
+
 template <class ELFT> InputSection<ELFT> *createCommonSection();
 template <class ELFT> InputSection<ELFT> *createInterpSection();
 template <class ELFT> MergeInputSection<ELFT> *createCommentSection();
@@ -226,22 +246,35 @@ template <class ELFT> MergeInputSection<
 template <class ELFT> struct In {
   static BuildIdSection<ELFT> *BuildId;
   static InputSection<ELFT> *Common;
+  static StringTableSection<ELFT> *DynStrTab;
   static GotSection<ELFT> *Got;
   static GotPltSection<ELFT> *GotPlt;
   static InputSection<ELFT> *Interp;
   static MipsAbiFlagsSection<ELFT> *MipsAbiFlags;
   static MipsOptionsSection<ELFT> *MipsOptions;
   static MipsReginfoSection<ELFT> *MipsReginfo;
+  static StringTableSection<ELFT> *ShStrTab;
+  static StringTableSection<ELFT> *StrTab;
+
+  // Contains list of sections, which size is not known when
+  // createSections() is called. This list is used when output
+  // sections are being finalized to calculate their size correctly.
+  static std::vector<SyntheticSection<ELFT> *> SyntheticSections;
 };
 
 template <class ELFT> BuildIdSection<ELFT> *In<ELFT>::BuildId;
 template <class ELFT> InputSection<ELFT> *In<ELFT>::Common;
+template <class ELFT> StringTableSection<ELFT> *In<ELFT>::DynStrTab;
 template <class ELFT> GotSection<ELFT> *In<ELFT>::Got;
 template <class ELFT> GotPltSection<ELFT> *In<ELFT>::GotPlt;
 template <class ELFT> InputSection<ELFT> *In<ELFT>::Interp;
 template <class ELFT> MipsAbiFlagsSection<ELFT> *In<ELFT>::MipsAbiFlags;
 template <class ELFT> MipsOptionsSection<ELFT> *In<ELFT>::MipsOptions;
 template <class ELFT> MipsReginfoSection<ELFT> *In<ELFT>::MipsReginfo;
+template <class ELFT> StringTableSection<ELFT> *In<ELFT>::ShStrTab;
+template <class ELFT> StringTableSection<ELFT> *In<ELFT>::StrTab;
+template <class ELFT>
+std::vector<SyntheticSection<ELFT> *> In<ELFT>::SyntheticSections;
 
 } // namespace elf
 } // namespace lld

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=286799&r1=286798&r2=286799&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Mon Nov 14 03:16:00 2016
@@ -209,13 +209,13 @@ template <class ELFT> void Writer<ELFT>:
   // Create singleton output sections.
   Out<ELFT>::Bss =
       make<OutputSection<ELFT>>(".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
-  Out<ELFT>::DynStrTab = make<StringTableSection<ELFT>>(".dynstr", true);
+  In<ELFT>::DynStrTab = make<StringTableSection<ELFT>>(".dynstr", true);
   Out<ELFT>::Dynamic = make<DynamicSection<ELFT>>();
   Out<ELFT>::EhFrame = make<EhOutputSection<ELFT>>();
   Out<ELFT>::Plt = make<PltSection<ELFT>>();
   Out<ELFT>::RelaDyn = make<RelocationSection<ELFT>>(
       Config->Rela ? ".rela.dyn" : ".rel.dyn", Config->ZCombreloc);
-  Out<ELFT>::ShStrTab = make<StringTableSection<ELFT>>(".shstrtab", false);
+  In<ELFT>::ShStrTab = make<StringTableSection<ELFT>>(".shstrtab", false);
   Out<ELFT>::VerSym = make<VersionTableSection<ELFT>>();
   Out<ELFT>::VerNeed = make<VersionNeedSection<ELFT>>();
 
@@ -232,8 +232,7 @@ template <class ELFT> void Writer<ELFT>:
   }
 
   if (!Symtab<ELFT>::X->getSharedFiles().empty() || Config->Pic) {
-    Out<ELFT>::DynSymTab =
-        make<SymbolTableSection<ELFT>>(*Out<ELFT>::DynStrTab);
+    Out<ELFT>::DynSymTab = make<SymbolTableSection<ELFT>>(*In<ELFT>::DynStrTab);
   }
 
   if (Config->EhFrameHdr)
@@ -249,8 +248,8 @@ template <class ELFT> void Writer<ELFT>:
   Out<ELFT>::RelaPlt = make<RelocationSection<ELFT>>(
       Config->Rela ? ".rela.plt" : ".rel.plt", false /*Sort*/);
   if (Config->Strip != StripPolicy::All) {
-    Out<ELFT>::StrTab = make<StringTableSection<ELFT>>(".strtab", false);
-    Out<ELFT>::SymTab = make<SymbolTableSection<ELFT>>(*Out<ELFT>::StrTab);
+    In<ELFT>::StrTab = make<StringTableSection<ELFT>>(".strtab", false);
+    Out<ELFT>::SymTab = make<SymbolTableSection<ELFT>>(*In<ELFT>::StrTab);
   }
 
   if (Config->EMachine == EM_MIPS && !Config->Shared) {
@@ -315,6 +314,13 @@ template <class ELFT> void Writer<ELFT>:
 
   In<ELFT>::Got = make<GotSection<ELFT>>();
   In<ELFT>::GotPlt = make<GotPltSection<ELFT>>();
+
+  // These sections are filled after createSections() is called.
+  // We use this list to fixup size of output sections, when they
+  // are finalized.
+  In<ELFT>::SyntheticSections = {In<ELFT>::ShStrTab, In<ELFT>::StrTab,
+                                 In<ELFT>::DynStrTab, In<ELFT>::Got,
+                                 In<ELFT>::GotPlt};
 }
 
 template <class ELFT>
@@ -734,6 +740,9 @@ void Writer<ELFT>::forEachRelSec(
 
 template <class ELFT>
 void Writer<ELFT>::addInputSec(InputSectionBase<ELFT> *IS) {
+  if (!IS)
+    return;
+
   if (!IS->Live) {
     reportDiscarded(IS);
     return;
@@ -918,7 +927,7 @@ template <class ELFT> void Writer<ELFT>:
   unsigned I = 1;
   for (OutputSectionBase *Sec : OutputSections) {
     Sec->SectionIndex = I++;
-    Sec->ShName = Out<ELFT>::ShStrTab->addString(Sec->getName());
+    Sec->ShName = In<ELFT>::ShStrTab->addString(Sec->getName());
   }
 
   // Finalizers fix each section's size.
@@ -968,8 +977,8 @@ template <class ELFT> void Writer<ELFT>:
   if (Out<ELFT>::GdbIndex && Out<ELFT>::DebugInfo)
     Add(Out<ELFT>::GdbIndex);
   Add(Out<ELFT>::SymTab);
-  Add(Out<ELFT>::ShStrTab);
-  Add(Out<ELFT>::StrTab);
+  addInputSec(In<ELFT>::ShStrTab);
+  addInputSec(In<ELFT>::StrTab);
   if (Out<ELFT>::DynSymTab) {
     Add(Out<ELFT>::DynSymTab);
 
@@ -983,7 +992,7 @@ template <class ELFT> void Writer<ELFT>:
     Add(Out<ELFT>::GnuHashTab);
     Add(Out<ELFT>::HashTab);
     Add(Out<ELFT>::Dynamic);
-    Add(Out<ELFT>::DynStrTab);
+    addInputSec(In<ELFT>::DynStrTab);
     if (Out<ELFT>::RelaDyn->hasRelocs())
       Add(Out<ELFT>::RelaDyn);
     Add(Out<ELFT>::MipsRldMap);
@@ -999,13 +1008,10 @@ template <class ELFT> void Writer<ELFT>:
   if (needsGot()) {
     In<ELFT>::Got->finalize();
     addInputSec(In<ELFT>::Got);
-    In<ELFT>::Got->OutSec->assignOffsets();
   }
 
-  if (!In<ELFT>::GotPlt->empty()) {
+  if (!In<ELFT>::GotPlt->empty())
     addInputSec(In<ELFT>::GotPlt);
-    In<ELFT>::GotPlt->OutSec->assignOffsets();
-  }
 
   if (!Out<ELFT>::Plt->empty())
     Add(Out<ELFT>::Plt);
@@ -1420,7 +1426,7 @@ template <class ELFT> void Writer<ELFT>:
   EHdr->e_phnum = Phdrs.size();
   EHdr->e_shentsize = sizeof(Elf_Shdr);
   EHdr->e_shnum = OutputSections.size() + 1;
-  EHdr->e_shstrndx = Out<ELFT>::ShStrTab->SectionIndex;
+  EHdr->e_shstrndx = In<ELFT>::ShStrTab->OutSec->SectionIndex;
 
   if (Config->EMachine == EM_ARM)
     // We don't currently use any features incompatible with EF_ARM_EABI_VER5,




More information about the llvm-commits mailing list