Revert part of my r81424 patch. I removed what looked like superfluous padding

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.

llvm-svn: 81434
This commit is contained in:
Bill Wendling 2009-09-10 06:27:16 +00:00
parent d3f98b1d15
commit 988ed7ed19

View File

@ -619,9 +619,11 @@ void DwarfException::EmitExceptionTable() {
// Type infos. // Type infos.
const MCSection *LSDASection = Asm->getObjFileLowering().getLSDASection(); const MCSection *LSDASection = Asm->getObjFileLowering().getLSDASection();
unsigned TTypeFormat; unsigned TTypeFormat;
unsigned TypeFormatSize;
if (!HaveTTData) { if (!HaveTTData) {
TTypeFormat = dwarf::DW_EH_PE_omit; TTypeFormat = dwarf::DW_EH_PE_omit;
TypeFormatSize = SizeOfEncodedValue(dwarf::DW_EH_PE_absptr);
} else { } else {
// Okay, we have actual filters or typeinfos to emit. As such, we need to // 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 // pick a type encoding for them. We're about to emit a list of pointers to
@ -653,6 +655,8 @@ void DwarfException::EmitExceptionTable() {
else else
TTypeFormat = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | TTypeFormat = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
dwarf::DW_EH_PE_sdata4; dwarf::DW_EH_PE_sdata4;
TypeFormatSize = SizeOfEncodedValue(TTypeFormat);
} }
// Begin the exception table. // Begin the exception table.
@ -660,6 +664,38 @@ void DwarfException::EmitExceptionTable() {
Asm->EmitAlignment(2, 0, 0, false); Asm->EmitAlignment(2, 0, 0, false);
O << "GCC_except_table" << SubprogramCount << ":\n"; 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); EmitLabel("exception", SubprogramCount);
if (IsSJLJ) { if (IsSJLJ) {
@ -679,29 +715,7 @@ void DwarfException::EmitExceptionTable() {
Asm->EOL("@TType format", TTypeFormat); Asm->EOL("@TType format", TTypeFormat);
if (HaveTTData) { if (HaveTTData) {
unsigned TypeFormatSize = SizeOfEncodedValue(TTypeFormat); Asm->EmitULEB128Bytes(TyOffset);
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->EOL("@TType base offset"); Asm->EOL("@TType base offset");
} }