[LLVMbugs] [Bug 6426] New: Structure layout is not correct in big endian.
bugzilla-daemon at llvm.org
bugzilla-daemon at llvm.org
Thu Feb 25 19:11:50 PST 2010
http://llvm.org/bugs/show_bug.cgi?id=6426
Summary: Structure layout is not correct in big endian.
Product: libraries
Version: trunk
Platform: PC
OS/Version: Linux
Status: NEW
Severity: critical
Priority: P5
Component: Target Description Classes
AssignedTo: unassignedbugs at nondot.org
ReportedBy: dodohack at gmail.com
CC: llvmbugs at cs.uiuc.edu
This bug can be reproduced when you compile 2003-05-07-VarArgs.c for big endian
target.
There is a structure "DWordS dw = { 18, 'a' };" that past as va_arg to function
test, LowerFormalArgument can currectly deal with "dw" and store it in register
or on stack, but llvm IR that expanded from macro va_arg failed to access char
'a' in big endian, because 'a' stored at least significant byte, but generated
IR assume 'a' stored at most significant byte.
I have read the code about struct layout, and tried to fix this bug like this:
original code: TargetData.cpp
=================================================================
StructLayout::StructLayout(const StructType *ST, const TargetData &TD) {
StructAlignment = 0;
StructSize = 0;
NumElements = ST->getNumElements();
// Loop over each of the elements, placing them in memory.
for (unsigned i = 0, e = NumElements; i != e; ++i) {
const Type *Ty = ST->getElementType(i);
unsigned TyAlign = ST->isPacked() ? 1 : TD.getABITypeAlignment(Ty);
// Add padding if necessary to align the data element properly.
if ((StructSize & (TyAlign-1)) != 0)
StructSize = TargetData::RoundUpAlignment(StructSize, TyAlign);
// Keep track of maximum alignment constraint.
StructAlignment = std::max(TyAlign, StructAlignment);
MemberOffsets[i] = StructSize;
......
=================================================================
updated code: TargetData.cpp
=================================================================
StructLayout::StructLayout(const StructType *ST, const TargetData &TD) {
StructAlignment = 0;
StructSize = 0;
NumElements = ST->getNumElements();
bool isBigEndian = TD.isBigEndian();
// Loop over each of the elements, placing them in memory.
for (unsigned i = 0, e = NumElements; i != e; ++i) {
const Type *Ty = ST->getElementType(i);
unsigned TyAlign = ST->isPacked() ? 1 : TD.getABITypeAlignment(Ty);
// Add padding if necessary to align the data element properly.
if ((StructSize & (TyAlign-1)) != 0)
StructSize = TargetData::RoundUpAlignment(StructSize, TyAlign);
// Keep track of maximum alignment constraint.
StructAlignment = std::max(TyAlign, StructAlignment);
if (isBigEndian && !Ty->isAggregateType() &&
Ty->getScalarSizeInBits() < 32 && Ty->getScalarSizeInBits() > 0) {
MemberOffsets[i] = StructSize + 4 - Ty->getScalarSizeInBits()/8;
} else {
MemberOffsets[i] = StructSize;
}
......
Add, other places that related to structure padding should be fixed, say
function EmitGlobalConstantStruct in AsmPrinter.cpp.
--
Configure bugmail: http://llvm.org/bugs/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are on the CC list for the bug.
More information about the llvm-bugs
mailing list