iPXE
efi_wrap.c
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2014 Michael Brown <mbrown@fensystems.co.uk>.
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License as
00006  * published by the Free Software Foundation; either version 2 of the
00007  * License, or any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful, but
00010  * WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software
00016  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
00017  * 02110-1301, USA.
00018  *
00019  * You can also choose to distribute this program under the terms of
00020  * the Unmodified Binary Distribution Licence (as given in the file
00021  * COPYING.UBDL), provided that you have satisfied its requirements.
00022  */
00023 
00024 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
00025 
00026 /**
00027  * @file
00028  *
00029  * EFI image wrapping
00030  *
00031  */
00032 
00033 #include <string.h>
00034 #include <stdio.h>
00035 #include <errno.h>
00036 #include <ipxe/efi/efi.h>
00037 #include <ipxe/efi/Protocol/LoadedImage.h>
00038 #include <ipxe/efi/efi_wrap.h>
00039 
00040 /** EFI system table wrapper */
00041 static EFI_SYSTEM_TABLE efi_systab_wrapper;
00042 
00043 /** EFI boot services table wrapper */
00044 static EFI_BOOT_SERVICES efi_bs_wrapper;
00045 
00046 /** Colour for debug messages */
00047 #define colour &efi_systab_wrapper
00048 
00049 /**
00050  * Convert EFI status code to text
00051  *
00052  * @v efirc             EFI status code
00053  * @ret text            EFI status code text
00054  */
00055 static const char * efi_status ( EFI_STATUS efirc ) {
00056         static char buf[ 19 /* "0xXXXXXXXXXXXXXXXX" + NUL */ ];
00057 
00058         switch ( efirc ) {
00059         case EFI_SUCCESS :                      return "0";
00060         case EFI_LOAD_ERROR :                   return "LOAD_ERROR";
00061         case EFI_INVALID_PARAMETER :            return "INVALID_PARAMETER";
00062         case EFI_UNSUPPORTED :                  return "UNSUPPORTED";
00063         case EFI_BAD_BUFFER_SIZE :              return "BAD_BUFFER_SIZE";
00064         case EFI_BUFFER_TOO_SMALL :             return "BUFFER_TOO_SMALL";
00065         case EFI_NOT_READY :                    return "NOT_READY";
00066         case EFI_DEVICE_ERROR :                 return "DEVICE_ERROR";
00067         case EFI_WRITE_PROTECTED :              return "WRITE_PROTECTED";
00068         case EFI_OUT_OF_RESOURCES :             return "OUT_OF_RESOURCES";
00069         case EFI_VOLUME_CORRUPTED :             return "VOLUME_CORRUPTED";
00070         case EFI_VOLUME_FULL :                  return "VOLUME_FULL";
00071         case EFI_NO_MEDIA :                     return "NO_MEDIA";
00072         case EFI_MEDIA_CHANGED :                return "MEDIA_CHANGED";
00073         case EFI_NOT_FOUND :                    return "NOT_FOUND";
00074         case EFI_ACCESS_DENIED :                return "ACCESS_DENIED";
00075         case EFI_NO_RESPONSE :                  return "NO_RESPONSE";
00076         case EFI_NO_MAPPING :                   return "NO_MAPPING";
00077         case EFI_TIMEOUT :                      return "TIMEOUT";
00078         case EFI_NOT_STARTED :                  return "NOT_STARTED";
00079         case EFI_ALREADY_STARTED :              return "ALREADY_STARTED";
00080         case EFI_ABORTED :                      return "ABORTED";
00081         case EFI_ICMP_ERROR :                   return "ICMP_ERROR";
00082         case EFI_TFTP_ERROR :                   return "TFTP_ERROR";
00083         case EFI_PROTOCOL_ERROR :               return "PROTOCOL_ERROR";
00084         case EFI_INCOMPATIBLE_VERSION :         return "INCOMPATIBLE_VERSION";
00085         case EFI_SECURITY_VIOLATION :           return "SECURITY_VIOLATION";
00086         case EFI_CRC_ERROR :                    return "CRC_ERROR";
00087         case EFI_END_OF_MEDIA :                 return "END_OF_MEDIA";
00088         case EFI_END_OF_FILE :                  return "END_OF_FILE";
00089         case EFI_INVALID_LANGUAGE :             return "INVALID_LANGUAGE";
00090         case EFI_COMPROMISED_DATA :             return "COMPROMISED_DATA";
00091         case EFI_WARN_UNKNOWN_GLYPH :           return "WARN_UNKNOWN_GLYPH";
00092         case EFI_WARN_DELETE_FAILURE :          return "WARN_DELETE_FAILURE";
00093         case EFI_WARN_WRITE_FAILURE :           return "WARN_WRITE_FAILURE";
00094         case EFI_WARN_BUFFER_TOO_SMALL :        return "WARN_BUFFER_TOO_SMALL";
00095         case EFI_WARN_STALE_DATA :              return "WARN_STALE_DATA";
00096         default:
00097                 snprintf ( buf, sizeof ( buf ), "%#lx",
00098                            ( unsigned long ) efirc );
00099                 return buf;
00100         }
00101 }
00102 
00103 /**
00104  * Convert EFI boolean to text
00105  *
00106  * @v boolean           Boolean value
00107  * @ret text            Boolean value text
00108  */
00109 static const char * efi_boolean ( BOOLEAN boolean ) {
00110 
00111         return ( boolean ? "TRUE" : "FALSE" );
00112 }
00113 
00114 /**
00115  * Wrap InstallProtocolInterface()
00116  *
00117  */
00118 static EFI_STATUS EFIAPI
00119 efi_install_protocol_interface_wrapper ( EFI_HANDLE *handle, EFI_GUID *protocol,
00120                                          EFI_INTERFACE_TYPE interface_type,
00121                                          VOID *interface ) {
00122         EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
00123         void *retaddr = __builtin_return_address ( 0 );
00124         EFI_STATUS efirc;
00125 
00126         DBGC ( colour, "InstallProtocolInterface ( %s, %s, %d, %p ) ",
00127                efi_handle_name ( *handle ), efi_guid_ntoa ( protocol ),
00128                interface_type, interface );
00129         efirc = bs->InstallProtocolInterface ( handle, protocol, interface_type,
00130                                                interface );
00131         DBGC ( colour, "= %s ( %s ) -> %p\n",
00132                efi_status ( efirc ), efi_handle_name ( *handle ), retaddr );
00133         return efirc;
00134 }
00135 
00136 /**
00137  * Wrap ReinstallProtocolInterface()
00138  *
00139  */
00140 static EFI_STATUS EFIAPI
00141 efi_reinstall_protocol_interface_wrapper ( EFI_HANDLE handle,
00142                                            EFI_GUID *protocol,
00143                                            VOID *old_interface,
00144                                            VOID *new_interface ) {
00145         EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
00146         void *retaddr = __builtin_return_address ( 0 );
00147         EFI_STATUS efirc;
00148 
00149         DBGC ( colour, "ReinstallProtocolInterface ( %s, %s, %p, %p ) ",
00150                efi_handle_name ( handle ), efi_guid_ntoa ( protocol ),
00151                old_interface, new_interface );
00152         efirc = bs->ReinstallProtocolInterface ( handle, protocol,
00153                                                  old_interface, new_interface );
00154         DBGC ( colour, "= %s -> %p\n", efi_status ( efirc ), retaddr );
00155         return efirc;
00156 }
00157 
00158 /**
00159  * Wrap UninstallProtocolInterface()
00160  *
00161  */
00162 static EFI_STATUS EFIAPI
00163 efi_uninstall_protocol_interface_wrapper ( EFI_HANDLE handle,
00164                                            EFI_GUID *protocol,
00165                                            VOID *interface ) {
00166         EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
00167         void *retaddr = __builtin_return_address ( 0 );
00168         EFI_STATUS efirc;
00169 
00170         DBGC ( colour, "UninstallProtocolInterface ( %s, %s, %p ) ",
00171                efi_handle_name ( handle ), efi_guid_ntoa ( protocol ),
00172                interface );
00173         efirc = bs->UninstallProtocolInterface ( handle, protocol, interface );
00174         DBGC ( colour, "= %s -> %p\n", efi_status ( efirc ), retaddr );
00175         return efirc;
00176 }
00177 
00178 /**
00179  * Wrap HandleProtocol()
00180  *
00181  */
00182 static EFI_STATUS EFIAPI
00183 efi_handle_protocol_wrapper ( EFI_HANDLE handle, EFI_GUID *protocol,
00184                               VOID **interface ) {
00185         EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
00186         void *retaddr = __builtin_return_address ( 0 );
00187         EFI_STATUS efirc;
00188 
00189         DBGC ( colour, "HandleProtocol ( %s, %s ) ",
00190                efi_handle_name ( handle ), efi_guid_ntoa ( protocol ) );
00191         efirc = bs->HandleProtocol ( handle, protocol, interface );
00192         DBGC ( colour, "= %s ( %p ) -> %p\n",
00193                efi_status ( efirc ), *interface, retaddr );
00194         return efirc;
00195 }
00196 
00197 /**
00198  * Wrap LocateHandle()
00199  *
00200  */
00201 static EFI_STATUS EFIAPI
00202 efi_locate_handle_wrapper ( EFI_LOCATE_SEARCH_TYPE search_type,
00203                             EFI_GUID *protocol, VOID *search_key,
00204                             UINTN *buffer_size, EFI_HANDLE *buffer ) {
00205         EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
00206         void *retaddr = __builtin_return_address ( 0 );
00207         unsigned int i;
00208         EFI_STATUS efirc;
00209 
00210         DBGC ( colour, "LocateHandle ( %s, %s, %p, %zd ) ",
00211                efi_locate_search_type_name ( search_type ),
00212                efi_guid_ntoa ( protocol ), search_key,
00213                ( ( size_t ) *buffer_size ) );
00214         efirc = bs->LocateHandle ( search_type, protocol, search_key,
00215                                    buffer_size, buffer );
00216         DBGC ( colour, "= %s ( %zd", efi_status ( efirc ),
00217                ( ( size_t ) *buffer_size ) );
00218         if ( efirc == 0 ) {
00219                 DBGC ( colour, ", {" );
00220                 for ( i = 0; i < ( *buffer_size / sizeof ( buffer[0] ) ); i++ ){
00221                         DBGC ( colour, "%s%s", ( i ? ", " : " " ),
00222                                efi_handle_name ( buffer[i] ) );
00223                 }
00224                 DBGC ( colour, " }" );
00225         }
00226         DBGC ( colour, " ) -> %p\n", retaddr );
00227         return efirc;
00228 }
00229 
00230 /**
00231  * Wrap LocateDevicePath()
00232  *
00233  */
00234 static EFI_STATUS EFIAPI
00235 efi_locate_device_path_wrapper ( EFI_GUID *protocol,
00236                                  EFI_DEVICE_PATH_PROTOCOL **device_path,
00237                                  EFI_HANDLE *device ) {
00238         EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
00239         void *retaddr = __builtin_return_address ( 0 );
00240         EFI_STATUS efirc;
00241 
00242         DBGC ( colour, "LocateDevicePath ( %s, %s ) ",
00243                efi_guid_ntoa ( protocol ), efi_devpath_text ( *device_path ) );
00244         efirc = bs->LocateDevicePath ( protocol, device_path, device );
00245         DBGC ( colour, "= %s ( %s, ",
00246                efi_status ( efirc ), efi_devpath_text ( *device_path ) );
00247         DBGC ( colour, "%s ) -> %p\n", efi_handle_name ( *device ), retaddr );
00248         return efirc;
00249 }
00250 
00251 /**
00252  * Wrap LoadImage()
00253  *
00254  */
00255 static EFI_STATUS EFIAPI
00256 efi_load_image_wrapper ( BOOLEAN boot_policy, EFI_HANDLE parent_image_handle,
00257                          EFI_DEVICE_PATH_PROTOCOL *device_path,
00258                          VOID *source_buffer, UINTN source_size,
00259                          EFI_HANDLE *image_handle ) {
00260         EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
00261         void *retaddr = __builtin_return_address ( 0 );
00262         EFI_STATUS efirc;
00263 
00264         DBGC ( colour, "LoadImage ( %s, %s, ", efi_boolean ( boot_policy ),
00265                efi_handle_name ( parent_image_handle ) );
00266         DBGC ( colour, "%s, %p, %#llx ) ",
00267                efi_devpath_text ( device_path ), source_buffer,
00268                ( ( unsigned long long ) source_size ) );
00269         efirc = bs->LoadImage ( boot_policy, parent_image_handle, device_path,
00270                                 source_buffer, source_size, image_handle );
00271         DBGC ( colour, "= %s ( ", efi_status ( efirc ) );
00272         if ( efirc == 0 )
00273                 DBGC ( colour, "%s ", efi_handle_name ( *image_handle ) );
00274         DBGC ( colour, ") -> %p\n", retaddr );
00275 
00276         /* Wrap the new image */
00277         if ( efirc == 0 )
00278                 efi_wrap ( *image_handle );
00279 
00280         return efirc;
00281 }
00282 
00283 /**
00284  * Wrap StartImage()
00285  *
00286  */
00287 static EFI_STATUS EFIAPI
00288 efi_start_image_wrapper ( EFI_HANDLE image_handle, UINTN *exit_data_size,
00289                           CHAR16 **exit_data ) {
00290         EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
00291         void *retaddr = __builtin_return_address ( 0 );
00292         EFI_STATUS efirc;
00293 
00294         DBGC ( colour, "StartImage ( %s ) ", efi_handle_name ( image_handle ) );
00295         efirc = bs->StartImage ( image_handle, exit_data_size, exit_data );
00296         DBGC ( colour, "= %s", efi_status ( efirc ) );
00297         if ( ( efirc != 0 ) && exit_data && *exit_data_size )
00298                 DBGC ( colour, " ( \"%ls\" )", *exit_data );
00299         DBGC ( colour, " -> %p\n", retaddr );
00300         if ( ( efirc != 0 ) && exit_data && *exit_data_size )
00301                 DBGC_HD ( colour, *exit_data, *exit_data_size );
00302         return efirc;
00303 }
00304 
00305 /**
00306  * Wrap Exit()
00307  *
00308  */
00309 static EFI_STATUS EFIAPI
00310 efi_exit_wrapper ( EFI_HANDLE image_handle, EFI_STATUS exit_status,
00311                    UINTN exit_data_size, CHAR16 *exit_data ) {
00312         EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
00313         void *retaddr = __builtin_return_address ( 0 );
00314         EFI_STATUS efirc;
00315 
00316         if ( ( exit_status != 0 ) && exit_data && exit_data_size )
00317                 DBGC_HD ( colour, exit_data, exit_data_size );
00318         DBGC ( colour, "Exit ( %s, %s",
00319                efi_handle_name ( image_handle ), efi_status ( exit_status ) );
00320         if ( ( exit_status != 0 ) && exit_data && exit_data_size )
00321                 DBGC ( colour, ", \"%ls\"", exit_data );
00322         DBGC ( colour, " ) " );
00323         efirc = bs->Exit ( image_handle, exit_status, exit_data_size,
00324                            exit_data );
00325         DBGC ( colour, "= %s -> %p\n", efi_status ( efirc ), retaddr );
00326         return efirc;
00327 }
00328 
00329 /**
00330  * Wrap UnloadImage()
00331  *
00332  */
00333 static EFI_STATUS EFIAPI
00334 efi_unload_image_wrapper ( EFI_HANDLE image_handle ) {
00335         EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
00336         void *retaddr = __builtin_return_address ( 0 );
00337         EFI_STATUS efirc;
00338 
00339         DBGC ( colour, "UnloadImage ( %s ) ",
00340                efi_handle_name ( image_handle ) );
00341         efirc = bs->UnloadImage ( image_handle );
00342         DBGC ( colour, "= %s -> %p\n", efi_status ( efirc ), retaddr );
00343         return efirc;
00344 }
00345 
00346 /**
00347  * Wrap ExitBootServices()
00348  *
00349  */
00350 static EFI_STATUS EFIAPI
00351 efi_exit_boot_services_wrapper ( EFI_HANDLE image_handle, UINTN map_key ) {
00352         EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
00353         void *retaddr = __builtin_return_address ( 0 );
00354         EFI_STATUS efirc;
00355 
00356         DBGC ( colour, "ExitBootServices ( %s, %#llx ) ",
00357                efi_handle_name ( image_handle ),
00358                ( ( unsigned long long ) map_key ) );
00359         efirc = bs->ExitBootServices ( image_handle, map_key );
00360         DBGC ( colour, "= %s -> %p\n", efi_status ( efirc ), retaddr );
00361         return efirc;
00362 }
00363 
00364 /**
00365  * Wrap ConnectController()
00366  *
00367  */
00368 static EFI_STATUS EFIAPI
00369 efi_connect_controller_wrapper ( EFI_HANDLE controller_handle,
00370                                  EFI_HANDLE *driver_image_handle,
00371                                  EFI_DEVICE_PATH_PROTOCOL *remaining_path,
00372                                  BOOLEAN recursive ) {
00373         EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
00374         void *retaddr = __builtin_return_address ( 0 );
00375         EFI_HANDLE *tmp;
00376         EFI_STATUS efirc;
00377 
00378         DBGC ( colour, "ConnectController ( %s, {",
00379                efi_handle_name ( controller_handle ) );
00380         if ( driver_image_handle ) {
00381                 for ( tmp = driver_image_handle ; *tmp ; tmp++ ) {
00382                         DBGC ( colour, "%s%s",
00383                                ( ( tmp == driver_image_handle ) ? " " : ", " ),
00384                                efi_handle_name ( *tmp ) );
00385                 }
00386         }
00387         DBGC ( colour, " }, %s, %s ) ", efi_devpath_text ( remaining_path ),
00388                efi_boolean ( recursive ) );
00389         efirc = bs->ConnectController ( controller_handle, driver_image_handle,
00390                                         remaining_path, recursive );
00391         DBGC ( colour, "= %s -> %p\n", efi_status ( efirc ), retaddr );
00392         return efirc;
00393 }
00394 
00395 /**
00396  * Wrap DisconnectController()
00397  *
00398  */
00399 static EFI_STATUS EFIAPI
00400 efi_disconnect_controller_wrapper ( EFI_HANDLE controller_handle,
00401                                     EFI_HANDLE driver_image_handle,
00402                                     EFI_HANDLE child_handle ) {
00403         EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
00404         void *retaddr = __builtin_return_address ( 0 );
00405         EFI_STATUS efirc;
00406 
00407         DBGC ( colour, "DisconnectController ( %s",
00408                efi_handle_name ( controller_handle ) );
00409         DBGC ( colour, ", %s", efi_handle_name ( driver_image_handle ) );
00410         DBGC ( colour, ", %s ) ", efi_handle_name ( child_handle ) );
00411         efirc = bs->DisconnectController ( controller_handle,
00412                                            driver_image_handle,
00413                                            child_handle );
00414         DBGC ( colour, "= %s -> %p\n", efi_status ( efirc ), retaddr );
00415         return efirc;
00416 }
00417 
00418 /**
00419  * Wrap OpenProtocol()
00420  *
00421  */
00422 static EFI_STATUS EFIAPI
00423 efi_open_protocol_wrapper ( EFI_HANDLE handle, EFI_GUID *protocol,
00424                             VOID **interface, EFI_HANDLE agent_handle,
00425                             EFI_HANDLE controller_handle, UINT32 attributes ) {
00426         EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
00427         void *retaddr = __builtin_return_address ( 0 );
00428         EFI_STATUS efirc;
00429 
00430         DBGC ( colour, "OpenProtocol ( %s, %s, ",
00431                efi_handle_name ( handle ), efi_guid_ntoa ( protocol ) );
00432         DBGC ( colour, "%s, ", efi_handle_name ( agent_handle ) );
00433         DBGC ( colour, "%s, %s ) ", efi_handle_name ( controller_handle ),
00434                efi_open_attributes_name ( attributes ) );
00435         efirc = bs->OpenProtocol ( handle, protocol, interface, agent_handle,
00436                                    controller_handle, attributes );
00437         DBGC ( colour, "= %s ( %p ) -> %p\n",
00438                efi_status ( efirc ), *interface, retaddr );
00439         return efirc;
00440 }
00441 
00442 /**
00443  * Wrap CloseProtocol()
00444  *
00445  */
00446 static EFI_STATUS EFIAPI
00447 efi_close_protocol_wrapper ( EFI_HANDLE handle, EFI_GUID *protocol,
00448                              EFI_HANDLE agent_handle,
00449                              EFI_HANDLE controller_handle ) {
00450         EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
00451         void *retaddr = __builtin_return_address ( 0 );
00452         EFI_STATUS efirc;
00453 
00454         DBGC ( colour, "CloseProtocol ( %s, %s, ",
00455                efi_handle_name ( handle ), efi_guid_ntoa ( protocol ) );
00456         DBGC ( colour, "%s, ", efi_handle_name ( agent_handle ) );
00457         DBGC ( colour, "%s ) ", efi_handle_name ( controller_handle ) );
00458         efirc = bs->CloseProtocol ( handle, protocol, agent_handle,
00459                                     controller_handle );
00460         DBGC ( colour, "= %s -> %p\n",
00461                efi_status ( efirc ), retaddr );
00462         return efirc;
00463 }
00464 
00465 /**
00466  * Wrap ProtocolsPerHandle()
00467  *
00468  */
00469 static EFI_STATUS EFIAPI
00470 efi_protocols_per_handle_wrapper ( EFI_HANDLE handle,
00471                                    EFI_GUID ***protocol_buffer,
00472                                    UINTN *protocol_buffer_count ) {
00473         EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
00474         void *retaddr = __builtin_return_address ( 0 );
00475         unsigned int i;
00476         EFI_STATUS efirc;
00477 
00478         DBGC ( colour, "ProtocolsPerHandle ( %s ) ",
00479                efi_handle_name ( handle ) );
00480         efirc = bs->ProtocolsPerHandle ( handle, protocol_buffer,
00481                                          protocol_buffer_count );
00482         DBGC ( colour, "= %s", efi_status ( efirc ) );
00483         if ( efirc == 0 ) {
00484                 DBGC ( colour, " ( {" );
00485                 for ( i = 0 ; i < *protocol_buffer_count ; i++ ) {
00486                         DBGC ( colour, "%s%s", ( i ? ", " : " " ),
00487                                efi_guid_ntoa ( (*protocol_buffer)[i] ) );
00488                 }
00489                 DBGC ( colour, " } )" );
00490         }
00491         DBGC ( colour, " -> %p\n", retaddr );
00492         return efirc;
00493 }
00494 
00495 /**
00496  * Wrap LocateHandleBuffer()
00497  *
00498  */
00499 static EFI_STATUS EFIAPI
00500 efi_locate_handle_buffer_wrapper ( EFI_LOCATE_SEARCH_TYPE search_type,
00501                                    EFI_GUID *protocol, VOID *search_key,
00502                                    UINTN *no_handles, EFI_HANDLE **buffer ) {
00503         EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
00504         void *retaddr = __builtin_return_address ( 0 );
00505         unsigned int i;
00506         EFI_STATUS efirc;
00507 
00508         DBGC ( colour, "LocateHandleBuffer ( %s, %s, %p ) ",
00509                efi_locate_search_type_name ( search_type ),
00510                efi_guid_ntoa ( protocol ), search_key );
00511         efirc = bs->LocateHandleBuffer ( search_type, protocol, search_key,
00512                                          no_handles, buffer );
00513         DBGC ( colour, "= %s", efi_status ( efirc ) );
00514         if ( efirc == 0 ) {
00515                 DBGC ( colour, " ( %d, {", ( ( unsigned int ) *no_handles ) );
00516                 for ( i = 0 ; i < *no_handles ; i++ ) {
00517                         DBGC ( colour, "%s%s", ( i ? ", " : " " ),
00518                                efi_handle_name ( (*buffer)[i] ) );
00519                 }
00520                 DBGC ( colour, " } )" );
00521         }
00522         DBGC ( colour, " -> %p\n", retaddr );
00523         return efirc;
00524 }
00525 
00526 /**
00527  * Wrap LocateProtocol()
00528  *
00529  */
00530 static EFI_STATUS EFIAPI
00531 efi_locate_protocol_wrapper ( EFI_GUID *protocol, VOID *registration,
00532                               VOID **interface ) {
00533         EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
00534         void *retaddr = __builtin_return_address ( 0 );
00535         EFI_STATUS efirc;
00536 
00537         DBGC ( colour, "LocateProtocol ( %s, %p ) ",
00538                efi_guid_ntoa ( protocol ), registration );
00539         efirc = bs->LocateProtocol ( protocol, registration, interface );
00540         DBGC ( colour, "= %s ( %p ) -> %p\n",
00541                efi_status ( efirc ), *interface, retaddr );
00542         return efirc;
00543 }
00544 
00545 /**
00546  * Wrap the calls made by a loaded image
00547  *
00548  * @v handle            Image handle
00549  */
00550  void efi_wrap ( EFI_HANDLE handle ) {
00551         EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
00552         union {
00553                 EFI_LOADED_IMAGE_PROTOCOL *image;
00554                 void *intf;
00555         } loaded;
00556         EFI_STATUS efirc;
00557         int rc;
00558 
00559         /* Do nothing unless debugging is enabled */
00560         if ( ! DBG_LOG )
00561                 return;
00562 
00563         /* Populate table wrappers */
00564         memcpy ( &efi_systab_wrapper, efi_systab,
00565                  sizeof ( efi_systab_wrapper ) );
00566         memcpy ( &efi_bs_wrapper, bs, sizeof ( efi_bs_wrapper ) );
00567         efi_systab_wrapper.BootServices = &efi_bs_wrapper;
00568         efi_bs_wrapper.InstallProtocolInterface
00569                 = efi_install_protocol_interface_wrapper;
00570         efi_bs_wrapper.ReinstallProtocolInterface
00571                 = efi_reinstall_protocol_interface_wrapper;
00572         efi_bs_wrapper.UninstallProtocolInterface
00573                 = efi_uninstall_protocol_interface_wrapper;
00574         efi_bs_wrapper.HandleProtocol   = efi_handle_protocol_wrapper;
00575         efi_bs_wrapper.LocateHandle     = efi_locate_handle_wrapper;
00576         efi_bs_wrapper.LocateDevicePath = efi_locate_device_path_wrapper;
00577         efi_bs_wrapper.LoadImage        = efi_load_image_wrapper;
00578         efi_bs_wrapper.StartImage       = efi_start_image_wrapper;
00579         efi_bs_wrapper.Exit             = efi_exit_wrapper;
00580         efi_bs_wrapper.UnloadImage      = efi_unload_image_wrapper;
00581         efi_bs_wrapper.ExitBootServices = efi_exit_boot_services_wrapper;
00582         efi_bs_wrapper.ConnectController
00583                 = efi_connect_controller_wrapper;
00584         efi_bs_wrapper.DisconnectController
00585                 = efi_disconnect_controller_wrapper;
00586         efi_bs_wrapper.OpenProtocol     = efi_open_protocol_wrapper;
00587         efi_bs_wrapper.CloseProtocol    = efi_close_protocol_wrapper;
00588         efi_bs_wrapper.ProtocolsPerHandle
00589                 = efi_protocols_per_handle_wrapper;
00590         efi_bs_wrapper.LocateHandleBuffer
00591                 = efi_locate_handle_buffer_wrapper;
00592         efi_bs_wrapper.LocateProtocol   = efi_locate_protocol_wrapper;
00593 
00594         /* Open loaded image protocol */
00595         if ( ( efirc = bs->OpenProtocol ( handle,
00596                                           &efi_loaded_image_protocol_guid,
00597                                           &loaded.intf, efi_image_handle, NULL,
00598                                           EFI_OPEN_PROTOCOL_GET_PROTOCOL ))!=0){
00599                 rc = -EEFI ( efirc );
00600                 DBGC ( colour, "WRAP %s could not get loaded image protocol: "
00601                        "%s\n", efi_handle_name ( handle ), strerror ( rc ) );
00602                 return;
00603         }
00604 
00605         /* Provide system table wrapper to image */
00606         loaded.image->SystemTable = &efi_systab_wrapper;
00607         DBGC ( colour, "WRAP %s at base %p has protocols:\n",
00608                efi_handle_name ( handle ), loaded.image->ImageBase );
00609         DBGC_EFI_PROTOCOLS ( colour, handle );
00610         DBGC ( colour, "WRAP %s parent", efi_handle_name ( handle ) );
00611         DBGC ( colour, " %s\n", efi_handle_name ( loaded.image->ParentHandle ));
00612         DBGC ( colour, "WRAP %s device", efi_handle_name ( handle ) );
00613         DBGC ( colour, " %s\n", efi_handle_name ( loaded.image->DeviceHandle ));
00614         DBGC ( colour, "WRAP %s file", efi_handle_name ( handle ) );
00615         DBGC ( colour, " %s\n", efi_devpath_text ( loaded.image->FilePath ) );
00616 
00617         /* Close loaded image protocol */
00618         bs->CloseProtocol ( handle, &efi_loaded_image_protocol_guid,
00619                             efi_image_handle, NULL );
00620 }