On 04/17/19 20:31, Kinney, Michael D wrote:
> Laszlo,
>
> We should also be able to do a consistent fix without
> adding any new unions or macros:
>
> #define FFS_FILE_SIZE(FfsFileHeaderPtr) ((UINT32)( \
>   (((EFI_FFS_FILE_HEADER *) (UINTN) FfsFileHeaderPtr)->Size[0]       ) | \
>   (((EFI_FFS_FILE_HEADER *) (UINTN) FfsFileHeaderPtr)->Size[1] << 8  ) | \
>   (((EFI_FFS_FILE_HEADER *) (UINTN) FfsFileHeaderPtr)->Size[2] << 16 ) ))
>
> #define SECTION_SIZE(SectionHeaderPtr) ((UINT32)( \
>   (((EFI_COMMON_SECTION_HEADER *) (UINTN) SectionHeaderPtr)->Size[0]       ) 
> | \
>   (((EFI_COMMON_SECTION_HEADER *) (UINTN) SectionHeaderPtr)->Size[1] << 8  ) 
> | \
>   (((EFI_COMMON_SECTION_HEADER *) (UINTN) SectionHeaderPtr)->Size[2] << 16 ) 
> ))

I'll adopt this (see my other reply), with one small change: I think
I'll wrap "SectionHeaderPtr" in an extra set of parens.

My main reason for introducing the intermediate macros was that I wanted
to cast each UINT8 *individually* to UINT32, before applying the shift:

#define FFS_FILE_SIZE_ELEMENT(FfsFileHeaderPtr, Index) \
    ((UINT32) FFS_FILE_SIZE_ARRAY (FfsFileHeaderPtr)[(Index)])

#define FFS_FILE_SIZE(FfsFileHeaderPtr) \
    ((FFS_FILE_SIZE_ELEMENT ((FfsFileHeaderPtr), 0) <<  0) | \
     (FFS_FILE_SIZE_ELEMENT ((FfsFileHeaderPtr), 1) <<  8) | \
     (FFS_FILE_SIZE_ELEMENT ((FfsFileHeaderPtr), 2) << 16))

- Such casting is generally a good idea because UINT8 is promoted to
  INT32 as part of the integer promotions, and I consider bit-shifting
  signed integers bad hygiene (it carries a risk of undefined behavior).

- But then I felt that spelling out the same (UINT32) cast on every line
  of the expanded / flattened version of FFS_FILE_SIZE would make the
  replacement text simply too wide and hard to read. Hence the helper
  macros.

Now, in this particular case however (i.e. producing 24-bit unsigned
integers in the end), you have convinced me that casting to UINT32, as
the outermost operation only, is safe enough. Because, we never shift an
INT32 to the left by more than 16 bits, and that INT32 (pre-shift) is in
[0, UINT8_MAX] inclusive (because it comes from Size[2]). So the result
is always representable in an INT32.

... I've now also checked that no invocation of FFS_FILE_SIZE or
SECTION_SIZE in edk2 passes an argument with side effects, so evaluating
the arguments in the new macros multiple times should be safe. I might
add a new comment about this restriction.

Thanks!
Laszlo

-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.

View/Reply Online (#39291): https://edk2.groups.io/g/devel/message/39291
Mute This Topic: https://groups.io/mt/31070304/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub  [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-

Reply via email to