Revert part of my r81424 patch. I removed what looked like superfluous padding
authorBill Wendling <isanbard@gmail.com>
Thu, 10 Sep 2009 06:27:16 +0000 (06:27 +0000)
committerBill Wendling <isanbard@gmail.com>
Thu, 10 Sep 2009 06:27:16 +0000 (06:27 +0000)
from the exception tables. However, Duncan explained why it's a can of worms to
do it the GCC way. I went back to doing it the LLVM way and added Duncan's
explanation so that I don't do this again in the future.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@81434 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/AsmPrinter/DwarfException.cpp

index 45d8676b4d2f2cb6e092bdc0414b5b30f233f6da..893340e932b84c8e986655e6761696e5d651ecf7 100644 (file)
@@ -619,9 +619,11 @@ void DwarfException::EmitExceptionTable() {
   // Type infos.
   const MCSection *LSDASection = Asm->getObjFileLowering().getLSDASection();
   unsigned TTypeFormat;
+  unsigned TypeFormatSize;
 
   if (!HaveTTData) {
     TTypeFormat = dwarf::DW_EH_PE_omit;
+    TypeFormatSize = SizeOfEncodedValue(dwarf::DW_EH_PE_absptr);
   } else {
     // Okay, we have actual filters or typeinfos to emit.  As such, we need to
     // pick a type encoding for them.  We're about to emit a list of pointers to
@@ -653,6 +655,8 @@ void DwarfException::EmitExceptionTable() {
     else
       TTypeFormat = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
         dwarf::DW_EH_PE_sdata4;
+
+    TypeFormatSize = SizeOfEncodedValue(TTypeFormat);
   }
 
   // Begin the exception table.
@@ -660,6 +664,38 @@ void DwarfException::EmitExceptionTable() {
   Asm->EmitAlignment(2, 0, 0, false);
 
   O << "GCC_except_table" << SubprogramCount << ":\n";
+
+  // The type infos need to be aligned. GCC does this by inserting padding just
+  // before the type infos. However, this changes the size of the exception
+  // table, so you need to take this into account when you output the exception
+  // table size. However, the size is output using a variable length encoding.
+  // So by increasing the size by inserting padding, you may increase the number
+  // of bytes used for writing the size. If it increases, say by one byte, then
+  // you now need to output one less byte of padding to get the type infos
+  // aligned.  However this decreases the size of the exception table. This
+  // changes the value you have to output for the exception table size. Due to
+  // the variable length encoding, the number of bytes used for writing the
+  // length may decrease. If so, you then have to increase the amount of
+  // padding. And so on. If you look carefully at the GCC code you will see that
+  // it indeed does this in a loop, going on and on until the values stabilize.
+  // We chose another solution: don't output padding inside the table like GCC
+  // does, instead output it before the table.
+  unsigned SizeTypes = TypeInfos.size() * TypeFormatSize;
+  unsigned TyOffset = sizeof(int8_t) +          // Call site format
+    MCAsmInfo::getULEB128Size(SizeSites) +      // Call-site table length
+    SizeSites + SizeActions + SizeTypes;
+  unsigned TotalSize = sizeof(int8_t) +         // LPStart format
+                       sizeof(int8_t) +         // TType format
+    (HaveTTData ?
+     MCAsmInfo::getULEB128Size(TyOffset) : 0) + // TType base offset
+    TyOffset;
+  unsigned SizeAlign = (4 - TotalSize) & 3;
+
+  for (unsigned i = 0; i != SizeAlign; ++i) {
+    Asm->EmitInt8(0);
+    Asm->EOL("Padding");
+  }
+
   EmitLabel("exception", SubprogramCount);
 
   if (IsSJLJ) {
@@ -679,29 +715,7 @@ void DwarfException::EmitExceptionTable() {
   Asm->EOL("@TType format", TTypeFormat);
 
   if (HaveTTData) {
-    unsigned TypeFormatSize = SizeOfEncodedValue(TTypeFormat);
-    unsigned SizeTypes = TypeInfos.size() * TypeFormatSize;
-    unsigned BeforeOffset = 2;
-    unsigned TypeOffset = sizeof(int8_t) +   // Call site format
-      MCAsmInfo::getULEB128Size(SizeSites) + // Call-site table length
-      SizeSites + SizeActions + SizeTypes;
-    unsigned Offset = TypeOffset;
-    unsigned LastOffset = 0;
-
-    while (Offset != LastOffset) {
-      LastOffset = Offset;
-      unsigned Size = MCAsmInfo::getULEB128Size(Offset);
-      unsigned Pad = BeforeOffset + Size + TypeOffset;
-
-      if (Pad % TypeFormatSize)
-        Pad = TypeFormatSize - (Pad % TypeFormatSize);
-      else
-        Pad = 0;
-
-      Offset = TypeOffset + Pad;
-    }
-
-    Asm->EmitULEB128Bytes(Offset);
+    Asm->EmitULEB128Bytes(TyOffset);
     Asm->EOL("@TType base offset");
   }