[lld] r322035 - Move scanReloc to an auxiliary function.

Rafael Espindola via llvm-commits llvm-commits at lists.llvm.org
Mon Jan 8 14:20:44 PST 2018


Author: rafael
Date: Mon Jan  8 14:20:44 2018
New Revision: 322035

URL: http://llvm.org/viewvc/llvm-project?rev=322035&view=rev
Log:
Move scanReloc to an auxiliary function.

The body of the in scanRelocs is fairly big. This moves it to its own
function.

It is not a big readability win by itself, but should help further
refactoring.

Modified:
    lld/trunk/ELF/Relocations.cpp

Modified: lld/trunk/ELF/Relocations.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Relocations.cpp?rev=322035&r1=322034&r2=322035&view=diff
==============================================================================
--- lld/trunk/ELF/Relocations.cpp (original)
+++ lld/trunk/ELF/Relocations.cpp Mon Jan  8 14:20:44 2018
@@ -740,12 +740,12 @@ static bool maybeReportUndefined(Symbol
 // this for the N32 ABI. Iterate over relocation with the same offset and put
 // theirs types into the single bit-set.
 template <class RelTy> static RelType getMipsN32RelType(RelTy *&Rel, RelTy *End) {
-  RelType Type = Rel->getType(Config->IsMips64EL);
+  RelType Type = 0;
   uint64_t Offset = Rel->r_offset;
 
   int N = 0;
-  while (Rel + 1 != End && (Rel + 1)->r_offset == Offset)
-    Type |= (++Rel)->getType(Config->IsMips64EL) << (8 * ++N);
+  while (Rel != End && Rel->r_offset == Offset)
+    Type |= (Rel++)->getType(Config->IsMips64EL) << (8 * N++);
   return Type;
 }
 
@@ -850,169 +850,178 @@ template <class ELFT> static void addGot
 // complicates things for the dynamic linker and means we would have to reserve
 // space for the extra PT_LOAD even if we end up not using it.
 template <class ELFT, class RelTy>
-static void scanRelocs(InputSectionBase &Sec, ArrayRef<RelTy> Rels) {
-  OffsetGetter GetOffset(Sec);
+static void scanReloc(InputSectionBase &Sec, OffsetGetter &GetOffset, RelTy *&I,
+                      RelTy *End) {
+  const RelTy &Rel = *I;
+  Symbol &Sym = Sec.getFile<ELFT>()->getRelocTargetSym(Rel);
+  RelType Type;
 
-  // Not all relocations end up in Sec.Relocations, but a lot do.
-  Sec.Relocations.reserve(Rels.size());
+  // Deal with MIPS oddity.
+  if (Config->MipsN32Abi) {
+    Type = getMipsN32RelType(I, End);
+  } else {
+    Type = Rel.getType(Config->IsMips64EL);
+    ++I;
+  }
 
-  for (auto I = Rels.begin(), End = Rels.end(); I != End; ++I) {
-    const RelTy &Rel = *I;
-    Symbol &Sym = Sec.getFile<ELFT>()->getRelocTargetSym(Rel);
-    RelType Type = Rel.getType(Config->IsMips64EL);
-
-    // Deal with MIPS oddity.
-    if (Config->MipsN32Abi)
-      Type = getMipsN32RelType(I, End);
-
-    // Get an offset in an output section this relocation is applied to.
-    uint64_t Offset = GetOffset.get(Rel.r_offset);
-    if (Offset == uint64_t(-1))
-      continue;
-
-    // Skip if the target symbol is an erroneous undefined symbol.
-    if (maybeReportUndefined(Sym, Sec, Rel.r_offset))
-      continue;
-
-    const uint8_t *RelocatedAddr = Sec.Data.begin() + Rel.r_offset;
-    RelExpr Expr = Target->getRelExpr(Type, Sym, RelocatedAddr);
-
-    // Ignore "hint" relocations because they are only markers for relaxation.
-    if (isRelExprOneOf<R_HINT, R_NONE>(Expr))
-      continue;
-
-    // In case of MIPS GP-relative relocations always resolve to a definition
-    // in a regular input file, ignoring the one-definition rule. So we,
-    // for example, should not attempt to create a dynamic relocation even
-    // if the target symbol is preemptible. There are two two MIPS GP-relative
-    // relocations R_MIPS_GPREL16 and R_MIPS_GPREL32. But only R_MIPS_GPREL16
-    // can be against a preemptible symbol.
-    if (Expr == R_MIPS_GOTREL) {
-      int64_t Addend = computeAddend<ELFT>(Rel, End, Sec, Expr, Sym.isLocal());
-      Sec.Relocations.push_back({R_MIPS_GOTREL, Type, Offset, Addend, &Sym});
-      continue;
-    }
+  // Get an offset in an output section this relocation is applied to.
+  uint64_t Offset = GetOffset.get(Rel.r_offset);
+  if (Offset == uint64_t(-1))
+    return;
+
+  // Skip if the target symbol is an erroneous undefined symbol.
+  if (maybeReportUndefined(Sym, Sec, Rel.r_offset))
+    return;
 
-    bool Preemptible = Sym.IsPreemptible;
+  const uint8_t *RelocatedAddr = Sec.Data.begin() + Rel.r_offset;
+  RelExpr Expr = Target->getRelExpr(Type, Sym, RelocatedAddr);
 
-    // Strenghten or relax relocations.
-    //
-    // GNU ifunc symbols must be accessed via PLT because their addresses
-    // are determined by runtime.
-    //
-    // On the other hand, if we know that a PLT entry will be resolved within
-    // the same ELF module, we can skip PLT access and directly jump to the
-    // destination function. For example, if we are linking a main exectuable,
-    // all dynamic symbols that can be resolved within the executable will
-    // actually be resolved that way at runtime, because the main exectuable
-    // is always at the beginning of a search list. We can leverage that fact.
-    if (Sym.isGnuIFunc())
-      Expr = toPlt(Expr);
-    else if (!Preemptible && Expr == R_GOT_PC && !isAbsoluteValue(Sym))
-      Expr = Target->adjustRelaxExpr(Type, RelocatedAddr, Expr);
-    else if (!Preemptible)
-      Expr = fromPlt(Expr);
-
-    bool IsConstant =
-        isStaticLinkTimeConstant(Expr, Type, Sym, Sec, Rel.r_offset);
-
-    Expr = adjustExpr<ELFT>(Sym, Expr, Type, Sec, Rel.r_offset, IsConstant);
-    if (errorCount())
-      continue;
-
-    // This relocation does not require got entry, but it is relative to got and
-    // needs it to be created. Here we request for that.
-    if (isRelExprOneOf<R_GOTONLY_PC, R_GOTONLY_PC_FROM_END, R_GOTREL,
-                       R_GOTREL_FROM_END, R_PPC_TOC>(Expr))
-      InX::Got->HasGotOffRel = true;
+  // Ignore "hint" relocations because they are only markers for relaxation.
+  if (isRelExprOneOf<R_HINT, R_NONE>(Expr))
+    return;
 
-    // Read an addend.
+  // In case of MIPS GP-relative relocations always resolve to a definition
+  // in a regular input file, ignoring the one-definition rule. So we,
+  // for example, should not attempt to create a dynamic relocation even
+  // if the target symbol is preemptible. There are two two MIPS GP-relative
+  // relocations R_MIPS_GPREL16 and R_MIPS_GPREL32. But only R_MIPS_GPREL16
+  // can be against a preemptible symbol.
+  if (Expr == R_MIPS_GOTREL) {
     int64_t Addend = computeAddend<ELFT>(Rel, End, Sec, Expr, Sym.isLocal());
+    Sec.Relocations.push_back({R_MIPS_GOTREL, Type, Offset, Addend, &Sym});
+    return;
+  }
 
-    // Process some TLS relocations, including relaxing TLS relocations.
-    // Note that this function does not handle all TLS relocations.
-    if (unsigned Processed =
-            handleTlsRelocation<ELFT>(Type, Sym, Sec, Offset, Addend, Expr)) {
-      I += (Processed - 1);
-      continue;
-    }
+  bool Preemptible = Sym.IsPreemptible;
 
-    // If a relocation needs PLT, we create PLT and GOTPLT slots for the symbol.
-    if (needsPlt(Expr) && !Sym.isInPlt()) {
-      if (Sym.isGnuIFunc() && !Preemptible)
-        addPltEntry<ELFT>(InX::Iplt, InX::IgotPlt, InX::RelaIplt,
-                          Target->IRelativeRel, Sym, true);
-      else
-        addPltEntry<ELFT>(InX::Plt, InX::GotPlt, InX::RelaPlt, Target->PltRel,
-                          Sym, !Preemptible);
-    }
+  // Strenghten or relax relocations.
+  //
+  // GNU ifunc symbols must be accessed via PLT because their addresses
+  // are determined by runtime.
+  //
+  // On the other hand, if we know that a PLT entry will be resolved within
+  // the same ELF module, we can skip PLT access and directly jump to the
+  // destination function. For example, if we are linking a main exectuable,
+  // all dynamic symbols that can be resolved within the executable will
+  // actually be resolved that way at runtime, because the main exectuable
+  // is always at the beginning of a search list. We can leverage that fact.
+  if (Sym.isGnuIFunc())
+    Expr = toPlt(Expr);
+  else if (!Preemptible && Expr == R_GOT_PC && !isAbsoluteValue(Sym))
+    Expr = Target->adjustRelaxExpr(Type, RelocatedAddr, Expr);
+  else if (!Preemptible)
+    Expr = fromPlt(Expr);
 
-    // Create a GOT slot if a relocation needs GOT.
-    if (needsGot(Expr)) {
-      if (Config->EMachine == EM_MIPS) {
-        // MIPS ABI has special rules to process GOT entries and doesn't
-        // require relocation entries for them. A special case is TLS
-        // relocations. In that case dynamic loader applies dynamic
-        // relocations to initialize TLS GOT entries.
-        // See "Global Offset Table" in Chapter 5 in the following document
-        // for detailed description:
-        // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
-        InX::MipsGot->addEntry(Sym, Addend, Expr);
-        if (Sym.isTls() && Sym.IsPreemptible)
-          InX::RelaDyn->addReloc({Target->TlsGotRel, InX::MipsGot,
-                                  Sym.getGotOffset(), false, &Sym, 0});
-      } else if (!Sym.isInGot()) {
-        addGotEntry<ELFT>(Sym, Preemptible);
-      }
-    }
+  bool IsConstant =
+      isStaticLinkTimeConstant(Expr, Type, Sym, Sec, Rel.r_offset);
 
-    if (!needsPlt(Expr) && !needsGot(Expr) && Sym.IsPreemptible) {
-      // We don't know anything about the finaly symbol. Just ask the dynamic
-      // linker to handle the relocation for us.
-      if (!Target->isPicRel(Type))
-        errorOrWarn("relocation " + toString(Type) +
-                    " cannot be used against symbol " + toString(Sym) +
-                    "; recompile with -fPIC" + getLocation(Sec, Sym, Offset));
-
-      InX::RelaDyn->addReloc(
-          {Target->getDynRel(Type), &Sec, Offset, false, &Sym, Addend});
-
-      // MIPS ABI turns using of GOT and dynamic relocations inside out.
-      // While regular ABI uses dynamic relocations to fill up GOT entries
-      // MIPS ABI requires dynamic linker to fills up GOT entries using
-      // specially sorted dynamic symbol table. This affects even dynamic
-      // relocations against symbols which do not require GOT entries
-      // creation explicitly, i.e. do not have any GOT-relocations. So if
-      // a preemptible symbol has a dynamic relocation we anyway have
-      // to create a GOT entry for it.
-      // If a non-preemptible symbol has a dynamic relocation against it,
-      // dynamic linker takes it st_value, adds offset and writes down
-      // result of the dynamic relocation. In case of preemptible symbol
-      // dynamic linker performs symbol resolution, writes the symbol value
-      // to the GOT entry and reads the GOT entry when it needs to perform
-      // a dynamic relocation.
-      // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf p.4-19
-      if (Config->EMachine == EM_MIPS)
-        InX::MipsGot->addEntry(Sym, Addend, Expr);
-      continue;
-    }
+  Expr = adjustExpr<ELFT>(Sym, Expr, Type, Sec, Rel.r_offset, IsConstant);
+  if (errorCount())
+    return;
 
-    // If the produced value is a constant, we just remember to write it
-    // when outputting this section. We also have to do it if the format
-    // uses Elf_Rel, since in that case the written value is the addend.
-    if (IsConstant) {
-      Sec.Relocations.push_back({Expr, Type, Offset, Addend, &Sym});
-      continue;
+  // This relocation does not require got entry, but it is relative to got and
+  // needs it to be created. Here we request for that.
+  if (isRelExprOneOf<R_GOTONLY_PC, R_GOTONLY_PC_FROM_END, R_GOTREL,
+                     R_GOTREL_FROM_END, R_PPC_TOC>(Expr))
+    InX::Got->HasGotOffRel = true;
+
+  // Read an addend.
+  int64_t Addend = computeAddend<ELFT>(Rel, End, Sec, Expr, Sym.isLocal());
+
+  // Process some TLS relocations, including relaxing TLS relocations.
+  // Note that this function does not handle all TLS relocations.
+  if (unsigned Processed =
+          handleTlsRelocation<ELFT>(Type, Sym, Sec, Offset, Addend, Expr)) {
+    I += (Processed - 1);
+    return;
+  }
+
+  // If a relocation needs PLT, we create PLT and GOTPLT slots for the symbol.
+  if (needsPlt(Expr) && !Sym.isInPlt()) {
+    if (Sym.isGnuIFunc() && !Preemptible)
+      addPltEntry<ELFT>(InX::Iplt, InX::IgotPlt, InX::RelaIplt,
+                        Target->IRelativeRel, Sym, true);
+    else
+      addPltEntry<ELFT>(InX::Plt, InX::GotPlt, InX::RelaPlt, Target->PltRel,
+                        Sym, !Preemptible);
+  }
+
+  // Create a GOT slot if a relocation needs GOT.
+  if (needsGot(Expr)) {
+    if (Config->EMachine == EM_MIPS) {
+      // MIPS ABI has special rules to process GOT entries and doesn't
+      // require relocation entries for them. A special case is TLS
+      // relocations. In that case dynamic loader applies dynamic
+      // relocations to initialize TLS GOT entries.
+      // See "Global Offset Table" in Chapter 5 in the following document
+      // for detailed description:
+      // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
+      InX::MipsGot->addEntry(Sym, Addend, Expr);
+      if (Sym.isTls() && Sym.IsPreemptible)
+        InX::RelaDyn->addReloc({Target->TlsGotRel, InX::MipsGot,
+                                Sym.getGotOffset(), false, &Sym, 0});
+    } else if (!Sym.isInGot()) {
+      addGotEntry<ELFT>(Sym, Preemptible);
     }
+  }
 
-    // If the output being produced is position independent, the final value
-    // is still not known. In that case we still need some help from the
-    // dynamic linker. We can however do better than just copying the incoming
-    // relocation. We can process some of it and and just ask the dynamic
-    // linker to add the load address.
-    InX::RelaDyn->addReloc(Target->RelativeRel, &Sec, Offset, true, &Sym,
-                           Addend, Expr, Type);
+  if (!needsPlt(Expr) && !needsGot(Expr) && Sym.IsPreemptible) {
+    // We don't know anything about the finaly symbol. Just ask the dynamic
+    // linker to handle the relocation for us.
+    if (!Target->isPicRel(Type))
+      errorOrWarn("relocation " + toString(Type) +
+                  " cannot be used against symbol " + toString(Sym) +
+                  "; recompile with -fPIC" + getLocation(Sec, Sym, Offset));
+
+    InX::RelaDyn->addReloc(
+        {Target->getDynRel(Type), &Sec, Offset, false, &Sym, Addend});
+
+    // MIPS ABI turns using of GOT and dynamic relocations inside out.
+    // While regular ABI uses dynamic relocations to fill up GOT entries
+    // MIPS ABI requires dynamic linker to fills up GOT entries using
+    // specially sorted dynamic symbol table. This affects even dynamic
+    // relocations against symbols which do not require GOT entries
+    // creation explicitly, i.e. do not have any GOT-relocations. So if
+    // a preemptible symbol has a dynamic relocation we anyway have
+    // to create a GOT entry for it.
+    // If a non-preemptible symbol has a dynamic relocation against it,
+    // dynamic linker takes it st_value, adds offset and writes down
+    // result of the dynamic relocation. In case of preemptible symbol
+    // dynamic linker performs symbol resolution, writes the symbol value
+    // to the GOT entry and reads the GOT entry when it needs to perform
+    // a dynamic relocation.
+    // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf p.4-19
+    if (Config->EMachine == EM_MIPS)
+      InX::MipsGot->addEntry(Sym, Addend, Expr);
+    return;
+  }
+
+  // If the produced value is a constant, we just remember to write it
+  // when outputting this section. We also have to do it if the format
+  // uses Elf_Rel, since in that case the written value is the addend.
+  if (IsConstant) {
+    Sec.Relocations.push_back({Expr, Type, Offset, Addend, &Sym});
+    return;
   }
+
+  // If the output being produced is position independent, the final value
+  // is still not known. In that case we still need some help from the
+  // dynamic linker. We can however do better than just copying the incoming
+  // relocation. We can process some of it and and just ask the dynamic
+  // linker to add the load address.
+  InX::RelaDyn->addReloc(Target->RelativeRel, &Sec, Offset, true, &Sym, Addend,
+                         Expr, Type);
+}
+
+template <class ELFT, class RelTy>
+static void scanRelocs(InputSectionBase &Sec, ArrayRef<RelTy> Rels) {
+  OffsetGetter GetOffset(Sec);
+
+  // Not all relocations end up in Sec.Relocations, but a lot do.
+  Sec.Relocations.reserve(Rels.size());
+
+  for (auto I = Rels.begin(), End = Rels.end(); I != End;)
+    scanReloc<ELFT>(Sec, GetOffset, I, End);
 }
 
 template <class ELFT> void elf::scanRelocations(InputSectionBase &S) {




More information about the llvm-commits mailing list