On 02/05/18 19:22, Kinney, Michael D wrote:
> Laszlo,
> 
> Let's see if we can close on the timeline for 
> the .S/.asm RFC this week.
> 
> I am concerned about making them UINT8 from C code
> because future maintainer may think that the patch 
> value type is UINT8.
> 
> Labels in assembly that are defined to be a function
> that is callable from C code does not have a storage
> type.  Why can't we make these labels the same way?

To my understanding, the labels in the NASM source code for functions
and variables look the same; the actual declaration only comes from the
C code.

(Assuming we declare a NASM label as a function in the C source, nothing
in the toolchain enforces an actual match between caller and callee; it
is possible to call the function (from C) through a declaration that
doesn't match the actual assembly implementation. IOW it's up to us to
avoid such bugs.)

If I understand correctly, you are suggesting that we take a label from
the NASM source that stands right after an instruction to patch, and we
declare it as a function in the C source. (With what prototype though?
The label does not actually introduce a function definition in the
assembly code; it would make no sense to call it.) Then, for the
patching, I presume your suggestion is to convert the address of the
function to UINTN, perform the subtraction, etc. Something like:

  typedef VOID (X86_ASSEMBLY_LABEL) (VOID);

(This is not a pointer-to-function type, but a function type.)

A declaration using the typedef would be

  extern X86_ASSEMBLY_LABEL gPatchCr3;

(This declares an extern function, not a pointer to a function.)

The patching function would take a pointer to a function:

  VOID
  EFIAPI
  PatchInstructionX86 (
    OUT X86_ASSEMBLY_LABEL *InstructionEnd,
    IN  UINT64             PatchValue,
    IN  UINTN              ValueSize
    );

and the implementation would have to do e.g.

  WriteUnaligned32 (
    (UINT32 *)(UINTN)InstructionEnd - 1,
    (UINT32)PatchValue
    );

It would be called like

  PatchInstructionX86 (&gPatchCr3, Value, 4);


But, what does this buy us in comparison to just:

  typedef UINT8 X86_ASSEMBLY_LABEL;

?

If you worry that a future maintainer misunderstands the UINT8, then we
can as well hide the UINT8 behind a typedef; X86_ASSEMBLY_LABEL doesn't
have to be a function type for the hiding. (Conversely, when using a
function type as underlying type, I worry that a future maintainer might
be tempted to call them :) )

Thanks,
Laszlo

>> -----Original Message-----
>> From: Laszlo Ersek [mailto:[email protected]]
>> Sent: Monday, February 5, 2018 2:28 AM
>> To: Kinney, Michael D <[email protected]>; edk2-
>> devel-01 <[email protected]>
>> Cc: Ard Biesheuvel <[email protected]>; Dong,
>> Eric <[email protected]>; Yao, Jiewen
>> <[email protected]>; Leif Lindholm
>> <[email protected]>; Gao, Liming
>> <[email protected]>; Ni, Ruiyu <[email protected]>
>> Subject: Re: [PATCH 00/14] rid PiSmmCpuDxeSmm of DB-
>> encoded instructions
>>
>> On 02/03/18 01:45, Kinney, Michael D wrote:
>>> Laszlo,
>>>
>>> Thanks for all the work on this series and the very
>>> detailed commit messages.
>>>
>>> Liming's email on removing the .S and .asm files is an
>>> RFC.  We need to see this RFC approved before we can
>>> commit changes to remove .S and .asm files.  This
>> should
>>> be a separate activity.
>>
>> Sure, I can drop that patch, but then the PiSmmCpuDxeSmm
>> changes in the
>> other patches will divert the NASM files from the .S and
>> .asm files. Is
>> that (temporary) non-uniformity better than removing the
>> .S and .asm files?
>>
>>> One odd thing I see in this series is that the
>> instruction
>>> patch label in the .nasm file is just a label and does
>> not
>>> have any storage associated with it.
>>
>> No, this is not correct; the storage that is associated
>> with each of
>> these "patch labels" is the one byte (UINT8) directly
>> following the
>> label -- whatever that byte might be. It is generally
>> part of a totally
>> unrelated instruction.
>>
>> In case we had to patch an immediate operand that
>> happened to comprise
>> the very last byte(s) of a NASM source file, *then* we'd
>> have to add one
>> dummy DB at the end, just so there was something that the
>> label directly
>> refered to.
>>
>> This is why UINT8 is a good type here, because it
>> requires us to add the
>> least amount of padding.
>>
>>> But in the C code
>>> the type UINT8 is used with the label which implies
>> some
>>> storage.  Can we make the globals in C code be a
>> pointer
>>> (maybe VOID *) instead of UINT8?
>>
>> I don't think so. For building the addresses, we rely on
>> the linker, and
>> the linker needs definitions (allocations) of objects.
>> Your above
>> observation is correct (i.e. that storage is required),
>> my addition to
>> that is that storage is *already* allocated (one UINT8
>> per patch label /
>> symbol).
>>
>> Thanks!
>> Laszlo

_______________________________________________
edk2-devel mailing list
[email protected]
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to