[llvm-dev] [cfe-dev] How to debug if LTO generate wrong code?
Davide Italiano via llvm-dev
llvm-dev at lists.llvm.org
Sun May 29 14:17:54 PDT 2016
On Sun, May 29, 2016 at 1:27 PM, Mehdi Amini via llvm-dev
<llvm-dev at lists.llvm.org> wrote:
> Hi,
>
>
> On May 29, 2016, at 7:36 AM, Shi, Steven <steven.shi at intel.com> wrote:
>
> Hi Mehdi,
> After deeper debug, I found my firmware LTO wrong code issue is related to
> X64 code model (-mcmodel=large) is always overridden as small
> (-mcmodel=small) if LTO build. And I don't know how to correctly specific
> the large code model for my X64 firmware LTO build. Appreciate if you could
> let me know it.
>
> You know, parts of my Uefi firmware (BIOS) have to been loaded to run in
> high address (larger than 2 GB) at the very beginning, and I need the code
> makes absolutely no assumptions about the addresses and data sections. But
> current LLVM LTO seems stick to use the small code model and generate many
> code with 32-bit RIP-relative addressing, which cause CPU exceptions when
> run in address larger than 2GB.
>
> Below, I just simply reuse the Eli's codemodel1.c example (link:
> http://eli.thegreenplace.net/2012/01/03/understanding-the-x64-code-models)
> to show the LLVM LTO code model issue.
> $ clang -g -O0 codemodel1.c -mcmodel=large -o codemodel1_large.bin
> $ clang -g -O0 codemodel1.c -mcmodel=small -o codemodel1_small.bin
> $ clang -g -O0 -flto codemodel1.c -mcmodel=large -o codemodel1_large_lto.bin
> $ clang -g -O0 -flto codemodel1.c -mcmodel=small -o codemodel1_small_lto.bin
>
> You will see the codemodel1_large_lto.bin and codemodel1_small_lto.bin are
> exactly the same!
> And if you disassemble the codemodel1_large_lto.bin, you will see it uses
> the small code model (32-bit RIP-relative), not large, to do addressing as
> below.
>
> $ objdump -dS codemodel1_large_lto.bin
>
> int main(int argc, const char* argv[])
> {
> 4004f0: 55 push %rbp
> 4004f1: 48 89 e5 mov %rsp,%rbp
> 4004f4: 48 83 ec 20 sub $0x20,%rsp
> 4004f8: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%rbp)
> 4004ff: 89 7d f8 mov %edi,-0x8(%rbp)
> 400502: 48 89 75 f0 mov %rsi,-0x10(%rbp)
> int t = global_func(argc);
> 400506: 8b 7d f8 mov -0x8(%rbp),%edi
> 400509: e8 d2 ff ff ff callq 4004e0 <global_func>
> 40050e: 89 45 ec mov %eax,-0x14(%rbp)
> t += global_arr[7];
> 400511: 8b 04 25 4c 10 60 00 mov 0x60104c,%eax
> 400518: 03 45 ec add -0x14(%rbp),%eax
> 40051b: 89 45 ec mov %eax,-0x14(%rbp)
> t += static_arr[7];
> 40051e: 8b 04 25 dc 11 60 00 mov 0x6011dc,%eax
> 400525: 03 45 ec add -0x14(%rbp),%eax
> 400528: 89 45 ec mov %eax,-0x14(%rbp)
> t += global_arr_big[7];
> 40052b: 8b 04 25 6c 13 60 00 mov 0x60136c,%eax
> 400532: 03 45 ec add -0x14(%rbp),%eax
> 400535: 89 45 ec mov %eax,-0x14(%rbp)
> t += static_arr_big[7];
> 400538: 8b 04 25 ac 20 63 00 mov 0x6320ac,%eax
> 40053f: 03 45 ec add -0x14(%rbp),%eax
> 400542: 89 45 ec mov %eax,-0x14(%rbp)
> return t;
> 400545: 8b 45 ec mov -0x14(%rbp),%eax
> 400548: 48 83 c4 20 add $0x20,%rsp
> 40054c: 5d pop %rbp
> 40054d: c3 retq
> 40054e: 66 90 xchg %ax,%ax
>
>
> So, does LTO support large code model? How to correctly specify the LTO code
> model option?
>
>
> Same answer as before: LTO is setup by the linker, so the option for that,
> if it exists, will be linker specific.
>
> As far as I can tell, neither libLTO-based linker (ld64 on OS X for
> example), neither the gold plugin supports such an option and the code model
> is always "default".
>
> I don't know about lld, CC Rafael about that.
>
Neither lld does (yet), to the best of my knowledge.
Cheers,
--
Davide
More information about the llvm-dev
mailing list