[PATCH] D16939: ELF: Simplify getFdeEncoding.

Rui Ueyama via llvm-commits llvm-commits at lists.llvm.org
Fri Feb 5 16:49:13 PST 2016


ruiu created this revision.
ruiu added a reviewer: grimar.
ruiu added a subscriber: llvm-commits.

I found that the handling of 'L' character in an augmentation string is
wrong because 'L' means that the next byte is the length field. I could
have fixed that by just skipping the next byte, but I decided to take
different approach.

Teaching the linker about all the types of CIE internal records just to
skip them is silly. And the code doing that is not actually executed now
(that's why the bug did not cause any issue.) It is because the 'R' field,
which we want to read, is always at beginning of the CIE. So I reduced
the code dramatically by assuming that that's always the case. I want to
see how it works in the wild. If it doesn't work, we can roll this back
(with a fix for 'L').

http://reviews.llvm.org/D16939

Files:
  ELF/OutputSections.cpp

Index: ELF/OutputSections.cpp
===================================================================
--- ELF/OutputSections.cpp
+++ ELF/OutputSections.cpp
@@ -903,22 +903,19 @@
 
 template <class ELFT>
 uint8_t EHOutputSection<ELFT>::getFdeEncoding(ArrayRef<uint8_t> D) {
-  auto Check = [](bool C) {
-    if (!C)
-      fatal("corrupted or unsupported CIE information");
-  };
-
-  Check(D.size() >= 8);
+  if (D.size() < 8)
+    fatal("CIE too small");
   D = D.slice(8);
 
   uint8_t Version = readByte(D);
   if (Version != 1 && Version != 3)
     fatal("FDE version 1 or 3 expected, but got " + Twine((unsigned)Version));
 
   auto AugEnd = std::find(D.begin() + 1, D.end(), '\0');
-  Check(AugEnd != D.end());
-  ArrayRef<uint8_t> AugString(D.begin(), AugEnd - D.begin());
-  D = D.slice(AugString.size() + 1);
+  if (AugEnd == D.end())
+    fatal("corrupted CIE");
+  StringRef Aug((char *)D.begin(), AugEnd - D.begin());
+  D = D.slice(Aug.size() + 1);
 
   // Code alignment factor should always be 1 for .eh_frame.
   if (readByte(D) != 1)
@@ -933,34 +930,13 @@
   else
     skipLeb128(D);
 
-  while (!AugString.empty()) {
-    switch (readByte(AugString)) {
-    case 'z':
-      skipLeb128(D);
-      break;
-    case 'R':
-      return readByte(D);
-    case 'P': {
-      uint8_t Enc = readByte(D);
-      if ((Enc & 0xf0) == dwarf::DW_EH_PE_aligned)
-        fatal("DW_EH_PE_aligned encoding for address of a personality routine "
-              "handler not supported");
-      unsigned EncSize = getSizeForEncoding<ELFT>(Enc);
-      Check(D.size() >= EncSize);
-      D = D.slice(EncSize);
-      break;
-    }
-    case 'S':
-    case 'L':
-      // L: Language Specific Data Area (LSDA) encoding
-      // S: This CIE represents a stack frame for the invocation of a signal
-      //    handler
-      break;
-    default:
-      fatal("unknown .eh_frame augmentation string value");
-    }
-  }
-  return dwarf::DW_EH_PE_absptr;
+  // We assume that the augmentation string always starts with 'z'
+  // (which specifies the size of the CIE field) and 'R' (which
+  // specifies the FDE encoding.)
+  if (!Aug.startswith("zR"))
+    fatal("unknown .eh_frame augmentation string: " + Aug);
+  skipLeb128(D);
+  return readByte(D);
 }
 
 template <class ELFT>


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D16939.47066.patch
Type: text/x-patch
Size: 2276 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160206/851e3a3c/attachment.bin>


More information about the llvm-commits mailing list