Va_arg in EFI

Source: Internet
Author: User

Http://blog.csdn.net/hgf1011/article/details/4713371

This is really a great commodity. It's a good talk. stay here so that you won't be able to find it again later.

Va_arg in EFI

1. Introduction

 

Variable parameters are actually a built-in function of the Standard C language. They have little to do with EFI itself. However, it is re-implemented and used in EDK, and our code base is frequently used. Many OEM callback uses variable parameters to obtain the uniformity of function formats and the flexibility of parameter passing. So I will mention the implementation of variable parameters. I hope it will be helpful for those who are not familiar with legacy bios and who are not very familiar with C.

 

2. function call impl

 

To understand the implementation of variable parameters, you must mention a core component stack necessary for running C. Leaving the stack, C cannot live J, which is why EFI
Code can only be 99%, but cannot be 100%. One of the reasons for implementing it in C (the SEC stage requires that the stack be prepared before the code can be delivered to C ). First, let's take a look at the stack changes during the function call process:

 

Void testq (int A, int B)

{

Int TMP;

A =;

B = B;

Testr ();

}

 

Void testp (void)

{

Testq (1, 2 );

}

Testp calls testq. The stack status is shown in 1.

 

Generally, the stack increases from the high address to the low address, and the ESP parameter is reduced when it is pressed into the stack. the pop-up will certainly increase and will usually be aligned with machine words. The stack space required by a function to save local variables and call the next-level function is called a frame. As shown in figure 1, EBP points to the address as the border, EBP is above a frame, and the following contains the stored testp EBP as another frame. The existence of EBP also facilitates the access of function parameters and local variables. EBP + N can be used to retrieve parameters, and EBP-N can be used to retrieve local variables. The order in which function call parameters are pushed to the stack is related to the platform and compiler, but usually from the right to the left. Therefore, testp puts B on the advanced stack, next, a saves the return address (the position where the execution continues when the returned result is from testq ). With this knowledge, it is enough to unveil the promise of variable parameters. Let's take a look at the implementation of variable parameters.

 

3. va_start, va_arg, va_end

 

These three macros are all the secrets of variable parameters, and there are no more than 10 lines of code. However, if you do not know the STACK layout mentioned above, it is not easy to understand these lines of code. The implementation of codej and EDK on Cuihua is as follows:

 

# DEFINE _ efi_int_size_of (N) (sizeof (n) + sizeof (uintn)-1 )&~ (Sizeof (uintn)-1 ))

//

// Also support coding Convention rules for VAR Arg macros

//

# Ifndef va_start

 

Typedef char8 * va_list;

# Define va_start (AP, V) (AP = (va_list) & (v) + _ efi_int_size_of (v ))

# Define va_arg (AP, t) (* (T *) (AP + = _ efi_int_size_of (t)-_ efi_int_size_of (t )))

# Define va_end (AP) (AP = (va_list) 0)

 

# Endif

Use a sample code to demonstrate and explain the usage and principles of variable parameters.

Void oemcallback (

In oemcallback * This,

In uint32 numofargs,

...

)

{

Va_list marker;

Uint32 TMP;

Uint32 cont;

 

Va_start (Marker, numofargs );

 

For (cont = 0x00; cont <numofargs; ++ cont)

{

TMP = va_arg (Marker, uint32 );

Printf ("the value is: % d,", TMP );

}

 

Printf ("/N ");

 

Va_end (Marker );

 

Return efi_success;

}

 

Int main (INT argc, char ** argv)

{

Oemcallback (null, 3, 5, 10, 33 );

Return 0;

}

Let's first look at what the call stack looks like, and then analyze the implementation principle. Call Stack 2 is shown in:

 

After va_start is expanded, the address of the parameter after numofargs is obtained (Marker = (va_list) & (numofargs) + _ efi_int_size_of (numofargs, that is, the first address of the Variable Parameter column. After va_arg is expanded, it will be a bit interesting: (* (uint32 *) (Marker + = _ efi_int_size_of (uint32)-_ efi_int_size_of (uint32 ))) here, defrence outputs the T-type value of the address pointed to by the current marker, and moves the marker pointer to prepare for the next round. This is "marker
+ = _ Efi_int_size_of (uint32. In this way, the marker pointer can traverse all variable parameters. Va_end is nothing to say, to prevent the emergence of a wild pointer: marker = (va_list) 0. The last _ efi_int_size_of is required for memory alignment of a specific platform. Because the uintn has different sizes on different platforms, this macro will align the memory to a machine word. Variable parameters must have an end identifier. Otherwise, the program cannot identify the number of parameters. numofargs in oemcallback gives the number of parameters, in addition, there must be at least one unchanged parameter J; otherwise, the first address of the Variable Parameter cannot be obtained.

 

The above is all the content of variable parameters. I hope someone can help me with it. I want to vomit blood again.

 

Peter

9-10-22

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.