12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259 |
- /*
- * utils/efirom.c
- *
- * Copyright (C) 2009 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * modifications for gnuefi by bzt (bztsrc@gitlab)
- *
- * This file is part of the POSIX-UEFI package.
- * @brief small tool to convert an .efi file to a .rom file
- *
- */
- #include <stdint.h>
- #include <stddef.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <sys/stat.h>
- #include <unistd.h>
- #include <errno.h>
- #include <assert.h>
- #include <getopt.h>
- #define eprintf(...) fprintf ( stderr, __VA_ARGS__ )
- /**
- * Print help
- *
- * @v program_name Program name
- */
- static void print_help ( const char *program_name ) {
- eprintf ( "POSIX-UEFI utils - efirom by Michael Brown GPL\r\n\r\n" );
- eprintf ( "%s [--vendor=VVVV] [--device=DDDD] "
- "infile outfile\n", program_name );
- }
- #define EFI_SIGNATURE_16(A,B) ((A) | (B<<8))
- #define EFI_SIGNATURE_32(A,B,C,D) (EFI_SIGNATURE_16(A,B) | (EFI_SIGNATURE_16(C,D) << 16))
- #define EFI_SIGNATURE_64(A,B,C,D,E,F,G,H) (EFI_SIGNATURE_32(A,B,C,D) | ((UINT64)(EFI_SIGNATURE_32(E,F,G,H)) << 32))
- typedef uint64_t UINTN;
- typedef UINTN EFI_TPL;
- typedef struct _EFI_DEVICE_PATH_PROTOCOL {
- uint8_t Type;
- uint8_t SubType;
- uint8_t Length[2];
- } EFI_DEVICE_PATH_PROTOCOL;
- typedef struct _EFI_DEVICE_PATH_PROTOCOL _EFI_DEVICE_PATH;
- typedef EFI_DEVICE_PATH_PROTOCOL EFI_DEVICE_PATH;
- #ifndef _EFI_LINK_H
- #define _EFI_LINK_H
- /*++
- Copyright (c) 1998 Intel Corporation
- Module Name:
- link.h (renamed efilink.h to avoid conflicts)
- Abstract:
- EFI link list macro's
- Revision History
- --*/
- #ifndef EFI_NT_EMUL
- //
- // List entry - doubly linked list
- //
- typedef struct _LIST_ENTRY {
- struct _LIST_ENTRY *Flink;
- struct _LIST_ENTRY *Blink;
- } LIST_ENTRY;
- #endif
- //
- // VOID
- // InitializeListHead(
- // LIST_ENTRY *ListHead
- // );
- //
- #define InitializeListHead(ListHead) \
- (ListHead)->Flink = ListHead; \
- (ListHead)->Blink = ListHead;
- //
- // BOOLEAN
- // IsListEmpty(
- // PLIST_ENTRY ListHead
- // );
- //
- #define IsListEmpty(ListHead) \
- ((ListHead)->Flink == (ListHead))
- //
- // VOID
- // RemoveEntryList(
- // PLIST_ENTRY Entry
- // );
- //
- #define _RemoveEntryList(Entry) { \
- LIST_ENTRY *_Blink, *_Flink; \
- _Flink = (Entry)->Flink; \
- _Blink = (Entry)->Blink; \
- _Blink->Flink = _Flink; \
- _Flink->Blink = _Blink; \
- }
- #if EFI_DEBUG
- #define RemoveEntryList(Entry) \
- _RemoveEntryList(Entry); \
- (Entry)->Flink = (LIST_ENTRY *) BAD_POINTER; \
- (Entry)->Blink = (LIST_ENTRY *) BAD_POINTER;
- #else
- #define RemoveEntryList(Entry) \
- _RemoveEntryList(Entry);
- #endif
- //
- // VOID
- // InsertTailList(
- // PLIST_ENTRY ListHead,
- // PLIST_ENTRY Entry
- // );
- //
- #define InsertTailList(ListHead,Entry) {\
- LIST_ENTRY *_ListHead, *_Blink; \
- _ListHead = (ListHead); \
- _Blink = _ListHead->Blink; \
- (Entry)->Flink = _ListHead; \
- (Entry)->Blink = _Blink; \
- _Blink->Flink = (Entry); \
- _ListHead->Blink = (Entry); \
- }
- //
- // VOID
- // InsertHeadList(
- // PLIST_ENTRY ListHead,
- // PLIST_ENTRY Entry
- // );
- //
- #define InsertHeadList(ListHead,Entry) {\
- LIST_ENTRY *_ListHead, *_Flink; \
- _ListHead = (ListHead); \
- _Flink = _ListHead->Flink; \
- (Entry)->Flink = _Flink; \
- (Entry)->Blink = _ListHead; \
- _Flink->Blink = (Entry); \
- _ListHead->Flink = (Entry); \
- }
- // VOID
- // SwapListEntries(
- // PLIST_ENTRY Entry1,
- // PLIST_ENTRY Entry2
- // );
- //
- // Put Entry2 before Entry1
- //
- #define SwapListEntries(Entry1,Entry2) {\
- LIST_ENTRY *Entry1Flink, *Entry1Blink; \
- LIST_ENTRY *Entry2Flink, *Entry2Blink; \
- Entry2Flink = (Entry2)->Flink; \
- Entry2Blink = (Entry2)->Blink; \
- Entry1Flink = (Entry1)->Flink; \
- Entry1Blink = (Entry1)->Blink; \
- Entry2Blink->Flink = Entry2Flink; \
- Entry2Flink->Blink = Entry2Blink; \
- (Entry2)->Flink = Entry1; \
- (Entry2)->Blink = Entry1Blink; \
- Entry1Blink->Flink = (Entry2); \
- (Entry1)->Blink = (Entry2); \
- }
- //
- // EFI_FIELD_OFFSET - returns the byte offset to a field within a structure
- //
- #define EFI_FIELD_OFFSET(TYPE,Field) ((UINTN)(&(((TYPE *) 0)->Field)))
- //
- // CONTAINING_RECORD - returns a pointer to the structure
- // from one of it's elements.
- //
- #define _CR(Record, TYPE, Field) \
- ((TYPE *) ( (CHAR8 *)(Record) - (CHAR8 *) &(((TYPE *) 0)->Field)))
- #if EFI_DEBUG
- #define CR(Record, TYPE, Field, Sig) \
- _CR(Record, TYPE, Field)->Signature != Sig ? \
- (TYPE *) ASSERT_STRUCT(_CR(Record, TYPE, Field), Record) : \
- _CR(Record, TYPE, Field)
- #else
- #define CR(Record, TYPE, Field, Signature) \
- _CR(Record, TYPE, Field)
- #endif
- //
- // A lock structure
- //
- typedef struct _FLOCK {
- EFI_TPL Tpl;
- EFI_TPL OwnerTpl;
- UINTN Lock;
- } FLOCK;
- #endif
- /*
- PE32+ header file
- */
- #ifndef _PE_H
- #define _PE_H
- #define IMAGE_DOS_SIGNATURE 0x5A4D // MZ
- #define IMAGE_OS2_SIGNATURE 0x454E // NE
- #define IMAGE_OS2_SIGNATURE_LE 0x454C // LE
- #define IMAGE_NT_SIGNATURE 0x00004550 // PE00
- #define IMAGE_EDOS_SIGNATURE 0x44454550 // PEED
- typedef struct _IMAGE_DOS_HEADER { // DOS .EXE header
- uint16_t e_magic; // Magic number
- uint16_t e_cblp; // Bytes on last page of file
- uint16_t e_cp; // Pages in file
- uint16_t e_crlc; // Relocations
- uint16_t e_cparhdr; // Size of header in paragraphs
- uint16_t e_minalloc; // Minimum extra paragraphs needed
- uint16_t e_maxalloc; // Maximum extra paragraphs needed
- uint16_t e_ss; // Initial (relative) SS value
- uint16_t e_sp; // Initial SP value
- uint16_t e_csum; // Checksum
- uint16_t e_ip; // Initial IP value
- uint16_t e_cs; // Initial (relative) CS value
- uint16_t e_lfarlc; // File address of relocation table
- uint16_t e_ovno; // Overlay number
- uint16_t e_res[4]; // Reserved words
- uint16_t e_oemid; // OEM identifier (for e_oeminfo)
- uint16_t e_oeminfo; // OEM information; e_oemid specific
- uint16_t e_res2[10]; // Reserved words
- uint32_t e_lfanew; // File address of new exe header
- } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
- typedef struct _IMAGE_OS2_HEADER { // OS/2 .EXE header
- uint16_t ne_magic; // Magic number
- uint8_t ne_ver; // Version number
- uint8_t ne_rev; // Revision number
- uint16_t ne_enttab; // Offset of Entry Table
- uint16_t ne_cbenttab; // Number of bytes in Entry Table
- uint32_t ne_crc; // Checksum of whole file
- uint16_t ne_flags; // Flag uint16_t
- uint16_t ne_autodata; // Automatic data segment number
- uint16_t ne_heap; // Initial heap allocation
- uint16_t ne_stack; // Initial stack allocation
- uint32_t ne_csip; // Initial CS:IP setting
- uint32_t ne_sssp; // Initial SS:SP setting
- uint16_t ne_cseg; // Count of file segments
- uint16_t ne_cmod; // Entries in Module Reference Table
- uint16_t ne_cbnrestab; // Size of non-resident name table
- uint16_t ne_segtab; // Offset of Segment Table
- uint16_t ne_rsrctab; // Offset of Resource Table
- uint16_t ne_restab; // Offset of resident name table
- uint16_t ne_modtab; // Offset of Module Reference Table
- uint16_t ne_imptab; // Offset of Imported Names Table
- uint32_t ne_nrestab; // Offset of Non-resident Names Table
- uint16_t ne_cmovent; // Count of movable entries
- uint16_t ne_align; // Segment alignment shift count
- uint16_t ne_cres; // Count of resource segments
- uint8_t ne_exetyp; // Target Operating system
- uint8_t ne_flagsothers; // Other .EXE flags
- uint16_t ne_pretthunks; // offset to return thunks
- uint16_t ne_psegrefbytes; // offset to segment ref. bytes
- uint16_t ne_swaparea; // Minimum code swap area size
- uint16_t ne_expver; // Expected Windows version number
- } IMAGE_OS2_HEADER, *PIMAGE_OS2_HEADER;
- //
- // File header format.
- //
- typedef struct _IMAGE_FILE_HEADER {
- uint16_t Machine;
- uint16_t NumberOfSections;
- uint32_t TimeDateStamp;
- uint32_t PointerToSymbolTable;
- uint32_t NumberOfSymbols;
- uint16_t SizeOfOptionalHeader;
- uint16_t Characteristics;
- } IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
- #define IMAGE_SIZEOF_FILE_HEADER 20
- #define IMAGE_FILE_RELOCS_STRIPPED 0x0001 // Relocation info stripped from file.
- #define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002 // File is executable (i.e. no unresolved externel references).
- #define IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004 // Line nunbers stripped from file.
- #define IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008 // Local symbols stripped from file.
- #define IMAGE_FILE_BYTES_REVERSED_LO 0x0080 // Bytes of machine word are reversed.
- #define IMAGE_FILE_32BIT_MACHINE 0x0100 // 32 bit word machine.
- #define IMAGE_FILE_DEBUG_STRIPPED 0x0200 // Debugging info stripped from file in .DBG file
- #define IMAGE_FILE_SYSTEM 0x1000 // System File.
- #define IMAGE_FILE_DLL 0x2000 // File is a DLL.
- #define IMAGE_FILE_BYTES_REVERSED_HI 0x8000 // Bytes of machine word are reversed.
- #define IMAGE_FILE_MACHINE_UNKNOWN 0
- #define IMAGE_FILE_MACHINE_I386 0x14c // Intel 386.
- #define IMAGE_FILE_MACHINE_R3000 0x162 // MIPS little-endian, 0540 big-endian
- #define IMAGE_FILE_MACHINE_R4000 0x166 // MIPS little-endian
- #define IMAGE_FILE_MACHINE_ALPHA 0x184 // Alpha_AXP
- #define IMAGE_FILE_MACHINE_ARMTHUMB_MIXED 0x1c2 // Arm/Thumb
- #define IMAGE_FILE_MACHINE_POWERPC 0x1F0 // IBM PowerPC Little-Endian
- #define IMAGE_FILE_MACHINE_IA64 0x200 // IA-64
- #define IMAGE_FILE_MACHINE_TAHOE 0x7cc // Intel EM machine
- #define IMAGE_FILE_MACHINE_EBC 0xebc // EFI Byte Code
- #define IMAGE_FILE_MACHINE_X64 0x8664 // x86_64
- //
- // Directory format.
- //
- typedef struct _IMAGE_DATA_DIRECTORY {
- uint32_t VirtualAddress;
- uint32_t Size;
- } IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
- #define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
- //
- // Optional header format.
- //
- typedef struct _IMAGE_OPTIONAL_HEADER {
- //
- // Standard fields.
- //
- uint16_t Magic;
- uint8_t MajorLinkerVersion;
- uint8_t MinorLinkerVersion;
- uint32_t SizeOfCode;
- uint32_t SizeOfInitializedData;
- uint32_t SizeOfUninitializedData;
- uint32_t AddressOfEntryPoint;
- uint32_t BaseOfCode;
- uint32_t BaseOfData;
- //
- // NT additional fields.
- //
- uint32_t ImageBase;
- uint32_t SectionAlignment;
- uint32_t FileAlignment;
- uint16_t MajorOperatingSystemVersion;
- uint16_t MinorOperatingSystemVersion;
- uint16_t MajorImageVersion;
- uint16_t MinorImageVersion;
- uint16_t MajorSubsystemVersion;
- uint16_t MinorSubsystemVersion;
- uint32_t Reserved1;
- uint32_t SizeOfImage;
- uint32_t SizeOfHeaders;
- uint32_t CheckSum;
- uint16_t Subsystem;
- uint16_t DllCharacteristics;
- uint32_t SizeOfStackReserve;
- uint32_t SizeOfStackCommit;
- uint32_t SizeOfHeapReserve;
- uint32_t SizeOfHeapCommit;
- uint32_t LoaderFlags;
- uint32_t NumberOfRvaAndSizes;
- IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
- } IMAGE_OPTIONAL_HEADER, *PIMAGE_OPTIONAL_HEADER;
- typedef struct _IMAGE_ROM_OPTIONAL_HEADER {
- uint16_t Magic;
- uint8_t MajorLinkerVersion;
- uint8_t MinorLinkerVersion;
- uint32_t SizeOfCode;
- uint32_t SizeOfInitializedData;
- uint32_t SizeOfUninitializedData;
- uint32_t AddressOfEntryPoint;
- uint32_t BaseOfCode;
- uint32_t BaseOfData;
- uint32_t BaseOfBss;
- uint32_t GprMask;
- uint32_t CprMask[4];
- uint32_t GpValue;
- } IMAGE_ROM_OPTIONAL_HEADER, *PIMAGE_ROM_OPTIONAL_HEADER;
- #define IMAGE_SIZEOF_ROM_OPTIONAL_HEADER 56
- #define IMAGE_SIZEOF_STD_OPTIONAL_HEADER 28
- #define IMAGE_SIZEOF_NT_OPTIONAL_HEADER 224
- #define IMAGE_NT_OPTIONAL_HDR_MAGIC 0x10b
- #define IMAGE_ROM_OPTIONAL_HDR_MAGIC 0x107
- typedef struct _IMAGE_NT_HEADERS {
- uint32_t Signature;
- IMAGE_FILE_HEADER FileHeader;
- IMAGE_OPTIONAL_HEADER OptionalHeader;
- } IMAGE_NT_HEADERS, *PIMAGE_NT_HEADERS;
- typedef struct _IMAGE_ROM_HEADERS {
- IMAGE_FILE_HEADER FileHeader;
- IMAGE_ROM_OPTIONAL_HEADER OptionalHeader;
- } IMAGE_ROM_HEADERS, *PIMAGE_ROM_HEADERS;
- #define IMAGE_FIRST_SECTION( ntheader ) ((PIMAGE_SECTION_HEADER) \
- ((uint32_t)ntheader + \
- FIELD_OFFSET( IMAGE_NT_HEADERS, OptionalHeader ) + \
- ((PIMAGE_NT_HEADERS)(ntheader))->FileHeader.SizeOfOptionalHeader \
- ))
- // Subsystem Values
- #define IMAGE_SUBSYSTEM_UNKNOWN 0 // Unknown subsystem.
- #define IMAGE_SUBSYSTEM_NATIVE 1 // Image doesn't require a subsystem.
- #define IMAGE_SUBSYSTEM_WINDOWS_GUI 2 // Image runs in the Windows GUI subsystem.
- #define IMAGE_SUBSYSTEM_WINDOWS_CUI 3 // Image runs in the Windows character subsystem.
- #define IMAGE_SUBSYSTEM_OS2_CUI 5 // image runs in the OS/2 character subsystem.
- #define IMAGE_SUBSYSTEM_POSIX_CUI 7 // image run in the Posix character subsystem.
- // Directory Entries
- #define IMAGE_DIRECTORY_ENTRY_EXPORT 0 // Export Directory
- #define IMAGE_DIRECTORY_ENTRY_IMPORT 1 // Import Directory
- #define IMAGE_DIRECTORY_ENTRY_RESOURCE 2 // Resource Directory
- #define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3 // Exception Directory
- #define IMAGE_DIRECTORY_ENTRY_SECURITY 4 // Security Directory
- #define IMAGE_DIRECTORY_ENTRY_BASERELOC 5 // Base Relocation Table
- #define IMAGE_DIRECTORY_ENTRY_DEBUG 6 // Debug Directory
- #define IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7 // Description String
- #define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 // Machine Value (MIPS GP)
- #define IMAGE_DIRECTORY_ENTRY_TLS 9 // TLS Directory
- #define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10 // Load Configuration Directory
- //
- // Section header format.
- //
- #define IMAGE_SIZEOF_SHORT_NAME 8
- typedef struct _IMAGE_SECTION_HEADER {
- uint8_t Name[IMAGE_SIZEOF_SHORT_NAME];
- union {
- uint32_t PhysicalAddress;
- uint32_t VirtualSize;
- } Misc;
- uint32_t VirtualAddress;
- uint32_t SizeOfRawData;
- uint32_t PointerToRawData;
- uint32_t PointerToRelocations;
- uint32_t PointerToLinenumbers;
- uint16_t NumberOfRelocations;
- uint16_t NumberOfLinenumbers;
- uint32_t Characteristics;
- } IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
- #define IMAGE_SIZEOF_SECTION_HEADER 40
- #define IMAGE_SCN_TYPE_NO_PAD 0x00000008 // Reserved.
- #define IMAGE_SCN_CNT_CODE 0x00000020 // Section contains code.
- #define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 // Section contains initialized data.
- #define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 // Section contains uninitialized data.
- #define IMAGE_SCN_LNK_OTHER 0x00000100 // Reserved.
- #define IMAGE_SCN_LNK_INFO 0x00000200 // Section contains comments or some other type of information.
- #define IMAGE_SCN_LNK_REMOVE 0x00000800 // Section contents will not become part of image.
- #define IMAGE_SCN_LNK_COMDAT 0x00001000 // Section contents comdat.
- #define IMAGE_SCN_ALIGN_1BYTES 0x00100000 //
- #define IMAGE_SCN_ALIGN_2BYTES 0x00200000 //
- #define IMAGE_SCN_ALIGN_4BYTES 0x00300000 //
- #define IMAGE_SCN_ALIGN_8BYTES 0x00400000 //
- #define IMAGE_SCN_ALIGN_16BYTES 0x00500000 // Default alignment if no others are specified.
- #define IMAGE_SCN_ALIGN_32BYTES 0x00600000 //
- #define IMAGE_SCN_ALIGN_64BYTES 0x00700000 //
- #define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 // Section can be discarded.
- #define IMAGE_SCN_MEM_NOT_CACHED 0x04000000 // Section is not cachable.
- #define IMAGE_SCN_MEM_NOT_PAGED 0x08000000 // Section is not pageable.
- #define IMAGE_SCN_MEM_SHARED 0x10000000 // Section is shareable.
- #define IMAGE_SCN_MEM_EXECUTE 0x20000000 // Section is executable.
- #define IMAGE_SCN_MEM_READ 0x40000000 // Section is readable.
- #define IMAGE_SCN_MEM_WRITE 0x80000000 // Section is writeable.
- //
- // Symbol format.
- //
- #define IMAGE_SIZEOF_SYMBOL 18
- //
- // Section values.
- //
- // Symbols have a section number of the section in which they are
- // defined. Otherwise, section numbers have the following meanings:
- //
- #define IMAGE_SYM_UNDEFINED (uint16_t)0 // Symbol is undefined or is common.
- #define IMAGE_SYM_ABSOLUTE (uint16_t)-1 // Symbol is an absolute value.
- #define IMAGE_SYM_DEBUG (uint16_t)-2 // Symbol is a special debug item.
- //
- // Type (fundamental) values.
- //
- #define IMAGE_SYM_TYPE_NULL 0 // no type.
- #define IMAGE_SYM_TYPE_VOID 1 //
- #define IMAGE_SYM_TYPE_CHAR 2 // type character.
- #define IMAGE_SYM_TYPE_SHORT 3 // type short integer.
- #define IMAGE_SYM_TYPE_INT 4 //
- #define IMAGE_SYM_TYPE_LONG 5 //
- #define IMAGE_SYM_TYPE_FLOAT 6 //
- #define IMAGE_SYM_TYPE_DOUBLE 7 //
- #define IMAGE_SYM_TYPE_STRUCT 8 //
- #define IMAGE_SYM_TYPE_UNION 9 //
- #define IMAGE_SYM_TYPE_ENUM 10 // enumeration.
- #define IMAGE_SYM_TYPE_MOE 11 // member of enumeration.
- #define IMAGE_SYM_TYPE_BYTE 12 //
- #define IMAGE_SYM_TYPE_WORD 13 //
- #define IMAGE_SYM_TYPE_UINT 14 //
- #define IMAGE_SYM_TYPE_DWORD 15 //
- //
- // Type (derived) values.
- //
- #define IMAGE_SYM_DTYPE_NULL 0 // no derived type.
- #define IMAGE_SYM_DTYPE_POINTER 1 // pointer.
- #define IMAGE_SYM_DTYPE_FUNCTION 2 // function.
- #define IMAGE_SYM_DTYPE_ARRAY 3 // array.
- //
- // Storage classes.
- //
- #define IMAGE_SYM_CLASS_END_OF_FUNCTION (BYTE )-1
- #define IMAGE_SYM_CLASS_NULL 0
- #define IMAGE_SYM_CLASS_AUTOMATIC 1
- #define IMAGE_SYM_CLASS_EXTERNAL 2
- #define IMAGE_SYM_CLASS_STATIC 3
- #define IMAGE_SYM_CLASS_REGISTER 4
- #define IMAGE_SYM_CLASS_EXTERNAL_DEF 5
- #define IMAGE_SYM_CLASS_LABEL 6
- #define IMAGE_SYM_CLASS_UNDEFINED_LABEL 7
- #define IMAGE_SYM_CLASS_MEMBER_OF_STRUCT 8
- #define IMAGE_SYM_CLASS_ARGUMENT 9
- #define IMAGE_SYM_CLASS_STRUCT_TAG 10
- #define IMAGE_SYM_CLASS_MEMBER_OF_UNION 11
- #define IMAGE_SYM_CLASS_UNION_TAG 12
- #define IMAGE_SYM_CLASS_TYPE_DEFINITION 13
- #define IMAGE_SYM_CLASS_UNDEFINED_STATIC 14
- #define IMAGE_SYM_CLASS_ENUM_TAG 15
- #define IMAGE_SYM_CLASS_MEMBER_OF_ENUM 16
- #define IMAGE_SYM_CLASS_REGISTER_PARAM 17
- #define IMAGE_SYM_CLASS_BIT_FIELD 18
- #define IMAGE_SYM_CLASS_BLOCK 100
- #define IMAGE_SYM_CLASS_FUNCTION 101
- #define IMAGE_SYM_CLASS_END_OF_STRUCT 102
- #define IMAGE_SYM_CLASS_FILE 103
- // new
- #define IMAGE_SYM_CLASS_SECTION 104
- #define IMAGE_SYM_CLASS_WEAK_EXTERNAL 105
- // type packing constants
- #define N_BTMASK 017
- #define N_TMASK 060
- #define N_TMASK1 0300
- #define N_TMASK2 0360
- #define N_BTSHFT 4
- #define N_TSHIFT 2
- // MACROS
- //
- // Communal selection types.
- //
- #define IMAGE_COMDAT_SELECT_NODUPLICATES 1
- #define IMAGE_COMDAT_SELECT_ANY 2
- #define IMAGE_COMDAT_SELECT_SAME_SIZE 3
- #define IMAGE_COMDAT_SELECT_EXACT_MATCH 4
- #define IMAGE_COMDAT_SELECT_ASSOCIATIVE 5
- #define IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY 1
- #define IMAGE_WEAK_EXTERN_SEARCH_LIBRARY 2
- #define IMAGE_WEAK_EXTERN_SEARCH_ALIAS 3
- //
- // Relocation format.
- //
- typedef struct _IMAGE_RELOCATION {
- uint32_t VirtualAddress;
- uint32_t SymbolTableIndex;
- uint16_t Type;
- } IMAGE_RELOCATION;
- #define IMAGE_SIZEOF_RELOCATION 10
- //
- // I386 relocation types.
- //
- #define IMAGE_REL_I386_ABSOLUTE 0 // Reference is absolute, no relocation is necessary
- #define IMAGE_REL_I386_DIR16 01 // Direct 16-bit reference to the symbols virtual address
- #define IMAGE_REL_I386_REL16 02 // PC-relative 16-bit reference to the symbols virtual address
- #define IMAGE_REL_I386_DIR32 06 // Direct 32-bit reference to the symbols virtual address
- #define IMAGE_REL_I386_DIR32NB 07 // Direct 32-bit reference to the symbols virtual address, base not included
- #define IMAGE_REL_I386_SEG12 011 // Direct 16-bit reference to the segment-selector bits of a 32-bit virtual address
- #define IMAGE_REL_I386_SECTION 012
- #define IMAGE_REL_I386_SECREL 013
- #define IMAGE_REL_I386_REL32 024 // PC-relative 32-bit reference to the symbols virtual address
- //
- // MIPS relocation types.
- //
- #define IMAGE_REL_MIPS_ABSOLUTE 0 // Reference is absolute, no relocation is necessary
- #define IMAGE_REL_MIPS_REFHALF 01
- #define IMAGE_REL_MIPS_REFWORD 02
- #define IMAGE_REL_MIPS_JMPADDR 03
- #define IMAGE_REL_MIPS_REFHI 04
- #define IMAGE_REL_MIPS_REFLO 05
- #define IMAGE_REL_MIPS_GPREL 06
- #define IMAGE_REL_MIPS_LITERAL 07
- #define IMAGE_REL_MIPS_SECTION 012
- #define IMAGE_REL_MIPS_SECREL 013
- #define IMAGE_REL_MIPS_REFWORDNB 042
- #define IMAGE_REL_MIPS_PAIR 045
- //
- // Alpha Relocation types.
- //
- #define IMAGE_REL_ALPHA_ABSOLUTE 0x0
- #define IMAGE_REL_ALPHA_REFLONG 0x1
- #define IMAGE_REL_ALPHA_REFQUAD 0x2
- #define IMAGE_REL_ALPHA_GPREL32 0x3
- #define IMAGE_REL_ALPHA_LITERAL 0x4
- #define IMAGE_REL_ALPHA_LITUSE 0x5
- #define IMAGE_REL_ALPHA_GPDISP 0x6
- #define IMAGE_REL_ALPHA_BRADDR 0x7
- #define IMAGE_REL_ALPHA_HINT 0x8
- #define IMAGE_REL_ALPHA_INLINE_REFLONG 0x9
- #define IMAGE_REL_ALPHA_REFHI 0xA
- #define IMAGE_REL_ALPHA_REFLO 0xB
- #define IMAGE_REL_ALPHA_PAIR 0xC
- #define IMAGE_REL_ALPHA_MATCH 0xD
- #define IMAGE_REL_ALPHA_SECTION 0xE
- #define IMAGE_REL_ALPHA_SECREL 0xF
- #define IMAGE_REL_ALPHA_REFLONGNB 0x10
- //
- // IBM PowerPC relocation types.
- //
- #define IMAGE_REL_PPC_ABSOLUTE 0x0000 // NOP
- #define IMAGE_REL_PPC_ADDR64 0x0001 // 64-bit address
- #define IMAGE_REL_PPC_ADDR32 0x0002 // 32-bit address
- #define IMAGE_REL_PPC_ADDR24 0x0003 // 26-bit address, shifted left 2 (branch absolute)
- #define IMAGE_REL_PPC_ADDR16 0x0004 // 16-bit address
- #define IMAGE_REL_PPC_ADDR14 0x0005 // 16-bit address, shifted left 2 (load doubleword)
- #define IMAGE_REL_PPC_REL24 0x0006 // 26-bit PC-relative offset, shifted left 2 (branch relative)
- #define IMAGE_REL_PPC_REL14 0x0007 // 16-bit PC-relative offset, shifted left 2 (br cond relative)
- #define IMAGE_REL_PPC_TOCREL16 0x0008 // 16-bit offset from TOC base
- #define IMAGE_REL_PPC_TOCREL14 0x0009 // 16-bit offset from TOC base, shifted left 2 (load doubleword)
- #define IMAGE_REL_PPC_ADDR32NB 0x000A // 32-bit addr w/o image base
- #define IMAGE_REL_PPC_SECREL 0x000B // va of containing section (as in an image sectionhdr)
- #define IMAGE_REL_PPC_SECTION 0x000C // sectionheader number
- #define IMAGE_REL_PPC_IFGLUE 0x000D // substitute TOC restore instruction iff symbol is glue code
- #define IMAGE_REL_PPC_IMGLUE 0x000E // symbol is glue code; virtual address is TOC restore instruction
- #define IMAGE_REL_PPC_TYPEMASK 0x00FF // mask to isolate above values in IMAGE_RELOCATION.Type
- // Flag bits in IMAGE_RELOCATION.TYPE
- #define IMAGE_REL_PPC_NEG 0x0100 // subtract reloc value rather than adding it
- #define IMAGE_REL_PPC_BRTAKEN 0x0200 // fix branch prediction bit to predict branch taken
- #define IMAGE_REL_PPC_BRNTAKEN 0x0400 // fix branch prediction bit to predict branch not taken
- #define IMAGE_REL_PPC_TOCDEFN 0x0800 // toc slot defined in file (or, data in toc)
- //
- // Based relocation format.
- //
- typedef struct _IMAGE_BASE_RELOCATION {
- uint32_t VirtualAddress;
- uint32_t SizeOfBlock;
- // uint16_t TypeOffset[1];
- } IMAGE_BASE_RELOCATION, *PIMAGE_BASE_RELOCATION;
- #define IMAGE_SIZEOF_BASE_RELOCATION 8
- //
- // Based relocation types.
- //
- #define IMAGE_REL_BASED_ABSOLUTE 0
- #define IMAGE_REL_BASED_HIGH 1
- #define IMAGE_REL_BASED_LOW 2
- #define IMAGE_REL_BASED_HIGHLOW 3
- #define IMAGE_REL_BASED_HIGHADJ 4
- #define IMAGE_REL_BASED_MIPS_JMPADDR 5
- #define IMAGE_REL_BASED_IA64_IMM64 9
- #define IMAGE_REL_BASED_DIR64 10
- //
- // Line number format.
- //
- typedef struct _IMAGE_LINENUMBER {
- union {
- uint32_t SymbolTableIndex; // Symbol table index of function name if Linenumber is 0.
- uint32_t VirtualAddress; // Virtual address of line number.
- } Type;
- uint16_t Linenumber; // Line number.
- } IMAGE_LINENUMBER;
- #define IMAGE_SIZEOF_LINENUMBER 6
- //
- // Archive format.
- //
- #define IMAGE_ARCHIVE_START_SIZE 8
- #define IMAGE_ARCHIVE_START "!<arch>\n"
- #define IMAGE_ARCHIVE_END "`\n"
- #define IMAGE_ARCHIVE_PAD "\n"
- #define IMAGE_ARCHIVE_LINKER_MEMBER "/ "
- #define IMAGE_ARCHIVE_LONGNAMES_MEMBER "// "
- typedef struct _IMAGE_ARCHIVE_MEMBER_HEADER {
- uint8_t Name[16]; // File member name - `/' terminated.
- uint8_t Date[12]; // File member date - decimal.
- uint8_t UserID[6]; // File member user id - decimal.
- uint8_t GroupID[6]; // File member group id - decimal.
- uint8_t Mode[8]; // File member mode - octal.
- uint8_t Size[10]; // File member size - decimal.
- uint8_t EndHeader[2]; // String to end header.
- } IMAGE_ARCHIVE_MEMBER_HEADER, *PIMAGE_ARCHIVE_MEMBER_HEADER;
- #define IMAGE_SIZEOF_ARCHIVE_MEMBER_HDR 60
- //
- // DLL support.
- //
- //
- // Export Format
- //
- typedef struct _IMAGE_EXPORT_DIRECTORY {
- uint32_t Characteristics;
- uint32_t TimeDateStamp;
- uint16_t MajorVersion;
- uint16_t MinorVersion;
- uint32_t Name;
- uint32_t Base;
- uint32_t NumberOfFunctions;
- uint32_t NumberOfNames;
- uint32_t *AddressOfFunctions;
- uint32_t *AddressOfNames;
- uint32_t *AddressOfNameOrdinals;
- } IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;
- //
- // Import Format
- //
- typedef struct _IMAGE_IMPORT_BY_NAME {
- uint16_t Hint;
- uint8_t Name[1];
- } IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME;
- typedef struct _IMAGE_THUNK_DATA {
- union {
- uint32_t Function;
- uint32_t Ordinal;
- PIMAGE_IMPORT_BY_NAME AddressOfData;
- } u1;
- } IMAGE_THUNK_DATA, *PIMAGE_THUNK_DATA;
- #define IMAGE_ORDINAL_FLAG 0x80000000
- #define IMAGE_SNAP_BY_ORDINAL(Ordinal) ((Ordinal & IMAGE_ORDINAL_FLAG) != 0)
- #define IMAGE_ORDINAL(Ordinal) (Ordinal & 0xffff)
- typedef struct _IMAGE_IMPORT_DESCRIPTOR {
- uint32_t Characteristics;
- uint32_t TimeDateStamp;
- uint32_t ForwarderChain;
- uint32_t Name;
- PIMAGE_THUNK_DATA FirstThunk;
- } IMAGE_IMPORT_DESCRIPTOR, *PIMAGE_IMPORT_DESCRIPTOR;
- #endif
- #ifndef _PCI22_H
- #define _PCI22_H
- /*++
- Copyright (c) 1999 Intel Corporation
- Module Name:
- pci22.h
- Abstract:
- Support for PCI 2.2 standard.
- Revision History
- --*/
- #ifdef SOFT_SDV
- #define PCI_MAX_BUS 1
- #else
- #define PCI_MAX_BUS 255
- #endif
- #define PCI_MAX_DEVICE 31
- #define PCI_MAX_FUNC 7
- //
- // Command
- //
- #define PCI_VGA_PALETTE_SNOOP_DISABLED 0x20
- #pragma pack(1)
- typedef struct {
- uint16_t VendorId;
- uint16_t DeviceId;
- uint16_t Command;
- uint16_t Status;
- uint8_t RevisionID;
- uint8_t ClassCode[3];
- uint8_t CacheLineSize;
- uint8_t LaytencyTimer;
- uint8_t HeaderType;
- uint8_t BIST;
- } PCI_DEVICE_INDEPENDENT_REGION;
- typedef struct {
- uint32_t Bar[6];
- uint32_t CISPtr;
- uint16_t SubsystemVendorID;
- uint16_t SubsystemID;
- uint32_t ExpansionRomBar;
- uint32_t Reserved[2];
- uint8_t InterruptLine;
- uint8_t InterruptPin;
- uint8_t MinGnt;
- uint8_t MaxLat;
- } PCI_DEVICE_HEADER_TYPE_REGION;
- typedef struct {
- PCI_DEVICE_INDEPENDENT_REGION Hdr;
- PCI_DEVICE_HEADER_TYPE_REGION Device;
- } PCI_TYPE00;
- typedef struct {
- uint32_t Bar[2];
- uint8_t PrimaryBus;
- uint8_t SecondaryBus;
- uint8_t SubordinateBus;
- uint8_t SecondaryLatencyTimer;
- uint8_t IoBase;
- uint8_t IoLimit;
- uint16_t SecondaryStatus;
- uint16_t MemoryBase;
- uint16_t MemoryLimit;
- uint16_t PrefetchableMemoryBase;
- uint16_t PrefetchableMemoryLimit;
- uint32_t PrefetchableBaseUpper32;
- uint32_t PrefetchableLimitUpper32;
- uint16_t IoBaseUpper16;
- uint16_t IoLimitUpper16;
- uint32_t Reserved;
- uint32_t ExpansionRomBAR;
- uint8_t InterruptLine;
- uint8_t InterruptPin;
- uint16_t BridgeControl;
- } PCI_BRIDGE_CONTROL_REGISTER;
- #define PCI_CLASS_DISPLAY_CTRL 0x03
- #define PCI_CLASS_VGA 0x00
- #define PCI_CLASS_BRIDGE 0x06
- #define PCI_CLASS_ISA 0x01
- #define PCI_CLASS_ISA_POSITIVE_DECODE 0x80
- #define PCI_CLASS_NETWORK 0x02
- #define PCI_CLASS_ETHERNET 0x00
- #define HEADER_TYPE_DEVICE 0x00
- #define HEADER_TYPE_PCI_TO_PCI_BRIDGE 0x01
- #define HEADER_TYPE_MULTI_FUNCTION 0x80
- #define HEADER_LAYOUT_CODE 0x7f
- #define IS_PCI_BRIDGE(_p) ((((_p)->Hdr.HeaderType) & HEADER_LAYOUT_CODE) == HEADER_TYPE_PCI_TO_PCI_BRIDGE)
- #define IS_PCI_MULTI_FUNC(_p) (((_p)->Hdr.HeaderType) & HEADER_TYPE_MULTI_FUNCTION)
- typedef struct {
- PCI_DEVICE_INDEPENDENT_REGION Hdr;
- PCI_BRIDGE_CONTROL_REGISTER Bridge;
- } PCI_TYPE01;
- typedef struct {
- uint8_t Register;
- uint8_t Function;
- uint8_t Device;
- uint8_t Bus;
- uint8_t Reserved[4];
- } DEFIO_PCI_ADDR;
- typedef struct {
- uint32_t Reg : 8;
- uint32_t Func : 3;
- uint32_t Dev : 5;
- uint32_t Bus : 8;
- uint32_t Reserved: 7;
- uint32_t Enable : 1;
- } PCI_CONFIG_ACCESS_CF8;
- #pragma pack()
- #define EFI_ROOT_BRIDGE_LIST 'eprb'
- typedef struct {
- UINTN Signature;
- uint16_t BridgeNumber;
- uint16_t PrimaryBus;
- uint16_t SubordinateBus;
- EFI_DEVICE_PATH *DevicePath;
- LIST_ENTRY Link;
- } PCI_ROOT_BRIDGE_ENTRY;
- #define PCI_EXPANSION_ROM_HEADER_SIGNATURE 0xaa55
- #define EFI_PCI_EXPANSION_ROM_HEADER_EFISIGNATURE 0x0EF1
- #define PCI_DATA_STRUCTURE_SIGNATURE EFI_SIGNATURE_32('P','C','I','R')
- #pragma pack(1)
- typedef struct {
- uint16_t Signature; // 0xaa55
- uint8_t Reserved[0x16];
- uint16_t PcirOffset;
- } PCI_EXPANSION_ROM_HEADER;
- typedef struct {
- uint16_t Signature; // 0xaa55
- uint16_t InitializationSize;
- uint16_t EfiSignature; // 0x0EF1
- uint16_t EfiSubsystem;
- uint16_t EfiMachineType;
- uint8_t Reserved[0x0A];
- uint16_t EfiImageHeaderOffset;
- uint16_t PcirOffset;
- } EFI_PCI_EXPANSION_ROM_HEADER;
- typedef struct {
- uint32_t Signature; // "PCIR"
- uint16_t VendorId;
- uint16_t DeviceId;
- uint16_t Reserved0;
- uint16_t Length;
- uint8_t Revision;
- uint8_t ClassCode[3];
- uint16_t ImageLength;
- uint16_t CodeRevision;
- uint8_t CodeType;
- uint8_t Indicator;
- uint16_t Reserved1;
- } PCI_DATA_STRUCTURE;
- #pragma pack()
- #endif
- /** Command-line options */
- struct options {
- uint16_t vendor;
- uint16_t device;
- };
- /**
- * Allocate memory
- *
- * @v len Length of memory to allocate
- * @ret ptr Pointer to allocated memory
- */
- static void * xmalloc ( size_t len ) {
- void *ptr;
- ptr = malloc ( len );
- if ( ! ptr ) {
- eprintf ( "Could not allocate %zd bytes\n", len );
- exit ( 1 );
- }
- return ptr;
- }
- /**
- * Get file size
- *
- * @v file File
- * @v len File size
- */
- /*
- static size_t file_size ( FILE *file ) {
- ssize_t len;
- return len;
- }
- */
- /**
- * Read information from PE headers
- *
- * @v pe PE file
- * @ret machine Machine type
- * @ret subsystem EFI subsystem
- */
- static void read_pe_info ( void *pe, uint16_t *machine,
- uint16_t *subsystem ) {
- IMAGE_DOS_HEADER *dos;
- union {
- IMAGE_NT_HEADERS nt64;
- } *nt;
- /* Locate NT header */
- dos = pe;
- nt = ( pe + dos->e_lfanew );
- /* issue 4: TianoCore demands subsystem 10, so we must use EFI_APPLICATION
- * in the PE header. Therefore we force EFI_ROM subsystem in this code here. */
- if(nt->nt64.OptionalHeader.Subsystem == 10)
- nt->nt64.OptionalHeader.Subsystem = 13;
- /* Parse out PE information */
- *machine = nt->nt64.FileHeader.Machine;
- *subsystem = nt->nt64.OptionalHeader.Subsystem;
- }
- /**
- * Convert EFI image to ROM image
- *
- * @v pe EFI file
- * @v rom ROM file
- */
- static void make_efi_rom ( FILE *pe, FILE *rom, struct options *opts ) {
- struct {
- EFI_PCI_EXPANSION_ROM_HEADER rom;
- PCI_DATA_STRUCTURE pci __attribute__ (( aligned ( 4 ) ));
- uint8_t checksum;
- } *headers;
- struct stat pe_stat;
- size_t pe_size;
- size_t rom_size;
- void *buf;
- void *payload;
- unsigned int i;
- uint8_t checksum;
- /* Determine PE file size */
- if ( fstat ( fileno ( pe ), &pe_stat ) != 0 ) {
- eprintf ( "Could not stat PE file: %s\n",
- strerror ( errno ) );
- exit ( 1 );
- }
- pe_size = pe_stat.st_size;
- /* Determine ROM file size */
- rom_size = ( ( pe_size + sizeof ( *headers ) + 511 ) & ~511 );
- /* Allocate ROM buffer and read in PE file */
- buf = xmalloc ( rom_size );
- memset ( buf, 0, rom_size );
- headers = buf;
- payload = ( buf + sizeof ( *headers ) );
- if ( fread ( payload, pe_size, 1, pe ) != 1 ) {
- eprintf ( "Could not read PE file: %s\n",
- strerror ( errno ) );
- exit ( 1 );
- }
- /* Construct ROM header */
- headers->rom.Signature = PCI_EXPANSION_ROM_HEADER_SIGNATURE;
- headers->rom.InitializationSize = ( rom_size / 512 );
- headers->rom.EfiSignature = EFI_PCI_EXPANSION_ROM_HEADER_EFISIGNATURE;
- read_pe_info ( payload, &headers->rom.EfiMachineType,
- &headers->rom.EfiSubsystem );
- headers->rom.EfiImageHeaderOffset = sizeof ( *headers );
- headers->rom.PcirOffset =
- offsetof ( typeof ( *headers ), pci );
- headers->pci.Signature = PCI_DATA_STRUCTURE_SIGNATURE;
- headers->pci.VendorId = opts->vendor ? opts->vendor : 0x8086;
- headers->pci.DeviceId = opts->device ? opts->device : 0x100E;
- headers->pci.Length = sizeof ( headers->pci );
- headers->pci.ClassCode[0] = PCI_CLASS_NETWORK;
- headers->pci.ImageLength = ( rom_size / 512 );
- headers->pci.CodeType = 0x03; /* No constant in EFI headers? */
- headers->pci.Indicator = 0x80; /* No constant in EFI headers? */
- /* Fix image checksum */
- for ( i = 0, checksum = 0 ; i < rom_size ; i++ )
- checksum += *( ( uint8_t * ) buf + i );
- headers->checksum -= checksum;
- /* Write out ROM */
- if ( fwrite ( buf, rom_size, 1, rom ) != 1 ) {
- eprintf ( "Could not write ROM file: %s\n",
- strerror ( errno ) );
- exit ( 1 );
- }
- }
- /**
- * Parse command-line options
- *
- * @v argc Argument count
- * @v argv Argument list
- * @v opts Options structure to populate
- */
- static int parse_options ( const int argc, char **argv,
- struct options *opts ) {
- char *end;
- int c;
- while (1) {
- int option_index = 0;
- static struct option long_options[] = {
- { "vendor", required_argument, NULL, 'v' },
- { "device", required_argument, NULL, 'd' },
- { "help", 0, NULL, 'h' },
- { 0, 0, 0, 0 }
- };
- if ( ( c = getopt_long ( argc, argv, "v:d:h",
- long_options,
- &option_index ) ) == -1 ) {
- break;
- }
- switch ( c ) {
- case 'v':
- opts->vendor = strtoul ( optarg, &end, 16 );
- if ( *end ) {
- eprintf ( "Invalid vendor \"%s\"\n", optarg );
- exit ( 2 );
- }
- break;
- case 'd':
- opts->device = strtoul ( optarg, &end, 16 );
- if ( *end ) {
- eprintf ( "Invalid device \"%s\"\n", optarg );
- exit ( 2 );
- }
- break;
- case 'h':
- print_help ( argv[0] );
- exit ( 0 );
- case '?':
- default:
- exit ( 2 );
- }
- }
- return optind;
- }
- int main ( int argc, char **argv ) {
- struct options opts = {
- };
- unsigned int infile_index;
- const char *infile_name;
- const char *outfile_name;
- FILE *infile;
- FILE *outfile;
- /* Parse command-line arguments */
- infile_index = parse_options ( argc, argv, &opts );
- if ( argc != ( infile_index + 2 ) ) {
- print_help ( argv[0] );
- exit ( 2 );
- }
- infile_name = argv[infile_index];
- outfile_name = argv[infile_index + 1];
- /* Open input and output files */
- infile = fopen ( infile_name, "r" );
- if ( ! infile ) {
- eprintf ( "Could not open %s for reading: %s\n",
- infile_name, strerror ( errno ) );
- exit ( 1 );
- }
- outfile = fopen ( outfile_name, "w" );
- if ( ! outfile ) {
- eprintf ( "Could not open %s for writing: %s\n",
- outfile_name, strerror ( errno ) );
- exit ( 1 );
- }
- /* Convert file */
- make_efi_rom ( infile, outfile, &opts );
- fclose ( outfile );
- fclose ( infile );
- return 0;
- }
|