This is an archive of the discontinued LLVM Phabricator instance.

Fix alignment bug in COFF emission.
ClosedPublic

Authored by ecbeckmann on Jun 9 2017, 4:42 PM.

Details

Summary

Fix alignment issue in D34020, by aligning all sections to 8 bytes.

Diff Detail

Event Timeline

ecbeckmann created this revision.Jun 9 2017, 4:42 PM
ruiu added a subscriber: ruiu.Jun 9 2017, 5:30 PM
ruiu added inline comments.
llvm/lib/Object/WindowsResource.cpp
511 ↗(On Diff #102098)

Do you have to memorize how large was a padding? I mean you may be able to do this.

Current = alignTo(Current, 8)
ecbeckmann added inline comments.Jun 9 2017, 6:05 PM
llvm/lib/Object/WindowsResource.cpp
511 ↗(On Diff #102098)

Hmm doesn't that depend on the way the loader aligns cvtres in memory? For example, it could be possible for the system to align the FileOutputBuffer on 4 bytes instead of 8 bytes. So aligning to 8 bytes would actually be aligning to 4 bytes.

zturner added inline comments.Jun 12 2017, 1:19 PM
llvm/lib/Object/WindowsResource.cpp
511 ↗(On Diff #102098)

Not sure I follow your comment here. If the system aligns the FileOutputBuffer to 4 bytes (let's be explicit and say it puts it at address 4), and you call Current = alignTo(Current, 8) then after that call Current will be equal to 8, which is what you want, isn't it?

Seems to me like calling

X = OffsetToAlignment(Number, Align)
Number += X;

is mathematically equivalent to:

Number = alignTo(Number, Align);
ecbeckmann added inline comments.Jun 12 2017, 2:45 PM
llvm/lib/Object/WindowsResource.cpp
511 ↗(On Diff #102098)

No....this won't be what we want to do.

The end goal is to have the final COFF file be aligned on 8 bytes. Therefore, we want to align with 8 bytes relative to the FileOutputBuffer base address, without regard to the buffer starting alignment. If the address of the buffer starts at 4 and then we say
Current = alignTo(Current, 8), then yes Current will have an absolute aligned-8 address relative to llvm-cvtres memory. However, relative to the COFF file itself it will have alignment 4.

zturner edited edge metadata.Jun 12 2017, 3:30 PM

So you're aligning the offset, not the absolute address. In that it might be more intuitive to isntead of storing Current, which is actually a pointer, to store Base and Offset separately, and only operate on (and align) Offset, then compute Base+Offset every time you want to write?

Keep a running offset from base buffer address rather than moving pointer.

So you're aligning the offset, not the absolute address. In that it might be more intuitive to isntead of storing Current, which is actually a pointer, to store Base and Offset separately, and only operate on (and align) Offset, then compute Base+Offset every time you want to write?

Okay, this probably makes the most sense.

This revision was automatically updated to reflect the committed changes.

I think you might have gotten this patch combined with the other patch, because now there are a lot of unrelated changes showing up. regardless, lgtm with the new change, but please separate them out again before committing.

The last diff incorrectly grouped this patch together with the testing infrastructure patch (D34047)

ruiu added inline comments.Jun 13 2017, 1:49 PM
llvm/trunk/lib/Object/WindowsResource.cpp
35

static?

The following two constants are not ALL_IN_UPPERCAPS, but this is. Since it is not a CPP macro or something, this should be SectionAlignment.

Also, why sizeof(uint64_t) instead of just 8?

469

It is better to increment CurrentOffset in a function that writes something rather than incrementing it in a function that is called after you write it. So move this to writeCOFFHeader.

601–603
write32le(BufferStart + CurrentOffset, 0);