From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-in2.apple.com (mail-out2.apple.com [17.151.62.25]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 0F1491A1DF3 for ; Thu, 22 Sep 2016 13:27:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; d=apple.com; s=mailout2048s; c=relaxed/simple; q=dns/txt; i=@apple.com; t=1474576026; x=2338489626; h=From:Sender:Reply-To:Subject:Date:Message-id:To:Cc:MIME-version:Content-type: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-reply-to:References:List-Id: List-Help:List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=IVctERumPQeywk0hB+Q6dkn01KqLG0fgJgX5tl6Z9hE=; b=vitTCM5MHckH3PcnZyGw8TLvBkksefFxkPNgebWk1DBo/EkwkK6vPaHHsj1x2jVL wvuetdhWnkQX3ikwyRGuNinfYjgFWGT7C7dqDSpZqo1LbFcC5zfv6VaV+h+kH1Pn 4SXJKZVhq3zHY383xdEr3TNpVJI+qm9fMWChzlJHXHNWWVMzxTKKt704pU5UABAD xJPbDj3PnCabdXf6t0SH10EMABcK2SZNivjEKmCdJdHhRPXOKqo/CFAWaZBs0mZ+ nXFCHW678gCNELwW1sl8Pnpsqt6faWCER4zih4IHRr416GiyhBe3PER01SfrZe6g 93yxBXsNPjWoVt2JDiTfbw==; Received: from relay6.apple.com (relay6.apple.com [17.128.113.90]) by mail-in2.apple.com (Apple Secure Mail Relay) with SMTP id 3A.6F.10360.A9E34E75; Thu, 22 Sep 2016 13:27:06 -0700 (PDT) X-AuditID: 11973e11-f79e76d000002878-68-57e43e9a97b2 Received: from chive.apple.com (chive.apple.com [17.128.115.15]) by relay6.apple.com (Apple SCV relay) with SMTP id 78.FC.23613.A9E34E75; Thu, 22 Sep 2016 13:27:06 -0700 (PDT) MIME-version: 1.0 Received: from [17.153.85.100] by chive.apple.com (Oracle Communications Messaging Server 8.0.1.1.0 64bit (built May 17 2016)) with ESMTPSA id <0ODX009QFA54AH30@chive.apple.com>; Thu, 22 Sep 2016 13:27:05 -0700 (PDT) Sender: afish@apple.com From: Andrew Fish Message-id: <418FE198-0CCC-4A8F-8C70-69BBF4E2EF05@apple.com> Date: Thu, 22 Sep 2016 13:27:03 -0700 In-reply-to: Cc: Ard Biesheuvel , "edk2-devel@lists.01.org" To: Pete Batard References: <88690c52-2185-13cb-2f61-eabedeb59b03@akeo.ie> X-Mailer: Apple Mail (2.3226) X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrDLMWRmVeSWpSXmKPExsUi2FAYpTvL7km4waGDfBb/P+xmtNhz6Ciz xbEHaxgdmD1aps5k87hzbQ+bR/fsfywBzFFcNimpOZllqUX6dglcGW3bj7MV3PvDWHFt/QW2 BsZlNxm7GDk5JARMJPav+MoKYYtJXLi3nq2LkYtDSGAvo8TqzQuZYYpe9R5hhUhsZJR41LGF DSTBKyAo8WPyPRYQm1kgTOLjjmMsEEX3GCW2th9iB0kIC4hLvDuzCWwSm4CyxIr5H9ghmm0k LjSvYIaocZE48vUM2CAWAVWJvlv/wWxOAWuJL63nmCAWpEq0tjeCnSoiICdxdMIuRohlmxgl Jh7YDNTAAXSqrMTsX14gcQmBx2wSKz+vYpvAKDwLybGzkBwLYWtJfH/UCmRzANnyEgfPy0KE NSWe3fvEDmFrSzx5d4F1ASPbKkah3MTMHN3MPCO9xIKCnFS95PzcTYyg6JluJ7iD8fgqq0OM AhyMSjy8Dx4/DhdiTSwrrsw9xCjNwaIkzvtP5Um4kEB6YklqdmpqQWpRfFFpTmrxIUYmDk6p BsYpDLv+LCtnmCj07GBX9IqeN40ntUMlS6y8BCekHnP5wPDke5v7H+aVC996R39suFcff3yt zHumB1ffiCwse/ze/w2D6mW57Gp5kcWMyvp/k9k/qa+Yo7Nrv3bggvZbqf4rHh+K4ZwRfNd2 Zif/pTnZJRX3VxfnXp0r8vK+dsfBnn57Z+aeNbOVWIozEg21mIuKEwG1HjQdfwIAAA== X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFrrGIsWRmVeSWpSXmKPExsUi2FDMrzvL7km4wYYJnBb/P+xmtNhz6Ciz xbEHaxgdmD1aps5k87hzbQ+bR/fsfywBzFFcNimpOZllqUX6dglcGW3bj7MV3PvDWHFt/QW2 BsZlNxm7GDk5JARMJF71HmGFsMUkLtxbz9bFyMUhJLCRUeJRxxY2kASvgKDEj8n3WEBsZoEw iY87jrFAFN1jlNjafogdJCEsIC7x7swmZhCbTUBZYsX8D+wQzTYSF5pXMEPUuEgc+XoGbBCL gKpE363/YDangLXEl9ZzTBALUiVa2xvBLhIRkJM4OmEXI8SyTYwSEw9sBmrgADpVVmL2L68J jAKzkNw3C8l9ELaWxPdHrUA2B5AtL3HwvCxEWFPi2b1P7BC2tsSTdxdYFzCyrWIUKErNSaw0 00ssKMhJ1UvOz93ECA72wqgdjA3LrQ4xCnAwKvHwPnj8OFyINbGsuDL3EKMEB7OSCK+p7ZNw Id6UxMqq1KL8+KLSnNTiQ4wTGYGenMgsJZqcD4zFvJJ4QxMTAxNjYzNjY3MTc1oKK4nzruN9 EC4kkJ5YkpqdmlqQWgRzFBMHp1QDo5Eof4KgsLJ31LbiZ/55LxfprL6kX1Cta97wxr4kaNLW ijdNh3JzKk0/f73xw0zrr9YJwwJF+crUjJMZMluuxf0T0bb+Pk/piOZxbbXvx/K4jZpOHN18 cXvjqrcyj7LFeR3WvOWc7az5OXKdh4tPmsuG+VtM/vqvmDwjRuZB0pfWYHe5U67RSizFGYmG WsxFxYkAP5RbxOkCAAA= X-Content-Filtered-By: Mailman/MimeDel 2.1.21 Subject: Re: [PATCH 0/1] MdeModulePkg/EbcDxe: add ARM support X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 22 Sep 2016 20:27:07 -0000 Content-Type: text/plain; CHARSET=US-ASCII Content-Transfer-Encoding: 7BIT > On Sep 22, 2016, at 4:05 AM, Pete Batard wrote: > > On 2016.09.22 11:06, Ard Biesheuvel wrote: >> However, there is a fundamental issue with EBC on ARM that has not >> been addressed yet, which makes EBC support problematic: >> ARM uses natural alignment for 64-bit types, which means it leaves >> gaps in the stack frame, and the thunking code has no way of dealing >> with that. > > I was hoping you would comment on this, as I believe the issue is larger than Arm (which is why I thought the Arm patch could be integrated), since I ran into something similar for X64 and AARCH64, with the conversion from stack to register parameters. > > Let me start by showing a real-life example of what the current EBC implementation does, on different architectures, if you CALLEX from EBC into a native function call such as: > > VOID MultiParamNative( > UINT32, > UINT64, > UINT64, > UINT64, > UINT32, > UINT32, > UINT64 > ); > > with values: > > 0x1C1C1C1C, > 0x2B2B2B2B2A2A2A2A, > 0x3B3B3B3B3A3A3A3A, > 0x4B4B4B4B4A4A4A4A, > 0x5C5C5C5C, > 0x6C6C6C6C, > 0x7B7B7B7B7A7A7A7A > > If you do that, then the parameter values seen by each Arch will be as follows: > > IA32: > p1 = 0x1C1C1C1C > p2 = 0x2B2B2B2B2A2A2A2A > p3 = 0x3B3B3B3B3A3A3A3A > p4 = 0x4B4B4B4B4A4A4A4A > p5 = 0x5C5C5C5C > p6 = 0x6C6C6C6C > p7 = 0x7B7B7B7B7A7A7A7A > > X64: > p1 = 0x1C1C1C1C > p2 = 0x3A3A3A3A2B2B2B2B > p3 = 0x4A4A4A4A3B3B3B3B > p4 = 0x5C5C5C5C4B4B4B4B > p5 = 0x6C6C6C6C > p6 = 0x7B7B7B7B > p7 = 0x06F23E4012345678 > > ARM: > p1 = 0x1C1C1C1C > p2 = 0x3A3A3A3A2B2B2B2B > p3 = 0x4A4A4A4A3B3B3B3B > p4 = 0x5C5C5C5C4B4B4B4B > p5 = 0x6C6C6C6C > p6 = 0x7A7A7A7A > p7 = 0x446EEC467B7B7B7B > > AA64: > p1 = 0x1C1C1C1C > p2 = 0x3A3A3A3A2B2B2B2B > p3 = 0x4A4A4A4A3B3B3B3B > p4 = 0x5C5C5C5C4B4B4B4B > p5 = 0x6C6C6C6C > p6 = 0x7B7B7B7B > p7 = 0x00000000FFFFFF91 > > Note that these are real-life results gotten from a native set of drivers [1] + EBC sample [2], specifically designed to test the above. > > So, as you can see, only IA32 currently retrieves the parameters with their expected values. All the other platforms, and not just Arm, have an issue with parameter retrieval. > > I too performed some analysis [3], to understand the problem, the result of which can be summarized as follows: > > Let's say you have native protocol function: > > ProtocolCall(UINT32, UINT64, UINT64) > > to which you want to pass values: > > (0x1C1C1C1C, 0x2B2B2B2B2A2A2A2A, 0x3B3B3B3B3A3A3A3A) > > With the EBC VM, the parameters then get stacked as (little endian, CDECL and using 32-bit longwords to represent the stack): > > +--------+ > |1C1C1C1C| > +--------+ > |2A2A2A2A| > +--------+ > |2B2B2B2B| > +--------+ > |3A3A3A3A| > +--------+ > |3B3B3B3B| > +--------+ > +????????+ > +--------+ > > Now, if you are calling into an x86_32 arch, this is no issue, as the native call reads the parameters off the stack, and finds each one it its expected location. > > But if, say, you are calling into native Arm, then the calling convention dictates that the first four 32 bits parameters must be placed into Arm registers r0-r3, rather than on the stack, and what's more, that if there exist 64 bit parameters among the register ones, they must start with an even register (r0 or r2). > > What this means is that, with the current EBC handling, which simply maps the top of the stack onto registers for native CALLEX (as the VM cannot guess the parameter signature of the function it is calling into, and therefore will not do anything else but a blind mapping of the stack onto registers), the native Arm function effectively gets called with the following parameter mapping: > > +--------+ > |1C1C1C1C| -> r0 (32-bit first parameter) > +--------+ > |2A2A2A2A| -> (r1/unused, since first parameter is 32-bit) > +--------+ > |2B2B2B2B| -> r2 (lower half of 64-bit second parameter) > +--------+ > |3A3A3A3A| -> r3 (upper half of 64-bit second parameter) > +--------+ > |3B3B3B3B| -> lower half of 64-bit third parameter (stack) > +--------+ > +????????+ -> upper half of 64-bit third parameter (stack) > +--------+ > > The end result is that, the Arm call ends up with these values: > > (0x1C1C1C1C, 0x3A3A3A3A2B2B2B2B, 0x????????3B3B3B3B) > > However, while we used Arm for this example, this is not an Arm specific issue, as x86_64 and Arm64 also expect any of the first eight parameters to a native call, that are smaller than 64-bit, to get passed as a 64-bit register, which means they too have the same issue as the one illustrated above. > > Now, I'm not sure what the solution to that issue would be. I tend to agree that, short of including a parameter signature for function calls, this function argument marshalling issue between EBC and native will be difficult to solve. A possible half-workaround I thought of could be to keep track of all the PUSHes having been carried out before a CALLEX, and *assume* (or mandate in the specs) that all the arguments were pushed individually and that the size of the PUSH matches the desired size for a register argument, but even that would still add a lot of complexity and be prone to breakage... > It seems like tracking the PUSHes would work? We could update the spec to require this behavior. But it brings up another issue in that you don't know how many PUSHes to go back? What is a calling convention PUSH vs. a state save push? Maybe we could also add a max number of args that are supported? Thanks, Andrew Fish PS I'm guessing that from a clang/LLVM point of view enforcing the push rules in the code gen should not be hard if the bit code gets optimized and then is converted to EBC. As the bit code for the external code call will contain all the info EBC needs to know about. For example: %7 = call i32 @MultiParamNative(i32 %4, i64 %5, i32 %6) Example: ~/work/Compiler/llvm>cat callit.c typedef unsigned int UINT32; typedef unsigned long long UINT64; int MultiParamNative(UINT32, UINT64, UINT32); int Example (UINT32 A, UINT64 B, UINT32 C) { return MultiParamNative (A, B, C); } ~/work/Compiler/llvm>clang -S -emit-llvm callit.c ~/work/Compiler/llvm>cat callit.ll ; ModuleID = 'callit.c' target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-apple-macosx10.12.0" ; Function Attrs: nounwind ssp uwtable define i32 @Example(i32 %A, i64 %B, i32 %C) #0 { %1 = alloca i32, align 4 %2 = alloca i64, align 8 %3 = alloca i32, align 4 store i32 %A, i32* %1, align 4 store i64 %B, i64* %2, align 8 store i32 %C, i32* %3, align 4 %4 = load i32* %1, align 4 %5 = load i64* %2, align 8 %6 = load i32* %3, align 4 %7 = call i32 @MultiParamNative(i32 %4, i64 %5, i32 %6) ret i32 %7 } declare i32 @MultiParamNative(i32, i64, i32) #1 attributes #0 = { nounwind ssp uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } attributes #1 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } !llvm.ident = !{!0} !0 = metadata !{metadata !"Apple LLVM version 6.1.0 (clang-602.0.53) (based on LLVM 3.6.0svn)"} > The other solution of course is to ask EBC code developers to be aware of and compensate for the calling convention issue, and pad the stack as required depending on the ISA they are calling into, which is how I made my protocol.asm sample work [4], but this is still rather inconvenient, especially if not coding in EBC assembly, and defeats the point of trying to write Arch independent code. > > Considering this, I'm not entirely convinced ARM EBC integration should be held back, as the problem we are faced with is part of a larger issue that we'll need to resolve for all archs (except IA32), and not just ARM... > > Regards, > > /Pete > > [1] https://github.com/pbatard/fasmg-ebc/tree/master/Protocol > [2] https://github.com/pbatard/fasmg-ebc/blob/master/protocol.asm > [3] https://github.com/pbatard/fasmg-ebc/blob/master/protocol.asm#L113-L177 > [4] https://github.com/pbatard/fasmg-ebc/blob/master/protocol.asm#L211-L219 > > _______________________________________________ > edk2-devel mailing list > edk2-devel@lists.01.org > https://lists.01.org/mailman/listinfo/edk2-devel