From f51461c829c124288a930829a78e2a5a799f4039 Mon Sep 17 00:00:00 2001 From: "Gao, Liming" Date: Mon, 27 Jan 2014 05:23:15 +0000 Subject: Sync BaseTool trunk (version r2649) into EDKII BaseTools. Signed-off-by: Gao, Liming git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15188 6f19259b-4bc3-4df7-8a09-765794883524 --- BaseTools/Source/C/GNUmakefile | 174 +- BaseTools/Source/C/GenFw/Elf32Convert.c | 2094 ++++++------- BaseTools/Source/C/GenFw/Elf32Convert.h | 48 +- BaseTools/Source/C/GenFw/Elf64Convert.c | 1866 +++++------ BaseTools/Source/C/GenFw/Elf64Convert.h | 48 +- BaseTools/Source/C/GenFw/ElfConvert.c | 466 +-- BaseTools/Source/C/GenFw/ElfConvert.h | 166 +- BaseTools/Source/C/GenFw/GenFw.h | 110 +- BaseTools/Source/C/GenFw/elf32.h | 516 +-- BaseTools/Source/C/GenFw/elf64.h | 520 +-- BaseTools/Source/C/GenFw/elf_common.h | 2090 ++++++------- BaseTools/Source/C/Include/Arm/ProcessorBind.h | 316 +- BaseTools/Source/C/Include/Common/BuildVersion.h | 2 +- BaseTools/Source/C/Makefiles/NmakeSubdirs.bat | 2 +- BaseTools/Source/C/Makefiles/app.makefile | 54 +- BaseTools/Source/C/Makefiles/footer.makefile | 50 +- BaseTools/Source/C/Makefiles/ms.app | 46 +- BaseTools/Source/C/Makefiles/ms.common | 102 +- BaseTools/Source/C/Makefiles/ms.lib | 44 +- BaseTools/Source/C/Makefiles/ms.rule | 30 +- BaseTools/Source/C/PyEfiCompressor/Makefile | 28 +- BaseTools/Source/C/PyUtility/Makefile | 28 +- BaseTools/Source/C/VfrCompile/VfrFormPkg.cpp | 8 +- BaseTools/Source/C/VfrCompile/VfrFormPkg.h | 28 +- BaseTools/Source/C/VolInfo/VolInfo.c | 3652 +++++++++++----------- BaseTools/Source/C/VolInfo/VolInfo.h | 82 +- 26 files changed, 6285 insertions(+), 6285 deletions(-) (limited to 'BaseTools/Source/C') diff --git a/BaseTools/Source/C/GNUmakefile b/BaseTools/Source/C/GNUmakefile index ae07509496..124517b6c1 100644 --- a/BaseTools/Source/C/GNUmakefile +++ b/BaseTools/Source/C/GNUmakefile @@ -1,87 +1,87 @@ -## @file -# GNU/Linux makefile for C tools build. -# -# Copyright (c) 2007 - 2012, Intel Corporation. All rights reserved.
-# -# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# - -ifndef ARCH - # - # If ARCH is not defined, then we use 'uname -m' to attempt - # try to figure out the appropriate ARCH. - # - uname_m = $(shell uname -m) - $(info Attempting to detect ARCH from 'uname -m': $(uname_m)) - ifeq ($(uname_m),x86_64) - ARCH=X64 - endif - ifeq ($(patsubst i%86,IA32,$(uname_m)),IA32) - ARCH=IA32 - endif - ifndef ARCH - $(info Could not detected ARCH from uname results) - $(error ARCH is not defined!) - endif - $(info Detected ARCH of $(ARCH) using uname.) -endif - -export ARCH - -MAKEROOT = . - -include Makefiles/header.makefile - -all: makerootdir subdirs $(MAKEROOT)/libs - @echo Finished building BaseTools C Tools with ARCH=$(ARCH) - -LIBRARIES = Common -# NON_BUILDABLE_APPLICATIONS = GenBootSector BootSectImage -APPLICATIONS = \ - GnuGenBootSector \ - BootSectImage \ - EfiLdrImage \ - EfiRom \ - GenFfs \ - GenFv \ - GenFw \ - GenPage \ - GenSec \ - GenCrc32 \ - GenVtf \ - LzmaCompress \ - Split \ - TianoCompress \ - VolInfo \ - VfrCompile - -SUBDIRS := $(LIBRARIES) $(APPLICATIONS) - -.PHONY: outputdirs -makerootdir: - -mkdir -p $(MAKEROOT) - -.PHONY: subdirs $(SUBDIRS) -subdirs: $(SUBDIRS) -$(SUBDIRS): - $(MAKE) -C $@ - -.PHONY: $(patsubst %,%-clean,$(sort $(SUBDIRS))) -$(patsubst %,%-clean,$(sort $(SUBDIRS))): - -$(MAKE) -C $(@:-clean=) clean - -clean: $(patsubst %,%-clean,$(sort $(SUBDIRS))) - -clean: localClean - -localClean: - rm -f $(MAKEROOT)/bin/* - -rmdir $(MAKEROOT)/libs $(MAKEROOT)/bin - -include Makefiles/footer.makefile +## @file +# GNU/Linux makefile for C tools build. +# +# Copyright (c) 2007 - 2012, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# + +ifndef ARCH + # + # If ARCH is not defined, then we use 'uname -m' to attempt + # try to figure out the appropriate ARCH. + # + uname_m = $(shell uname -m) + $(info Attempting to detect ARCH from 'uname -m': $(uname_m)) + ifeq ($(uname_m),x86_64) + ARCH=X64 + endif + ifeq ($(patsubst i%86,IA32,$(uname_m)),IA32) + ARCH=IA32 + endif + ifndef ARCH + $(info Could not detected ARCH from uname results) + $(error ARCH is not defined!) + endif + $(info Detected ARCH of $(ARCH) using uname.) +endif + +export ARCH + +MAKEROOT = . + +include Makefiles/header.makefile + +all: makerootdir subdirs $(MAKEROOT)/libs + @echo Finished building BaseTools C Tools with ARCH=$(ARCH) + +LIBRARIES = Common +# NON_BUILDABLE_APPLICATIONS = GenBootSector BootSectImage +APPLICATIONS = \ + GnuGenBootSector \ + BootSectImage \ + EfiLdrImage \ + EfiRom \ + GenFfs \ + GenFv \ + GenFw \ + GenPage \ + GenSec \ + GenCrc32 \ + GenVtf \ + LzmaCompress \ + Split \ + TianoCompress \ + VolInfo \ + VfrCompile + +SUBDIRS := $(LIBRARIES) $(APPLICATIONS) + +.PHONY: outputdirs +makerootdir: + -mkdir -p $(MAKEROOT) + +.PHONY: subdirs $(SUBDIRS) +subdirs: $(SUBDIRS) +$(SUBDIRS): + $(MAKE) -C $@ + +.PHONY: $(patsubst %,%-clean,$(sort $(SUBDIRS))) +$(patsubst %,%-clean,$(sort $(SUBDIRS))): + -$(MAKE) -C $(@:-clean=) clean + +clean: $(patsubst %,%-clean,$(sort $(SUBDIRS))) + +clean: localClean + +localClean: + rm -f $(MAKEROOT)/bin/* + -rmdir $(MAKEROOT)/libs $(MAKEROOT)/bin + +include Makefiles/footer.makefile diff --git a/BaseTools/Source/C/GenFw/Elf32Convert.c b/BaseTools/Source/C/GenFw/Elf32Convert.c index 58ac333888..97c9380c8d 100644 --- a/BaseTools/Source/C/GenFw/Elf32Convert.c +++ b/BaseTools/Source/C/GenFw/Elf32Convert.c @@ -1,1047 +1,1047 @@ -/** @file - -Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.
-Portions copyright (c) 2013, ARM Ltd. All rights reserved.
- -This program and the accompanying materials are licensed and made available -under the terms and conditions of the BSD License which accompanies this -distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "WinNtInclude.h" - -#ifndef __GNUC__ -#include -#include -#endif -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "PeCoffLib.h" -#include "EfiUtilityMsgs.h" - -#include "GenFw.h" -#include "ElfConvert.h" -#include "Elf32Convert.h" - -STATIC -VOID -ScanSections32 ( - VOID - ); - -STATIC -BOOLEAN -WriteSections32 ( - SECTION_FILTER_TYPES FilterType - ); - -STATIC -VOID -WriteRelocations32 ( - VOID - ); - -STATIC -VOID -WriteDebug32 ( - VOID - ); - -STATIC -VOID -SetImageSize32 ( - VOID - ); - -STATIC -VOID -CleanUp32 ( - VOID - ); - -// -// Rename ELF32 strucutres to common names to help when porting to ELF64. -// -typedef Elf32_Shdr Elf_Shdr; -typedef Elf32_Ehdr Elf_Ehdr; -typedef Elf32_Rel Elf_Rel; -typedef Elf32_Sym Elf_Sym; -typedef Elf32_Phdr Elf_Phdr; -typedef Elf32_Dyn Elf_Dyn; -#define ELFCLASS ELFCLASS32 -#define ELF_R_TYPE(r) ELF32_R_TYPE(r) -#define ELF_R_SYM(r) ELF32_R_SYM(r) - -// -// Well known ELF structures. -// -STATIC Elf_Ehdr *mEhdr; -STATIC Elf_Shdr *mShdrBase; -STATIC Elf_Phdr *mPhdrBase; - -// -// Coff information -// -STATIC const UINT32 mCoffAlignment = 0x20; - -// -// PE section alignment. -// -STATIC const UINT16 mCoffNbrSections = 5; - -// -// ELF sections to offset in Coff file. -// -STATIC UINT32 *mCoffSectionsOffset = NULL; - -// -// Offsets in COFF file -// -STATIC UINT32 mNtHdrOffset; -STATIC UINT32 mTextOffset; -STATIC UINT32 mDataOffset; -STATIC UINT32 mHiiRsrcOffset; -STATIC UINT32 mRelocOffset; - -// -// Initialization Function -// -BOOLEAN -InitializeElf32 ( - UINT8 *FileBuffer, - ELF_FUNCTION_TABLE *ElfFunctions - ) -{ - // - // Initialize data pointer and structures. - // - mEhdr = (Elf_Ehdr*) FileBuffer; - - // - // Check the ELF32 specific header information. - // - if (mEhdr->e_ident[EI_CLASS] != ELFCLASS32) { - Error (NULL, 0, 3000, "Unsupported", "ELF EI_DATA not ELFCLASS32"); - return FALSE; - } - if (mEhdr->e_ident[EI_DATA] != ELFDATA2LSB) { - Error (NULL, 0, 3000, "Unsupported", "ELF EI_DATA not ELFDATA2LSB"); - return FALSE; - } - if ((mEhdr->e_type != ET_EXEC) && (mEhdr->e_type != ET_DYN)) { - Error (NULL, 0, 3000, "Unsupported", "ELF e_type not ET_EXEC or ET_DYN"); - return FALSE; - } - if (!((mEhdr->e_machine == EM_386) || (mEhdr->e_machine == EM_ARM))) { - Error (NULL, 0, 3000, "Unsupported", "ELF e_machine not EM_386 or EM_ARM"); - return FALSE; - } - if (mEhdr->e_version != EV_CURRENT) { - Error (NULL, 0, 3000, "Unsupported", "ELF e_version (%u) not EV_CURRENT (%d)", (unsigned) mEhdr->e_version, EV_CURRENT); - return FALSE; - } - - // - // Update section header pointers - // - mShdrBase = (Elf_Shdr *)((UINT8 *)mEhdr + mEhdr->e_shoff); - mPhdrBase = (Elf_Phdr *)((UINT8 *)mEhdr + mEhdr->e_phoff); - - // - // Create COFF Section offset buffer and zero. - // - mCoffSectionsOffset = (UINT32 *)malloc(mEhdr->e_shnum * sizeof (UINT32)); - memset(mCoffSectionsOffset, 0, mEhdr->e_shnum * sizeof(UINT32)); - - // - // Fill in function pointers. - // - ElfFunctions->ScanSections = ScanSections32; - ElfFunctions->WriteSections = WriteSections32; - ElfFunctions->WriteRelocations = WriteRelocations32; - ElfFunctions->WriteDebug = WriteDebug32; - ElfFunctions->SetImageSize = SetImageSize32; - ElfFunctions->CleanUp = CleanUp32; - - return TRUE; -} - - -// -// Header by Index functions -// -STATIC -Elf_Shdr* -GetShdrByIndex ( - UINT32 Num - ) -{ - if (Num >= mEhdr->e_shnum) - return NULL; - return (Elf_Shdr*)((UINT8*)mShdrBase + Num * mEhdr->e_shentsize); -} - -STATIC -Elf_Phdr* -GetPhdrByIndex ( - UINT32 num - ) -{ - if (num >= mEhdr->e_phnum) { - return NULL; - } - - return (Elf_Phdr *)((UINT8*)mPhdrBase + num * mEhdr->e_phentsize); -} - -STATIC -UINT32 -CoffAlign ( - UINT32 Offset - ) -{ - return (Offset + mCoffAlignment - 1) & ~(mCoffAlignment - 1); -} - -// -// filter functions -// -STATIC -BOOLEAN -IsTextShdr ( - Elf_Shdr *Shdr - ) -{ - return (BOOLEAN) ((Shdr->sh_flags & (SHF_WRITE | SHF_ALLOC)) == SHF_ALLOC); -} - -STATIC -BOOLEAN -IsHiiRsrcShdr ( - Elf_Shdr *Shdr - ) -{ - Elf_Shdr *Namedr = GetShdrByIndex(mEhdr->e_shstrndx); - - return (BOOLEAN) (strcmp((CHAR8*)mEhdr + Namedr->sh_offset + Shdr->sh_name, ELF_HII_SECTION_NAME) == 0); -} - -STATIC -BOOLEAN -IsDataShdr ( - Elf_Shdr *Shdr - ) -{ - if (IsHiiRsrcShdr(Shdr)) { - return FALSE; - } - return (BOOLEAN) (Shdr->sh_flags & (SHF_WRITE | SHF_ALLOC)) == (SHF_ALLOC | SHF_WRITE); -} - -// -// Elf functions interface implementation -// - -STATIC -VOID -ScanSections32 ( - VOID - ) -{ - UINT32 i; - EFI_IMAGE_DOS_HEADER *DosHdr; - EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr; - UINT32 CoffEntry; - UINT32 SectionCount; - BOOLEAN FoundText; - - CoffEntry = 0; - mCoffOffset = 0; - mTextOffset = 0; - FoundText = FALSE; - - // - // Coff file start with a DOS header. - // - mCoffOffset = sizeof(EFI_IMAGE_DOS_HEADER) + 0x40; - mNtHdrOffset = mCoffOffset; - switch (mEhdr->e_machine) { - case EM_386: - case EM_ARM: - mCoffOffset += sizeof (EFI_IMAGE_NT_HEADERS32); - break; - default: - VerboseMsg ("%s unknown e_machine type. Assume IA-32", (UINTN)mEhdr->e_machine); - mCoffOffset += sizeof (EFI_IMAGE_NT_HEADERS32); - break; - } - - mTableOffset = mCoffOffset; - mCoffOffset += mCoffNbrSections * sizeof(EFI_IMAGE_SECTION_HEADER); - - // - // First text sections. - // - mCoffOffset = CoffAlign(mCoffOffset); - SectionCount = 0; - for (i = 0; i < mEhdr->e_shnum; i++) { - Elf_Shdr *shdr = GetShdrByIndex(i); - if (IsTextShdr(shdr)) { - if ((shdr->sh_addralign != 0) && (shdr->sh_addralign != 1)) { - // the alignment field is valid - if ((shdr->sh_addr & (shdr->sh_addralign - 1)) == 0) { - // if the section address is aligned we must align PE/COFF - mCoffOffset = (mCoffOffset + shdr->sh_addralign - 1) & ~(shdr->sh_addralign - 1); - } else if ((shdr->sh_addr % shdr->sh_addralign) != (mCoffOffset % shdr->sh_addralign)) { - // ARM RVCT tools have behavior outside of the ELF specification to try - // and make images smaller. If sh_addr is not aligned to sh_addralign - // then the section needs to preserve sh_addr MOD sh_addralign. - // Normally doing nothing here works great. - Error (NULL, 0, 3000, "Invalid", "Unsupported section alignment."); - } - } - - /* Relocate entry. */ - if ((mEhdr->e_entry >= shdr->sh_addr) && - (mEhdr->e_entry < shdr->sh_addr + shdr->sh_size)) { - CoffEntry = mCoffOffset + mEhdr->e_entry - shdr->sh_addr; - } - - // - // Set mTextOffset with the offset of the first '.text' section - // - if (!FoundText) { - mTextOffset = mCoffOffset; - FoundText = TRUE; - } - - mCoffSectionsOffset[i] = mCoffOffset; - mCoffOffset += shdr->sh_size; - SectionCount ++; - } - } - - if (!FoundText) { - Error (NULL, 0, 3000, "Invalid", "Did not find any '.text' section."); - assert (FALSE); - } - - if (mEhdr->e_machine != EM_ARM) { - mCoffOffset = CoffAlign(mCoffOffset); - } - - if (SectionCount > 1 && mOutImageType == FW_EFI_IMAGE) { - Warning (NULL, 0, 0, NULL, "Mulitple sections in %s are merged into 1 text section. Source level debug might not work correctly.", mInImageName); - } - - // - // Then data sections. - // - mDataOffset = mCoffOffset; - SectionCount = 0; - for (i = 0; i < mEhdr->e_shnum; i++) { - Elf_Shdr *shdr = GetShdrByIndex(i); - if (IsDataShdr(shdr)) { - if ((shdr->sh_addralign != 0) && (shdr->sh_addralign != 1)) { - // the alignment field is valid - if ((shdr->sh_addr & (shdr->sh_addralign - 1)) == 0) { - // if the section address is aligned we must align PE/COFF - mCoffOffset = (mCoffOffset + shdr->sh_addralign - 1) & ~(shdr->sh_addralign - 1); - } else if ((shdr->sh_addr % shdr->sh_addralign) != (mCoffOffset % shdr->sh_addralign)) { - // ARM RVCT tools have behavior outside of the ELF specification to try - // and make images smaller. If sh_addr is not aligned to sh_addralign - // then the section needs to preserve sh_addr MOD sh_addralign. - // Normally doing nothing here works great. - Error (NULL, 0, 3000, "Invalid", "Unsupported section alignment."); - } - } - mCoffSectionsOffset[i] = mCoffOffset; - mCoffOffset += shdr->sh_size; - SectionCount ++; - } - } - mCoffOffset = CoffAlign(mCoffOffset); - - if (SectionCount > 1 && mOutImageType == FW_EFI_IMAGE) { - Warning (NULL, 0, 0, NULL, "Mulitple sections in %s are merged into 1 data section. Source level debug might not work correctly.", mInImageName); - } - - // - // The HII resource sections. - // - mHiiRsrcOffset = mCoffOffset; - for (i = 0; i < mEhdr->e_shnum; i++) { - Elf_Shdr *shdr = GetShdrByIndex(i); - if (IsHiiRsrcShdr(shdr)) { - if ((shdr->sh_addralign != 0) && (shdr->sh_addralign != 1)) { - // the alignment field is valid - if ((shdr->sh_addr & (shdr->sh_addralign - 1)) == 0) { - // if the section address is aligned we must align PE/COFF - mCoffOffset = (mCoffOffset + shdr->sh_addralign - 1) & ~(shdr->sh_addralign - 1); - } else if ((shdr->sh_addr % shdr->sh_addralign) != (mCoffOffset % shdr->sh_addralign)) { - // ARM RVCT tools have behavior outside of the ELF specification to try - // and make images smaller. If sh_addr is not aligned to sh_addralign - // then the section needs to preserve sh_addr MOD sh_addralign. - // Normally doing nothing here works great. - Error (NULL, 0, 3000, "Invalid", "Unsupported section alignment."); - } - } - if (shdr->sh_size != 0) { - mCoffSectionsOffset[i] = mCoffOffset; - mCoffOffset += shdr->sh_size; - mCoffOffset = CoffAlign(mCoffOffset); - SetHiiResourceHeader ((UINT8*) mEhdr + shdr->sh_offset, mHiiRsrcOffset); - } - break; - } - } - - mRelocOffset = mCoffOffset; - - // - // Allocate base Coff file. Will be expanded later for relocations. - // - mCoffFile = (UINT8 *)malloc(mCoffOffset); - memset(mCoffFile, 0, mCoffOffset); - - // - // Fill headers. - // - DosHdr = (EFI_IMAGE_DOS_HEADER *)mCoffFile; - DosHdr->e_magic = EFI_IMAGE_DOS_SIGNATURE; - DosHdr->e_lfanew = mNtHdrOffset; - - NtHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION*)(mCoffFile + mNtHdrOffset); - - NtHdr->Pe32.Signature = EFI_IMAGE_NT_SIGNATURE; - - switch (mEhdr->e_machine) { - case EM_386: - NtHdr->Pe32.FileHeader.Machine = EFI_IMAGE_MACHINE_IA32; - NtHdr->Pe32.OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC; - break; - case EM_ARM: - NtHdr->Pe32.FileHeader.Machine = EFI_IMAGE_MACHINE_ARMT; - NtHdr->Pe32.OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC; - break; - default: - VerboseMsg ("%s unknown e_machine type. Assume IA-32", (UINTN)mEhdr->e_machine); - NtHdr->Pe32.FileHeader.Machine = EFI_IMAGE_MACHINE_IA32; - NtHdr->Pe32.OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC; - } - - NtHdr->Pe32.FileHeader.NumberOfSections = mCoffNbrSections; - NtHdr->Pe32.FileHeader.TimeDateStamp = (UINT32) time(NULL); - mImageTimeStamp = NtHdr->Pe32.FileHeader.TimeDateStamp; - NtHdr->Pe32.FileHeader.PointerToSymbolTable = 0; - NtHdr->Pe32.FileHeader.NumberOfSymbols = 0; - NtHdr->Pe32.FileHeader.SizeOfOptionalHeader = sizeof(NtHdr->Pe32.OptionalHeader); - NtHdr->Pe32.FileHeader.Characteristics = EFI_IMAGE_FILE_EXECUTABLE_IMAGE - | EFI_IMAGE_FILE_LINE_NUMS_STRIPPED - | EFI_IMAGE_FILE_LOCAL_SYMS_STRIPPED - | EFI_IMAGE_FILE_32BIT_MACHINE; - - NtHdr->Pe32.OptionalHeader.SizeOfCode = mDataOffset - mTextOffset; - NtHdr->Pe32.OptionalHeader.SizeOfInitializedData = mRelocOffset - mDataOffset; - NtHdr->Pe32.OptionalHeader.SizeOfUninitializedData = 0; - NtHdr->Pe32.OptionalHeader.AddressOfEntryPoint = CoffEntry; - - NtHdr->Pe32.OptionalHeader.BaseOfCode = mTextOffset; - - NtHdr->Pe32.OptionalHeader.BaseOfData = mDataOffset; - NtHdr->Pe32.OptionalHeader.ImageBase = 0; - NtHdr->Pe32.OptionalHeader.SectionAlignment = mCoffAlignment; - NtHdr->Pe32.OptionalHeader.FileAlignment = mCoffAlignment; - NtHdr->Pe32.OptionalHeader.SizeOfImage = 0; - - NtHdr->Pe32.OptionalHeader.SizeOfHeaders = mTextOffset; - NtHdr->Pe32.OptionalHeader.NumberOfRvaAndSizes = EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES; - - // - // Section headers. - // - if ((mDataOffset - mTextOffset) > 0) { - CreateSectionHeader (".text", mTextOffset, mDataOffset - mTextOffset, - EFI_IMAGE_SCN_CNT_CODE - | EFI_IMAGE_SCN_MEM_EXECUTE - | EFI_IMAGE_SCN_MEM_READ); - } else { - // Don't make a section of size 0. - NtHdr->Pe32.FileHeader.NumberOfSections--; - } - - if ((mHiiRsrcOffset - mDataOffset) > 0) { - CreateSectionHeader (".data", mDataOffset, mHiiRsrcOffset - mDataOffset, - EFI_IMAGE_SCN_CNT_INITIALIZED_DATA - | EFI_IMAGE_SCN_MEM_WRITE - | EFI_IMAGE_SCN_MEM_READ); - } else { - // Don't make a section of size 0. - NtHdr->Pe32.FileHeader.NumberOfSections--; - } - - if ((mRelocOffset - mHiiRsrcOffset) > 0) { - CreateSectionHeader (".rsrc", mHiiRsrcOffset, mRelocOffset - mHiiRsrcOffset, - EFI_IMAGE_SCN_CNT_INITIALIZED_DATA - | EFI_IMAGE_SCN_MEM_READ); - - NtHdr->Pe32.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].Size = mRelocOffset - mHiiRsrcOffset; - NtHdr->Pe32.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress = mHiiRsrcOffset; - } else { - // Don't make a section of size 0. - NtHdr->Pe32.FileHeader.NumberOfSections--; - } - -} - -STATIC -BOOLEAN -WriteSections32 ( - SECTION_FILTER_TYPES FilterType - ) -{ - UINT32 Idx; - Elf_Shdr *SecShdr; - UINT32 SecOffset; - BOOLEAN (*Filter)(Elf_Shdr *); - - // - // Initialize filter pointer - // - switch (FilterType) { - case SECTION_TEXT: - Filter = IsTextShdr; - break; - case SECTION_HII: - Filter = IsHiiRsrcShdr; - break; - case SECTION_DATA: - Filter = IsDataShdr; - break; - default: - return FALSE; - } - - // - // First: copy sections. - // - for (Idx = 0; Idx < mEhdr->e_shnum; Idx++) { - Elf_Shdr *Shdr = GetShdrByIndex(Idx); - if ((*Filter)(Shdr)) { - switch (Shdr->sh_type) { - case SHT_PROGBITS: - /* Copy. */ - memcpy(mCoffFile + mCoffSectionsOffset[Idx], - (UINT8*)mEhdr + Shdr->sh_offset, - Shdr->sh_size); - break; - - case SHT_NOBITS: - memset(mCoffFile + mCoffSectionsOffset[Idx], 0, Shdr->sh_size); - break; - - default: - // - // Ignore for unkown section type. - // - VerboseMsg ("%s unknown section type %x. We directly copy this section into Coff file", mInImageName, (unsigned)Shdr->sh_type); - break; - } - } - } - - // - // Second: apply relocations. - // - for (Idx = 0; Idx < mEhdr->e_shnum; Idx++) { - // - // Determine if this is a relocation section. - // - Elf_Shdr *RelShdr = GetShdrByIndex(Idx); - if ((RelShdr->sh_type != SHT_REL) && (RelShdr->sh_type != SHT_RELA)) { - continue; - } - - // - // Relocation section found. Now extract section information that the relocations - // apply to in the ELF data and the new COFF data. - // - SecShdr = GetShdrByIndex(RelShdr->sh_info); - SecOffset = mCoffSectionsOffset[RelShdr->sh_info]; - - // - // Only process relocations for the current filter type. - // - if (RelShdr->sh_type == SHT_REL && (*Filter)(SecShdr)) { - UINT32 RelOffset; - - // - // Determine the symbol table referenced by the relocation data. - // - Elf_Shdr *SymtabShdr = GetShdrByIndex(RelShdr->sh_link); - UINT8 *Symtab = (UINT8*)mEhdr + SymtabShdr->sh_offset; - - // - // Process all relocation entries for this section. - // - for (RelOffset = 0; RelOffset < RelShdr->sh_size; RelOffset += RelShdr->sh_entsize) { - // - // Set pointer to relocation entry - // - Elf_Rel *Rel = (Elf_Rel *)((UINT8*)mEhdr + RelShdr->sh_offset + RelOffset); - - // - // Set pointer to symbol table entry associated with the relocation entry. - // - Elf_Sym *Sym = (Elf_Sym *)(Symtab + ELF_R_SYM(Rel->r_info) * SymtabShdr->sh_entsize); - - Elf_Shdr *SymShdr; - UINT8 *Targ; - UINT16 Address; - - // - // Check section header index found in symbol table and get the section - // header location. - // - if (Sym->st_shndx == SHN_UNDEF - || Sym->st_shndx == SHN_ABS - || Sym->st_shndx > mEhdr->e_shnum) { - Error (NULL, 0, 3000, "Invalid", "%s bad symbol definition.", mInImageName); - } - SymShdr = GetShdrByIndex(Sym->st_shndx); - - // - // Convert the relocation data to a pointer into the coff file. - // - // Note: - // r_offset is the virtual address of the storage unit to be relocated. - // sh_addr is the virtual address for the base of the section. - // - Targ = mCoffFile + SecOffset + (Rel->r_offset - SecShdr->sh_addr); - - // - // Determine how to handle each relocation type based on the machine type. - // - if (mEhdr->e_machine == EM_386) { - switch (ELF_R_TYPE(Rel->r_info)) { - case R_386_NONE: - break; - case R_386_32: - // - // Absolute relocation. - // Converts Targ from a absolute virtual address to the absolute - // COFF address. - // - *(UINT32 *)Targ = *(UINT32 *)Targ - SymShdr->sh_addr - + mCoffSectionsOffset[Sym->st_shndx]; - break; - case R_386_PC32: - // - // Relative relocation: Symbol - Ip + Addend - // - *(UINT32 *)Targ = *(UINT32 *)Targ - + (mCoffSectionsOffset[Sym->st_shndx] - SymShdr->sh_addr) - - (SecOffset - SecShdr->sh_addr); - break; - default: - Error (NULL, 0, 3000, "Invalid", "%s unsupported ELF EM_386 relocation 0x%x.", mInImageName, (unsigned) ELF_R_TYPE(Rel->r_info)); - } - } else if (mEhdr->e_machine == EM_ARM) { - switch (ELF32_R_TYPE(Rel->r_info)) { - case R_ARM_RBASE: - // No relocation - no action required - // break skipped - - case R_ARM_PC24: - case R_ARM_XPC25: - case R_ARM_THM_PC22: - case R_ARM_THM_JUMP19: - case R_ARM_CALL: - case R_ARM_JMP24: - case R_ARM_THM_JUMP24: - case R_ARM_PREL31: - case R_ARM_MOVW_PREL_NC: - case R_ARM_MOVT_PREL: - case R_ARM_THM_MOVW_PREL_NC: - case R_ARM_THM_MOVT_PREL: - case R_ARM_THM_JMP6: - case R_ARM_THM_ALU_PREL_11_0: - case R_ARM_THM_PC12: - case R_ARM_REL32_NOI: - case R_ARM_ALU_PC_G0_NC: - case R_ARM_ALU_PC_G0: - case R_ARM_ALU_PC_G1_NC: - case R_ARM_ALU_PC_G1: - case R_ARM_ALU_PC_G2: - case R_ARM_LDR_PC_G1: - case R_ARM_LDR_PC_G2: - case R_ARM_LDRS_PC_G0: - case R_ARM_LDRS_PC_G1: - case R_ARM_LDRS_PC_G2: - case R_ARM_LDC_PC_G0: - case R_ARM_LDC_PC_G1: - case R_ARM_LDC_PC_G2: - case R_ARM_GOT_PREL: - case R_ARM_THM_JUMP11: - case R_ARM_THM_JUMP8: - case R_ARM_TLS_GD32: - case R_ARM_TLS_LDM32: - case R_ARM_TLS_IE32: - // Thease are all PC-relative relocations and don't require modification - // GCC does not seem to have the concept of a application that just needs to get relocated. - break; - - case R_ARM_THM_MOVW_ABS_NC: - // MOVW is only lower 16-bits of the addres - Address = (UINT16)(Sym->st_value - SymShdr->sh_addr + mCoffSectionsOffset[Sym->st_shndx]); - ThumbMovtImmediatePatch ((UINT16 *)Targ, Address); - break; - - case R_ARM_THM_MOVT_ABS: - // MOVT is only upper 16-bits of the addres - Address = (UINT16)((Sym->st_value - SymShdr->sh_addr + mCoffSectionsOffset[Sym->st_shndx]) >> 16); - ThumbMovtImmediatePatch ((UINT16 *)Targ, Address); - break; - - case R_ARM_ABS32: - case R_ARM_RABS32: - // - // Absolute relocation. - // - *(UINT32 *)Targ = *(UINT32 *)Targ - SymShdr->sh_addr + mCoffSectionsOffset[Sym->st_shndx]; - break; - - default: - Error (NULL, 0, 3000, "Invalid", "WriteSections (): %s unsupported ELF EM_ARM relocation 0x%x.", mInImageName, (unsigned) ELF32_R_TYPE(Rel->r_info)); - } - } - } - } - } - - return TRUE; -} - -UINTN gMovwOffset = 0; - -STATIC -VOID -WriteRelocations32 ( - VOID - ) -{ - UINT32 Index; - EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr; - EFI_IMAGE_DATA_DIRECTORY *Dir; - BOOLEAN FoundRelocations; - Elf_Dyn *Dyn; - Elf_Rel *Rel; - UINTN RelElementSize; - UINTN RelSize; - UINTN RelOffset; - UINTN K; - UINT8 *Targ; - Elf32_Phdr *DynamicSegment; - Elf32_Phdr *TargetSegment; - - for (Index = 0, FoundRelocations = FALSE; Index < mEhdr->e_shnum; Index++) { - Elf_Shdr *RelShdr = GetShdrByIndex(Index); - if ((RelShdr->sh_type == SHT_REL) || (RelShdr->sh_type == SHT_RELA)) { - Elf_Shdr *SecShdr = GetShdrByIndex (RelShdr->sh_info); - if (IsTextShdr(SecShdr) || IsDataShdr(SecShdr)) { - UINT32 RelIdx; - - FoundRelocations = TRUE; - for (RelIdx = 0; RelIdx < RelShdr->sh_size; RelIdx += RelShdr->sh_entsize) { - Elf_Rel *Rel = (Elf_Rel *)((UINT8*)mEhdr + RelShdr->sh_offset + RelIdx); - - if (mEhdr->e_machine == EM_386) { - switch (ELF_R_TYPE(Rel->r_info)) { - case R_386_NONE: - case R_386_PC32: - // - // No fixup entry required. - // - break; - case R_386_32: - // - // Creates a relative relocation entry from the absolute entry. - // - CoffAddFixup(mCoffSectionsOffset[RelShdr->sh_info] - + (Rel->r_offset - SecShdr->sh_addr), - EFI_IMAGE_REL_BASED_HIGHLOW); - break; - default: - Error (NULL, 0, 3000, "Invalid", "%s unsupported ELF EM_386 relocation 0x%x.", mInImageName, (unsigned) ELF_R_TYPE(Rel->r_info)); - } - } else if (mEhdr->e_machine == EM_ARM) { - switch (ELF32_R_TYPE(Rel->r_info)) { - case R_ARM_RBASE: - // No relocation - no action required - // break skipped - - case R_ARM_PC24: - case R_ARM_XPC25: - case R_ARM_THM_PC22: - case R_ARM_THM_JUMP19: - case R_ARM_CALL: - case R_ARM_JMP24: - case R_ARM_THM_JUMP24: - case R_ARM_PREL31: - case R_ARM_MOVW_PREL_NC: - case R_ARM_MOVT_PREL: - case R_ARM_THM_MOVW_PREL_NC: - case R_ARM_THM_MOVT_PREL: - case R_ARM_THM_JMP6: - case R_ARM_THM_ALU_PREL_11_0: - case R_ARM_THM_PC12: - case R_ARM_REL32_NOI: - case R_ARM_ALU_PC_G0_NC: - case R_ARM_ALU_PC_G0: - case R_ARM_ALU_PC_G1_NC: - case R_ARM_ALU_PC_G1: - case R_ARM_ALU_PC_G2: - case R_ARM_LDR_PC_G1: - case R_ARM_LDR_PC_G2: - case R_ARM_LDRS_PC_G0: - case R_ARM_LDRS_PC_G1: - case R_ARM_LDRS_PC_G2: - case R_ARM_LDC_PC_G0: - case R_ARM_LDC_PC_G1: - case R_ARM_LDC_PC_G2: - case R_ARM_GOT_PREL: - case R_ARM_THM_JUMP11: - case R_ARM_THM_JUMP8: - case R_ARM_TLS_GD32: - case R_ARM_TLS_LDM32: - case R_ARM_TLS_IE32: - // Thease are all PC-relative relocations and don't require modification - break; - - case R_ARM_THM_MOVW_ABS_NC: - CoffAddFixup ( - mCoffSectionsOffset[RelShdr->sh_info] - + (Rel->r_offset - SecShdr->sh_addr), - EFI_IMAGE_REL_BASED_ARM_MOV32T - ); - - // PE/COFF treats MOVW/MOVT relocation as single 64-bit instruction - // Track this address so we can log an error for unsupported sequence of MOVW/MOVT - gMovwOffset = mCoffSectionsOffset[RelShdr->sh_info] + (Rel->r_offset - SecShdr->sh_addr); - break; - - case R_ARM_THM_MOVT_ABS: - if ((gMovwOffset + 4) != (mCoffSectionsOffset[RelShdr->sh_info] + (Rel->r_offset - SecShdr->sh_addr))) { - Error (NULL, 0, 3000, "Not Supported", "PE/COFF requires MOVW+MOVT instruction sequence %x +4 != %x.", gMovwOffset, mCoffSectionsOffset[RelShdr->sh_info] + (Rel->r_offset - SecShdr->sh_addr)); - } - break; - - case R_ARM_ABS32: - case R_ARM_RABS32: - CoffAddFixup ( - mCoffSectionsOffset[RelShdr->sh_info] - + (Rel->r_offset - SecShdr->sh_addr), - EFI_IMAGE_REL_BASED_HIGHLOW - ); - break; - - default: - Error (NULL, 0, 3000, "Invalid", "WriteRelocations(): %s unsupported ELF EM_ARM relocation 0x%x.", mInImageName, (unsigned) ELF32_R_TYPE(Rel->r_info)); - } - } else { - Error (NULL, 0, 3000, "Not Supported", "This tool does not support relocations for ELF with e_machine %u (processor type).", (unsigned) mEhdr->e_machine); - } - } - } - } - } - - if (!FoundRelocations && (mEhdr->e_machine == EM_ARM)) { - /* Try again, but look for PT_DYNAMIC instead of SHT_REL */ - - for (Index = 0; Index < mEhdr->e_phnum; Index++) { - RelElementSize = 0; - RelSize = 0; - RelOffset = 0; - - DynamicSegment = GetPhdrByIndex (Index); - - if (DynamicSegment->p_type == PT_DYNAMIC) { - Dyn = (Elf32_Dyn *) ((UINT8 *)mEhdr + DynamicSegment->p_offset); - - while (Dyn->d_tag != DT_NULL) { - switch (Dyn->d_tag) { - case DT_REL: - RelOffset = Dyn->d_un.d_val; - break; - - case DT_RELSZ: - RelSize = Dyn->d_un.d_val; - break; - - case DT_RELENT: - RelElementSize = Dyn->d_un.d_val; - break; - - default: - break; - } - Dyn++; - } - if (( RelOffset == 0 ) || ( RelSize == 0 ) || ( RelElementSize == 0 )) { - Error (NULL, 0, 3000, "Invalid", "%s bad ARM dynamic relocations.", mInImageName); - } - - for (K = 0; K < RelSize; K += RelElementSize) { - - if (DynamicSegment->p_paddr == 0) { - // Older versions of the ARM ELF (SWS ESPC 0003 B-02) specification define DT_REL - // as an offset in the dynamic segment. p_paddr is defined to be zero for ARM tools - Rel = (Elf32_Rel *) ((UINT8 *) mEhdr + DynamicSegment->p_offset + RelOffset + K); - } else { - // This is how it reads in the generic ELF specification - Rel = (Elf32_Rel *) ((UINT8 *) mEhdr + RelOffset + K); - } - - switch (ELF32_R_TYPE (Rel->r_info)) { - case R_ARM_RBASE: - break; - - case R_ARM_RABS32: - TargetSegment = GetPhdrByIndex (ELF32_R_SYM (Rel->r_info) - 1); - - // Note: r_offset in a memory address. Convert it to a pointer in the coff file. - Targ = mCoffFile + mCoffSectionsOffset[ ELF32_R_SYM( Rel->r_info ) ] + Rel->r_offset - TargetSegment->p_vaddr; - - *(UINT32 *)Targ = *(UINT32 *)Targ + mCoffSectionsOffset [ELF32_R_SYM( Rel->r_info )]; - - CoffAddFixup (mCoffSectionsOffset[ELF32_R_SYM (Rel->r_info)] + (Rel->r_offset - TargetSegment->p_vaddr), EFI_IMAGE_REL_BASED_HIGHLOW); - break; - - default: - Error (NULL, 0, 3000, "Invalid", "%s bad ARM dynamic relocations, unkown type %d.", mInImageName, ELF32_R_TYPE (Rel->r_info)); - break; - } - } - break; - } - } - } - - // - // Pad by adding empty entries. - // - while (mCoffOffset & (mCoffAlignment - 1)) { - CoffAddFixupEntry(0); - } - - NtHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(mCoffFile + mNtHdrOffset); - Dir = &NtHdr->Pe32.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC]; - Dir->Size = mCoffOffset - mRelocOffset; - if (Dir->Size == 0) { - // If no relocations, null out the directory entry and don't add the .reloc section - Dir->VirtualAddress = 0; - NtHdr->Pe32.FileHeader.NumberOfSections--; - } else { - Dir->VirtualAddress = mRelocOffset; - CreateSectionHeader (".reloc", mRelocOffset, mCoffOffset - mRelocOffset, - EFI_IMAGE_SCN_CNT_INITIALIZED_DATA - | EFI_IMAGE_SCN_MEM_DISCARDABLE - | EFI_IMAGE_SCN_MEM_READ); - } - -} - -STATIC -VOID -WriteDebug32 ( - VOID - ) -{ - UINT32 Len; - UINT32 DebugOffset; - EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr; - EFI_IMAGE_DATA_DIRECTORY *DataDir; - EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *Dir; - EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY *Nb10; - - Len = strlen(mInImageName) + 1; - DebugOffset = mCoffOffset; - - mCoffOffset += sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY) - + sizeof(EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY) - + Len; - mCoffOffset = CoffAlign(mCoffOffset); - - mCoffFile = realloc(mCoffFile, mCoffOffset); - memset(mCoffFile + DebugOffset, 0, mCoffOffset - DebugOffset); - - Dir = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY*)(mCoffFile + DebugOffset); - Dir->Type = EFI_IMAGE_DEBUG_TYPE_CODEVIEW; - Dir->SizeOfData = sizeof(EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY) + Len; - Dir->RVA = DebugOffset + sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY); - Dir->FileOffset = DebugOffset + sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY); - - Nb10 = (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY*)(Dir + 1); - Nb10->Signature = CODEVIEW_SIGNATURE_NB10; - strcpy ((char *)(Nb10 + 1), mInImageName); - - - NtHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(mCoffFile + mNtHdrOffset); - DataDir = &NtHdr->Pe32.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]; - DataDir->VirtualAddress = DebugOffset; - DataDir->Size = mCoffOffset - DebugOffset; - if (DataDir->Size == 0) { - // If no debug, null out the directory entry and don't add the .debug section - DataDir->VirtualAddress = 0; - NtHdr->Pe32.FileHeader.NumberOfSections--; - } else { - DataDir->VirtualAddress = DebugOffset; - CreateSectionHeader (".debug", DebugOffset, mCoffOffset - DebugOffset, - EFI_IMAGE_SCN_CNT_INITIALIZED_DATA - | EFI_IMAGE_SCN_MEM_DISCARDABLE - | EFI_IMAGE_SCN_MEM_READ); - - } -} - -STATIC -VOID -SetImageSize32 ( - VOID - ) -{ - EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr; - - // - // Set image size - // - NtHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(mCoffFile + mNtHdrOffset); - NtHdr->Pe32.OptionalHeader.SizeOfImage = mCoffOffset; -} - -STATIC -VOID -CleanUp32 ( - VOID - ) -{ - if (mCoffSectionsOffset != NULL) { - free (mCoffSectionsOffset); - } -} - - +/** @file + +Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.
+Portions copyright (c) 2013, ARM Ltd. All rights reserved.
+ +This program and the accompanying materials are licensed and made available +under the terms and conditions of the BSD License which accompanies this +distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "WinNtInclude.h" + +#ifndef __GNUC__ +#include +#include +#endif +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "PeCoffLib.h" +#include "EfiUtilityMsgs.h" + +#include "GenFw.h" +#include "ElfConvert.h" +#include "Elf32Convert.h" + +STATIC +VOID +ScanSections32 ( + VOID + ); + +STATIC +BOOLEAN +WriteSections32 ( + SECTION_FILTER_TYPES FilterType + ); + +STATIC +VOID +WriteRelocations32 ( + VOID + ); + +STATIC +VOID +WriteDebug32 ( + VOID + ); + +STATIC +VOID +SetImageSize32 ( + VOID + ); + +STATIC +VOID +CleanUp32 ( + VOID + ); + +// +// Rename ELF32 strucutres to common names to help when porting to ELF64. +// +typedef Elf32_Shdr Elf_Shdr; +typedef Elf32_Ehdr Elf_Ehdr; +typedef Elf32_Rel Elf_Rel; +typedef Elf32_Sym Elf_Sym; +typedef Elf32_Phdr Elf_Phdr; +typedef Elf32_Dyn Elf_Dyn; +#define ELFCLASS ELFCLASS32 +#define ELF_R_TYPE(r) ELF32_R_TYPE(r) +#define ELF_R_SYM(r) ELF32_R_SYM(r) + +// +// Well known ELF structures. +// +STATIC Elf_Ehdr *mEhdr; +STATIC Elf_Shdr *mShdrBase; +STATIC Elf_Phdr *mPhdrBase; + +// +// Coff information +// +STATIC const UINT32 mCoffAlignment = 0x20; + +// +// PE section alignment. +// +STATIC const UINT16 mCoffNbrSections = 5; + +// +// ELF sections to offset in Coff file. +// +STATIC UINT32 *mCoffSectionsOffset = NULL; + +// +// Offsets in COFF file +// +STATIC UINT32 mNtHdrOffset; +STATIC UINT32 mTextOffset; +STATIC UINT32 mDataOffset; +STATIC UINT32 mHiiRsrcOffset; +STATIC UINT32 mRelocOffset; + +// +// Initialization Function +// +BOOLEAN +InitializeElf32 ( + UINT8 *FileBuffer, + ELF_FUNCTION_TABLE *ElfFunctions + ) +{ + // + // Initialize data pointer and structures. + // + mEhdr = (Elf_Ehdr*) FileBuffer; + + // + // Check the ELF32 specific header information. + // + if (mEhdr->e_ident[EI_CLASS] != ELFCLASS32) { + Error (NULL, 0, 3000, "Unsupported", "ELF EI_DATA not ELFCLASS32"); + return FALSE; + } + if (mEhdr->e_ident[EI_DATA] != ELFDATA2LSB) { + Error (NULL, 0, 3000, "Unsupported", "ELF EI_DATA not ELFDATA2LSB"); + return FALSE; + } + if ((mEhdr->e_type != ET_EXEC) && (mEhdr->e_type != ET_DYN)) { + Error (NULL, 0, 3000, "Unsupported", "ELF e_type not ET_EXEC or ET_DYN"); + return FALSE; + } + if (!((mEhdr->e_machine == EM_386) || (mEhdr->e_machine == EM_ARM))) { + Error (NULL, 0, 3000, "Unsupported", "ELF e_machine not EM_386 or EM_ARM"); + return FALSE; + } + if (mEhdr->e_version != EV_CURRENT) { + Error (NULL, 0, 3000, "Unsupported", "ELF e_version (%u) not EV_CURRENT (%d)", (unsigned) mEhdr->e_version, EV_CURRENT); + return FALSE; + } + + // + // Update section header pointers + // + mShdrBase = (Elf_Shdr *)((UINT8 *)mEhdr + mEhdr->e_shoff); + mPhdrBase = (Elf_Phdr *)((UINT8 *)mEhdr + mEhdr->e_phoff); + + // + // Create COFF Section offset buffer and zero. + // + mCoffSectionsOffset = (UINT32 *)malloc(mEhdr->e_shnum * sizeof (UINT32)); + memset(mCoffSectionsOffset, 0, mEhdr->e_shnum * sizeof(UINT32)); + + // + // Fill in function pointers. + // + ElfFunctions->ScanSections = ScanSections32; + ElfFunctions->WriteSections = WriteSections32; + ElfFunctions->WriteRelocations = WriteRelocations32; + ElfFunctions->WriteDebug = WriteDebug32; + ElfFunctions->SetImageSize = SetImageSize32; + ElfFunctions->CleanUp = CleanUp32; + + return TRUE; +} + + +// +// Header by Index functions +// +STATIC +Elf_Shdr* +GetShdrByIndex ( + UINT32 Num + ) +{ + if (Num >= mEhdr->e_shnum) + return NULL; + return (Elf_Shdr*)((UINT8*)mShdrBase + Num * mEhdr->e_shentsize); +} + +STATIC +Elf_Phdr* +GetPhdrByIndex ( + UINT32 num + ) +{ + if (num >= mEhdr->e_phnum) { + return NULL; + } + + return (Elf_Phdr *)((UINT8*)mPhdrBase + num * mEhdr->e_phentsize); +} + +STATIC +UINT32 +CoffAlign ( + UINT32 Offset + ) +{ + return (Offset + mCoffAlignment - 1) & ~(mCoffAlignment - 1); +} + +// +// filter functions +// +STATIC +BOOLEAN +IsTextShdr ( + Elf_Shdr *Shdr + ) +{ + return (BOOLEAN) ((Shdr->sh_flags & (SHF_WRITE | SHF_ALLOC)) == SHF_ALLOC); +} + +STATIC +BOOLEAN +IsHiiRsrcShdr ( + Elf_Shdr *Shdr + ) +{ + Elf_Shdr *Namedr = GetShdrByIndex(mEhdr->e_shstrndx); + + return (BOOLEAN) (strcmp((CHAR8*)mEhdr + Namedr->sh_offset + Shdr->sh_name, ELF_HII_SECTION_NAME) == 0); +} + +STATIC +BOOLEAN +IsDataShdr ( + Elf_Shdr *Shdr + ) +{ + if (IsHiiRsrcShdr(Shdr)) { + return FALSE; + } + return (BOOLEAN) (Shdr->sh_flags & (SHF_WRITE | SHF_ALLOC)) == (SHF_ALLOC | SHF_WRITE); +} + +// +// Elf functions interface implementation +// + +STATIC +VOID +ScanSections32 ( + VOID + ) +{ + UINT32 i; + EFI_IMAGE_DOS_HEADER *DosHdr; + EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr; + UINT32 CoffEntry; + UINT32 SectionCount; + BOOLEAN FoundText; + + CoffEntry = 0; + mCoffOffset = 0; + mTextOffset = 0; + FoundText = FALSE; + + // + // Coff file start with a DOS header. + // + mCoffOffset = sizeof(EFI_IMAGE_DOS_HEADER) + 0x40; + mNtHdrOffset = mCoffOffset; + switch (mEhdr->e_machine) { + case EM_386: + case EM_ARM: + mCoffOffset += sizeof (EFI_IMAGE_NT_HEADERS32); + break; + default: + VerboseMsg ("%s unknown e_machine type. Assume IA-32", (UINTN)mEhdr->e_machine); + mCoffOffset += sizeof (EFI_IMAGE_NT_HEADERS32); + break; + } + + mTableOffset = mCoffOffset; + mCoffOffset += mCoffNbrSections * sizeof(EFI_IMAGE_SECTION_HEADER); + + // + // First text sections. + // + mCoffOffset = CoffAlign(mCoffOffset); + SectionCount = 0; + for (i = 0; i < mEhdr->e_shnum; i++) { + Elf_Shdr *shdr = GetShdrByIndex(i); + if (IsTextShdr(shdr)) { + if ((shdr->sh_addralign != 0) && (shdr->sh_addralign != 1)) { + // the alignment field is valid + if ((shdr->sh_addr & (shdr->sh_addralign - 1)) == 0) { + // if the section address is aligned we must align PE/COFF + mCoffOffset = (mCoffOffset + shdr->sh_addralign - 1) & ~(shdr->sh_addralign - 1); + } else if ((shdr->sh_addr % shdr->sh_addralign) != (mCoffOffset % shdr->sh_addralign)) { + // ARM RVCT tools have behavior outside of the ELF specification to try + // and make images smaller. If sh_addr is not aligned to sh_addralign + // then the section needs to preserve sh_addr MOD sh_addralign. + // Normally doing nothing here works great. + Error (NULL, 0, 3000, "Invalid", "Unsupported section alignment."); + } + } + + /* Relocate entry. */ + if ((mEhdr->e_entry >= shdr->sh_addr) && + (mEhdr->e_entry < shdr->sh_addr + shdr->sh_size)) { + CoffEntry = mCoffOffset + mEhdr->e_entry - shdr->sh_addr; + } + + // + // Set mTextOffset with the offset of the first '.text' section + // + if (!FoundText) { + mTextOffset = mCoffOffset; + FoundText = TRUE; + } + + mCoffSectionsOffset[i] = mCoffOffset; + mCoffOffset += shdr->sh_size; + SectionCount ++; + } + } + + if (!FoundText) { + Error (NULL, 0, 3000, "Invalid", "Did not find any '.text' section."); + assert (FALSE); + } + + if (mEhdr->e_machine != EM_ARM) { + mCoffOffset = CoffAlign(mCoffOffset); + } + + if (SectionCount > 1 && mOutImageType == FW_EFI_IMAGE) { + Warning (NULL, 0, 0, NULL, "Mulitple sections in %s are merged into 1 text section. Source level debug might not work correctly.", mInImageName); + } + + // + // Then data sections. + // + mDataOffset = mCoffOffset; + SectionCount = 0; + for (i = 0; i < mEhdr->e_shnum; i++) { + Elf_Shdr *shdr = GetShdrByIndex(i); + if (IsDataShdr(shdr)) { + if ((shdr->sh_addralign != 0) && (shdr->sh_addralign != 1)) { + // the alignment field is valid + if ((shdr->sh_addr & (shdr->sh_addralign - 1)) == 0) { + // if the section address is aligned we must align PE/COFF + mCoffOffset = (mCoffOffset + shdr->sh_addralign - 1) & ~(shdr->sh_addralign - 1); + } else if ((shdr->sh_addr % shdr->sh_addralign) != (mCoffOffset % shdr->sh_addralign)) { + // ARM RVCT tools have behavior outside of the ELF specification to try + // and make images smaller. If sh_addr is not aligned to sh_addralign + // then the section needs to preserve sh_addr MOD sh_addralign. + // Normally doing nothing here works great. + Error (NULL, 0, 3000, "Invalid", "Unsupported section alignment."); + } + } + mCoffSectionsOffset[i] = mCoffOffset; + mCoffOffset += shdr->sh_size; + SectionCount ++; + } + } + mCoffOffset = CoffAlign(mCoffOffset); + + if (SectionCount > 1 && mOutImageType == FW_EFI_IMAGE) { + Warning (NULL, 0, 0, NULL, "Mulitple sections in %s are merged into 1 data section. Source level debug might not work correctly.", mInImageName); + } + + // + // The HII resource sections. + // + mHiiRsrcOffset = mCoffOffset; + for (i = 0; i < mEhdr->e_shnum; i++) { + Elf_Shdr *shdr = GetShdrByIndex(i); + if (IsHiiRsrcShdr(shdr)) { + if ((shdr->sh_addralign != 0) && (shdr->sh_addralign != 1)) { + // the alignment field is valid + if ((shdr->sh_addr & (shdr->sh_addralign - 1)) == 0) { + // if the section address is aligned we must align PE/COFF + mCoffOffset = (mCoffOffset + shdr->sh_addralign - 1) & ~(shdr->sh_addralign - 1); + } else if ((shdr->sh_addr % shdr->sh_addralign) != (mCoffOffset % shdr->sh_addralign)) { + // ARM RVCT tools have behavior outside of the ELF specification to try + // and make images smaller. If sh_addr is not aligned to sh_addralign + // then the section needs to preserve sh_addr MOD sh_addralign. + // Normally doing nothing here works great. + Error (NULL, 0, 3000, "Invalid", "Unsupported section alignment."); + } + } + if (shdr->sh_size != 0) { + mCoffSectionsOffset[i] = mCoffOffset; + mCoffOffset += shdr->sh_size; + mCoffOffset = CoffAlign(mCoffOffset); + SetHiiResourceHeader ((UINT8*) mEhdr + shdr->sh_offset, mHiiRsrcOffset); + } + break; + } + } + + mRelocOffset = mCoffOffset; + + // + // Allocate base Coff file. Will be expanded later for relocations. + // + mCoffFile = (UINT8 *)malloc(mCoffOffset); + memset(mCoffFile, 0, mCoffOffset); + + // + // Fill headers. + // + DosHdr = (EFI_IMAGE_DOS_HEADER *)mCoffFile; + DosHdr->e_magic = EFI_IMAGE_DOS_SIGNATURE; + DosHdr->e_lfanew = mNtHdrOffset; + + NtHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION*)(mCoffFile + mNtHdrOffset); + + NtHdr->Pe32.Signature = EFI_IMAGE_NT_SIGNATURE; + + switch (mEhdr->e_machine) { + case EM_386: + NtHdr->Pe32.FileHeader.Machine = EFI_IMAGE_MACHINE_IA32; + NtHdr->Pe32.OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC; + break; + case EM_ARM: + NtHdr->Pe32.FileHeader.Machine = EFI_IMAGE_MACHINE_ARMT; + NtHdr->Pe32.OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC; + break; + default: + VerboseMsg ("%s unknown e_machine type. Assume IA-32", (UINTN)mEhdr->e_machine); + NtHdr->Pe32.FileHeader.Machine = EFI_IMAGE_MACHINE_IA32; + NtHdr->Pe32.OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC; + } + + NtHdr->Pe32.FileHeader.NumberOfSections = mCoffNbrSections; + NtHdr->Pe32.FileHeader.TimeDateStamp = (UINT32) time(NULL); + mImageTimeStamp = NtHdr->Pe32.FileHeader.TimeDateStamp; + NtHdr->Pe32.FileHeader.PointerToSymbolTable = 0; + NtHdr->Pe32.FileHeader.NumberOfSymbols = 0; + NtHdr->Pe32.FileHeader.SizeOfOptionalHeader = sizeof(NtHdr->Pe32.OptionalHeader); + NtHdr->Pe32.FileHeader.Characteristics = EFI_IMAGE_FILE_EXECUTABLE_IMAGE + | EFI_IMAGE_FILE_LINE_NUMS_STRIPPED + | EFI_IMAGE_FILE_LOCAL_SYMS_STRIPPED + | EFI_IMAGE_FILE_32BIT_MACHINE; + + NtHdr->Pe32.OptionalHeader.SizeOfCode = mDataOffset - mTextOffset; + NtHdr->Pe32.OptionalHeader.SizeOfInitializedData = mRelocOffset - mDataOffset; + NtHdr->Pe32.OptionalHeader.SizeOfUninitializedData = 0; + NtHdr->Pe32.OptionalHeader.AddressOfEntryPoint = CoffEntry; + + NtHdr->Pe32.OptionalHeader.BaseOfCode = mTextOffset; + + NtHdr->Pe32.OptionalHeader.BaseOfData = mDataOffset; + NtHdr->Pe32.OptionalHeader.ImageBase = 0; + NtHdr->Pe32.OptionalHeader.SectionAlignment = mCoffAlignment; + NtHdr->Pe32.OptionalHeader.FileAlignment = mCoffAlignment; + NtHdr->Pe32.OptionalHeader.SizeOfImage = 0; + + NtHdr->Pe32.OptionalHeader.SizeOfHeaders = mTextOffset; + NtHdr->Pe32.OptionalHeader.NumberOfRvaAndSizes = EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES; + + // + // Section headers. + // + if ((mDataOffset - mTextOffset) > 0) { + CreateSectionHeader (".text", mTextOffset, mDataOffset - mTextOffset, + EFI_IMAGE_SCN_CNT_CODE + | EFI_IMAGE_SCN_MEM_EXECUTE + | EFI_IMAGE_SCN_MEM_READ); + } else { + // Don't make a section of size 0. + NtHdr->Pe32.FileHeader.NumberOfSections--; + } + + if ((mHiiRsrcOffset - mDataOffset) > 0) { + CreateSectionHeader (".data", mDataOffset, mHiiRsrcOffset - mDataOffset, + EFI_IMAGE_SCN_CNT_INITIALIZED_DATA + | EFI_IMAGE_SCN_MEM_WRITE + | EFI_IMAGE_SCN_MEM_READ); + } else { + // Don't make a section of size 0. + NtHdr->Pe32.FileHeader.NumberOfSections--; + } + + if ((mRelocOffset - mHiiRsrcOffset) > 0) { + CreateSectionHeader (".rsrc", mHiiRsrcOffset, mRelocOffset - mHiiRsrcOffset, + EFI_IMAGE_SCN_CNT_INITIALIZED_DATA + | EFI_IMAGE_SCN_MEM_READ); + + NtHdr->Pe32.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].Size = mRelocOffset - mHiiRsrcOffset; + NtHdr->Pe32.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress = mHiiRsrcOffset; + } else { + // Don't make a section of size 0. + NtHdr->Pe32.FileHeader.NumberOfSections--; + } + +} + +STATIC +BOOLEAN +WriteSections32 ( + SECTION_FILTER_TYPES FilterType + ) +{ + UINT32 Idx; + Elf_Shdr *SecShdr; + UINT32 SecOffset; + BOOLEAN (*Filter)(Elf_Shdr *); + + // + // Initialize filter pointer + // + switch (FilterType) { + case SECTION_TEXT: + Filter = IsTextShdr; + break; + case SECTION_HII: + Filter = IsHiiRsrcShdr; + break; + case SECTION_DATA: + Filter = IsDataShdr; + break; + default: + return FALSE; + } + + // + // First: copy sections. + // + for (Idx = 0; Idx < mEhdr->e_shnum; Idx++) { + Elf_Shdr *Shdr = GetShdrByIndex(Idx); + if ((*Filter)(Shdr)) { + switch (Shdr->sh_type) { + case SHT_PROGBITS: + /* Copy. */ + memcpy(mCoffFile + mCoffSectionsOffset[Idx], + (UINT8*)mEhdr + Shdr->sh_offset, + Shdr->sh_size); + break; + + case SHT_NOBITS: + memset(mCoffFile + mCoffSectionsOffset[Idx], 0, Shdr->sh_size); + break; + + default: + // + // Ignore for unkown section type. + // + VerboseMsg ("%s unknown section type %x. We directly copy this section into Coff file", mInImageName, (unsigned)Shdr->sh_type); + break; + } + } + } + + // + // Second: apply relocations. + // + for (Idx = 0; Idx < mEhdr->e_shnum; Idx++) { + // + // Determine if this is a relocation section. + // + Elf_Shdr *RelShdr = GetShdrByIndex(Idx); + if ((RelShdr->sh_type != SHT_REL) && (RelShdr->sh_type != SHT_RELA)) { + continue; + } + + // + // Relocation section found. Now extract section information that the relocations + // apply to in the ELF data and the new COFF data. + // + SecShdr = GetShdrByIndex(RelShdr->sh_info); + SecOffset = mCoffSectionsOffset[RelShdr->sh_info]; + + // + // Only process relocations for the current filter type. + // + if (RelShdr->sh_type == SHT_REL && (*Filter)(SecShdr)) { + UINT32 RelOffset; + + // + // Determine the symbol table referenced by the relocation data. + // + Elf_Shdr *SymtabShdr = GetShdrByIndex(RelShdr->sh_link); + UINT8 *Symtab = (UINT8*)mEhdr + SymtabShdr->sh_offset; + + // + // Process all relocation entries for this section. + // + for (RelOffset = 0; RelOffset < RelShdr->sh_size; RelOffset += RelShdr->sh_entsize) { + // + // Set pointer to relocation entry + // + Elf_Rel *Rel = (Elf_Rel *)((UINT8*)mEhdr + RelShdr->sh_offset + RelOffset); + + // + // Set pointer to symbol table entry associated with the relocation entry. + // + Elf_Sym *Sym = (Elf_Sym *)(Symtab + ELF_R_SYM(Rel->r_info) * SymtabShdr->sh_entsize); + + Elf_Shdr *SymShdr; + UINT8 *Targ; + UINT16 Address; + + // + // Check section header index found in symbol table and get the section + // header location. + // + if (Sym->st_shndx == SHN_UNDEF + || Sym->st_shndx == SHN_ABS + || Sym->st_shndx > mEhdr->e_shnum) { + Error (NULL, 0, 3000, "Invalid", "%s bad symbol definition.", mInImageName); + } + SymShdr = GetShdrByIndex(Sym->st_shndx); + + // + // Convert the relocation data to a pointer into the coff file. + // + // Note: + // r_offset is the virtual address of the storage unit to be relocated. + // sh_addr is the virtual address for the base of the section. + // + Targ = mCoffFile + SecOffset + (Rel->r_offset - SecShdr->sh_addr); + + // + // Determine how to handle each relocation type based on the machine type. + // + if (mEhdr->e_machine == EM_386) { + switch (ELF_R_TYPE(Rel->r_info)) { + case R_386_NONE: + break; + case R_386_32: + // + // Absolute relocation. + // Converts Targ from a absolute virtual address to the absolute + // COFF address. + // + *(UINT32 *)Targ = *(UINT32 *)Targ - SymShdr->sh_addr + + mCoffSectionsOffset[Sym->st_shndx]; + break; + case R_386_PC32: + // + // Relative relocation: Symbol - Ip + Addend + // + *(UINT32 *)Targ = *(UINT32 *)Targ + + (mCoffSectionsOffset[Sym->st_shndx] - SymShdr->sh_addr) + - (SecOffset - SecShdr->sh_addr); + break; + default: + Error (NULL, 0, 3000, "Invalid", "%s unsupported ELF EM_386 relocation 0x%x.", mInImageName, (unsigned) ELF_R_TYPE(Rel->r_info)); + } + } else if (mEhdr->e_machine == EM_ARM) { + switch (ELF32_R_TYPE(Rel->r_info)) { + case R_ARM_RBASE: + // No relocation - no action required + // break skipped + + case R_ARM_PC24: + case R_ARM_XPC25: + case R_ARM_THM_PC22: + case R_ARM_THM_JUMP19: + case R_ARM_CALL: + case R_ARM_JMP24: + case R_ARM_THM_JUMP24: + case R_ARM_PREL31: + case R_ARM_MOVW_PREL_NC: + case R_ARM_MOVT_PREL: + case R_ARM_THM_MOVW_PREL_NC: + case R_ARM_THM_MOVT_PREL: + case R_ARM_THM_JMP6: + case R_ARM_THM_ALU_PREL_11_0: + case R_ARM_THM_PC12: + case R_ARM_REL32_NOI: + case R_ARM_ALU_PC_G0_NC: + case R_ARM_ALU_PC_G0: + case R_ARM_ALU_PC_G1_NC: + case R_ARM_ALU_PC_G1: + case R_ARM_ALU_PC_G2: + case R_ARM_LDR_PC_G1: + case R_ARM_LDR_PC_G2: + case R_ARM_LDRS_PC_G0: + case R_ARM_LDRS_PC_G1: + case R_ARM_LDRS_PC_G2: + case R_ARM_LDC_PC_G0: + case R_ARM_LDC_PC_G1: + case R_ARM_LDC_PC_G2: + case R_ARM_GOT_PREL: + case R_ARM_THM_JUMP11: + case R_ARM_THM_JUMP8: + case R_ARM_TLS_GD32: + case R_ARM_TLS_LDM32: + case R_ARM_TLS_IE32: + // Thease are all PC-relative relocations and don't require modification + // GCC does not seem to have the concept of a application that just needs to get relocated. + break; + + case R_ARM_THM_MOVW_ABS_NC: + // MOVW is only lower 16-bits of the addres + Address = (UINT16)(Sym->st_value - SymShdr->sh_addr + mCoffSectionsOffset[Sym->st_shndx]); + ThumbMovtImmediatePatch ((UINT16 *)Targ, Address); + break; + + case R_ARM_THM_MOVT_ABS: + // MOVT is only upper 16-bits of the addres + Address = (UINT16)((Sym->st_value - SymShdr->sh_addr + mCoffSectionsOffset[Sym->st_shndx]) >> 16); + ThumbMovtImmediatePatch ((UINT16 *)Targ, Address); + break; + + case R_ARM_ABS32: + case R_ARM_RABS32: + // + // Absolute relocation. + // + *(UINT32 *)Targ = *(UINT32 *)Targ - SymShdr->sh_addr + mCoffSectionsOffset[Sym->st_shndx]; + break; + + default: + Error (NULL, 0, 3000, "Invalid", "WriteSections (): %s unsupported ELF EM_ARM relocation 0x%x.", mInImageName, (unsigned) ELF32_R_TYPE(Rel->r_info)); + } + } + } + } + } + + return TRUE; +} + +UINTN gMovwOffset = 0; + +STATIC +VOID +WriteRelocations32 ( + VOID + ) +{ + UINT32 Index; + EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr; + EFI_IMAGE_DATA_DIRECTORY *Dir; + BOOLEAN FoundRelocations; + Elf_Dyn *Dyn; + Elf_Rel *Rel; + UINTN RelElementSize; + UINTN RelSize; + UINTN RelOffset; + UINTN K; + UINT8 *Targ; + Elf32_Phdr *DynamicSegment; + Elf32_Phdr *TargetSegment; + + for (Index = 0, FoundRelocations = FALSE; Index < mEhdr->e_shnum; Index++) { + Elf_Shdr *RelShdr = GetShdrByIndex(Index); + if ((RelShdr->sh_type == SHT_REL) || (RelShdr->sh_type == SHT_RELA)) { + Elf_Shdr *SecShdr = GetShdrByIndex (RelShdr->sh_info); + if (IsTextShdr(SecShdr) || IsDataShdr(SecShdr)) { + UINT32 RelIdx; + + FoundRelocations = TRUE; + for (RelIdx = 0; RelIdx < RelShdr->sh_size; RelIdx += RelShdr->sh_entsize) { + Elf_Rel *Rel = (Elf_Rel *)((UINT8*)mEhdr + RelShdr->sh_offset + RelIdx); + + if (mEhdr->e_machine == EM_386) { + switch (ELF_R_TYPE(Rel->r_info)) { + case R_386_NONE: + case R_386_PC32: + // + // No fixup entry required. + // + break; + case R_386_32: + // + // Creates a relative relocation entry from the absolute entry. + // + CoffAddFixup(mCoffSectionsOffset[RelShdr->sh_info] + + (Rel->r_offset - SecShdr->sh_addr), + EFI_IMAGE_REL_BASED_HIGHLOW); + break; + default: + Error (NULL, 0, 3000, "Invalid", "%s unsupported ELF EM_386 relocation 0x%x.", mInImageName, (unsigned) ELF_R_TYPE(Rel->r_info)); + } + } else if (mEhdr->e_machine == EM_ARM) { + switch (ELF32_R_TYPE(Rel->r_info)) { + case R_ARM_RBASE: + // No relocation - no action required + // break skipped + + case R_ARM_PC24: + case R_ARM_XPC25: + case R_ARM_THM_PC22: + case R_ARM_THM_JUMP19: + case R_ARM_CALL: + case R_ARM_JMP24: + case R_ARM_THM_JUMP24: + case R_ARM_PREL31: + case R_ARM_MOVW_PREL_NC: + case R_ARM_MOVT_PREL: + case R_ARM_THM_MOVW_PREL_NC: + case R_ARM_THM_MOVT_PREL: + case R_ARM_THM_JMP6: + case R_ARM_THM_ALU_PREL_11_0: + case R_ARM_THM_PC12: + case R_ARM_REL32_NOI: + case R_ARM_ALU_PC_G0_NC: + case R_ARM_ALU_PC_G0: + case R_ARM_ALU_PC_G1_NC: + case R_ARM_ALU_PC_G1: + case R_ARM_ALU_PC_G2: + case R_ARM_LDR_PC_G1: + case R_ARM_LDR_PC_G2: + case R_ARM_LDRS_PC_G0: + case R_ARM_LDRS_PC_G1: + case R_ARM_LDRS_PC_G2: + case R_ARM_LDC_PC_G0: + case R_ARM_LDC_PC_G1: + case R_ARM_LDC_PC_G2: + case R_ARM_GOT_PREL: + case R_ARM_THM_JUMP11: + case R_ARM_THM_JUMP8: + case R_ARM_TLS_GD32: + case R_ARM_TLS_LDM32: + case R_ARM_TLS_IE32: + // Thease are all PC-relative relocations and don't require modification + break; + + case R_ARM_THM_MOVW_ABS_NC: + CoffAddFixup ( + mCoffSectionsOffset[RelShdr->sh_info] + + (Rel->r_offset - SecShdr->sh_addr), + EFI_IMAGE_REL_BASED_ARM_MOV32T + ); + + // PE/COFF treats MOVW/MOVT relocation as single 64-bit instruction + // Track this address so we can log an error for unsupported sequence of MOVW/MOVT + gMovwOffset = mCoffSectionsOffset[RelShdr->sh_info] + (Rel->r_offset - SecShdr->sh_addr); + break; + + case R_ARM_THM_MOVT_ABS: + if ((gMovwOffset + 4) != (mCoffSectionsOffset[RelShdr->sh_info] + (Rel->r_offset - SecShdr->sh_addr))) { + Error (NULL, 0, 3000, "Not Supported", "PE/COFF requires MOVW+MOVT instruction sequence %x +4 != %x.", gMovwOffset, mCoffSectionsOffset[RelShdr->sh_info] + (Rel->r_offset - SecShdr->sh_addr)); + } + break; + + case R_ARM_ABS32: + case R_ARM_RABS32: + CoffAddFixup ( + mCoffSectionsOffset[RelShdr->sh_info] + + (Rel->r_offset - SecShdr->sh_addr), + EFI_IMAGE_REL_BASED_HIGHLOW + ); + break; + + default: + Error (NULL, 0, 3000, "Invalid", "WriteRelocations(): %s unsupported ELF EM_ARM relocation 0x%x.", mInImageName, (unsigned) ELF32_R_TYPE(Rel->r_info)); + } + } else { + Error (NULL, 0, 3000, "Not Supported", "This tool does not support relocations for ELF with e_machine %u (processor type).", (unsigned) mEhdr->e_machine); + } + } + } + } + } + + if (!FoundRelocations && (mEhdr->e_machine == EM_ARM)) { + /* Try again, but look for PT_DYNAMIC instead of SHT_REL */ + + for (Index = 0; Index < mEhdr->e_phnum; Index++) { + RelElementSize = 0; + RelSize = 0; + RelOffset = 0; + + DynamicSegment = GetPhdrByIndex (Index); + + if (DynamicSegment->p_type == PT_DYNAMIC) { + Dyn = (Elf32_Dyn *) ((UINT8 *)mEhdr + DynamicSegment->p_offset); + + while (Dyn->d_tag != DT_NULL) { + switch (Dyn->d_tag) { + case DT_REL: + RelOffset = Dyn->d_un.d_val; + break; + + case DT_RELSZ: + RelSize = Dyn->d_un.d_val; + break; + + case DT_RELENT: + RelElementSize = Dyn->d_un.d_val; + break; + + default: + break; + } + Dyn++; + } + if (( RelOffset == 0 ) || ( RelSize == 0 ) || ( RelElementSize == 0 )) { + Error (NULL, 0, 3000, "Invalid", "%s bad ARM dynamic relocations.", mInImageName); + } + + for (K = 0; K < RelSize; K += RelElementSize) { + + if (DynamicSegment->p_paddr == 0) { + // Older versions of the ARM ELF (SWS ESPC 0003 B-02) specification define DT_REL + // as an offset in the dynamic segment. p_paddr is defined to be zero for ARM tools + Rel = (Elf32_Rel *) ((UINT8 *) mEhdr + DynamicSegment->p_offset + RelOffset + K); + } else { + // This is how it reads in the generic ELF specification + Rel = (Elf32_Rel *) ((UINT8 *) mEhdr + RelOffset + K); + } + + switch (ELF32_R_TYPE (Rel->r_info)) { + case R_ARM_RBASE: + break; + + case R_ARM_RABS32: + TargetSegment = GetPhdrByIndex (ELF32_R_SYM (Rel->r_info) - 1); + + // Note: r_offset in a memory address. Convert it to a pointer in the coff file. + Targ = mCoffFile + mCoffSectionsOffset[ ELF32_R_SYM( Rel->r_info ) ] + Rel->r_offset - TargetSegment->p_vaddr; + + *(UINT32 *)Targ = *(UINT32 *)Targ + mCoffSectionsOffset [ELF32_R_SYM( Rel->r_info )]; + + CoffAddFixup (mCoffSectionsOffset[ELF32_R_SYM (Rel->r_info)] + (Rel->r_offset - TargetSegment->p_vaddr), EFI_IMAGE_REL_BASED_HIGHLOW); + break; + + default: + Error (NULL, 0, 3000, "Invalid", "%s bad ARM dynamic relocations, unkown type %d.", mInImageName, ELF32_R_TYPE (Rel->r_info)); + break; + } + } + break; + } + } + } + + // + // Pad by adding empty entries. + // + while (mCoffOffset & (mCoffAlignment - 1)) { + CoffAddFixupEntry(0); + } + + NtHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(mCoffFile + mNtHdrOffset); + Dir = &NtHdr->Pe32.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC]; + Dir->Size = mCoffOffset - mRelocOffset; + if (Dir->Size == 0) { + // If no relocations, null out the directory entry and don't add the .reloc section + Dir->VirtualAddress = 0; + NtHdr->Pe32.FileHeader.NumberOfSections--; + } else { + Dir->VirtualAddress = mRelocOffset; + CreateSectionHeader (".reloc", mRelocOffset, mCoffOffset - mRelocOffset, + EFI_IMAGE_SCN_CNT_INITIALIZED_DATA + | EFI_IMAGE_SCN_MEM_DISCARDABLE + | EFI_IMAGE_SCN_MEM_READ); + } + +} + +STATIC +VOID +WriteDebug32 ( + VOID + ) +{ + UINT32 Len; + UINT32 DebugOffset; + EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr; + EFI_IMAGE_DATA_DIRECTORY *DataDir; + EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *Dir; + EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY *Nb10; + + Len = strlen(mInImageName) + 1; + DebugOffset = mCoffOffset; + + mCoffOffset += sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY) + + sizeof(EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY) + + Len; + mCoffOffset = CoffAlign(mCoffOffset); + + mCoffFile = realloc(mCoffFile, mCoffOffset); + memset(mCoffFile + DebugOffset, 0, mCoffOffset - DebugOffset); + + Dir = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY*)(mCoffFile + DebugOffset); + Dir->Type = EFI_IMAGE_DEBUG_TYPE_CODEVIEW; + Dir->SizeOfData = sizeof(EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY) + Len; + Dir->RVA = DebugOffset + sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY); + Dir->FileOffset = DebugOffset + sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY); + + Nb10 = (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY*)(Dir + 1); + Nb10->Signature = CODEVIEW_SIGNATURE_NB10; + strcpy ((char *)(Nb10 + 1), mInImageName); + + + NtHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(mCoffFile + mNtHdrOffset); + DataDir = &NtHdr->Pe32.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]; + DataDir->VirtualAddress = DebugOffset; + DataDir->Size = mCoffOffset - DebugOffset; + if (DataDir->Size == 0) { + // If no debug, null out the directory entry and don't add the .debug section + DataDir->VirtualAddress = 0; + NtHdr->Pe32.FileHeader.NumberOfSections--; + } else { + DataDir->VirtualAddress = DebugOffset; + CreateSectionHeader (".debug", DebugOffset, mCoffOffset - DebugOffset, + EFI_IMAGE_SCN_CNT_INITIALIZED_DATA + | EFI_IMAGE_SCN_MEM_DISCARDABLE + | EFI_IMAGE_SCN_MEM_READ); + + } +} + +STATIC +VOID +SetImageSize32 ( + VOID + ) +{ + EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr; + + // + // Set image size + // + NtHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(mCoffFile + mNtHdrOffset); + NtHdr->Pe32.OptionalHeader.SizeOfImage = mCoffOffset; +} + +STATIC +VOID +CleanUp32 ( + VOID + ) +{ + if (mCoffSectionsOffset != NULL) { + free (mCoffSectionsOffset); + } +} + + diff --git a/BaseTools/Source/C/GenFw/Elf32Convert.h b/BaseTools/Source/C/GenFw/Elf32Convert.h index 2eafbec258..e6a11d57bc 100644 --- a/BaseTools/Source/C/GenFw/Elf32Convert.h +++ b/BaseTools/Source/C/GenFw/Elf32Convert.h @@ -1,24 +1,24 @@ -/** @file - -Copyright (c) 2010, Intel Corporation. All rights reserved.
- -This program and the accompanying materials are licensed and made available -under the terms and conditions of the BSD License which accompanies this -distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _ELF_32_CONVERT_ -#define _ELF_32_CONVERT_ - -BOOLEAN -InitializeElf32 ( - UINT8 *FileBuffer, - ELF_FUNCTION_TABLE *ElfFunctions - ); - -#endif +/** @file + +Copyright (c) 2010, Intel Corporation. All rights reserved.
+ +This program and the accompanying materials are licensed and made available +under the terms and conditions of the BSD License which accompanies this +distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _ELF_32_CONVERT_ +#define _ELF_32_CONVERT_ + +BOOLEAN +InitializeElf32 ( + UINT8 *FileBuffer, + ELF_FUNCTION_TABLE *ElfFunctions + ); + +#endif diff --git a/BaseTools/Source/C/GenFw/Elf64Convert.c b/BaseTools/Source/C/GenFw/Elf64Convert.c index 713f8f7e47..606c7284f7 100644 --- a/BaseTools/Source/C/GenFw/Elf64Convert.c +++ b/BaseTools/Source/C/GenFw/Elf64Convert.c @@ -1,933 +1,933 @@ -/** @file - -Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.
-Portions copyright (c) 2013, ARM Ltd. All rights reserved.
- -This program and the accompanying materials are licensed and made available -under the terms and conditions of the BSD License which accompanies this -distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "WinNtInclude.h" - -#ifndef __GNUC__ -#include -#include -#endif -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "PeCoffLib.h" -#include "EfiUtilityMsgs.h" - -#include "GenFw.h" -#include "ElfConvert.h" -#include "Elf64Convert.h" - -STATIC -VOID -ScanSections64 ( - VOID - ); - -STATIC -BOOLEAN -WriteSections64 ( - SECTION_FILTER_TYPES FilterType - ); - -STATIC -VOID -WriteRelocations64 ( - VOID - ); - -STATIC -VOID -WriteDebug64 ( - VOID - ); - -STATIC -VOID -SetImageSize64 ( - VOID - ); - -STATIC -VOID -CleanUp64 ( - VOID - ); - -// -// Rename ELF32 strucutres to common names to help when porting to ELF64. -// -typedef Elf64_Shdr Elf_Shdr; -typedef Elf64_Ehdr Elf_Ehdr; -typedef Elf64_Rel Elf_Rel; -typedef Elf64_Rela Elf_Rela; -typedef Elf64_Sym Elf_Sym; -typedef Elf64_Phdr Elf_Phdr; -typedef Elf64_Dyn Elf_Dyn; -#define ELFCLASS ELFCLASS64 -#define ELF_R_TYPE(r) ELF64_R_TYPE(r) -#define ELF_R_SYM(r) ELF64_R_SYM(r) - -// -// Well known ELF structures. -// -STATIC Elf_Ehdr *mEhdr; -STATIC Elf_Shdr *mShdrBase; -STATIC Elf_Phdr *mPhdrBase; - -// -// Coff information -// -STATIC const UINT32 mCoffAlignment = 0x20; - -// -// PE section alignment. -// -STATIC const UINT16 mCoffNbrSections = 5; - -// -// ELF sections to offset in Coff file. -// -STATIC UINT32 *mCoffSectionsOffset = NULL; - -// -// Offsets in COFF file -// -STATIC UINT32 mNtHdrOffset; -STATIC UINT32 mTextOffset; -STATIC UINT32 mDataOffset; -STATIC UINT32 mHiiRsrcOffset; -STATIC UINT32 mRelocOffset; - -// -// Initialization Function -// -BOOLEAN -InitializeElf64 ( - UINT8 *FileBuffer, - ELF_FUNCTION_TABLE *ElfFunctions - ) -{ - // - // Initialize data pointer and structures. - // - VerboseMsg ("Set EHDR"); - mEhdr = (Elf_Ehdr*) FileBuffer; - - // - // Check the ELF64 specific header information. - // - VerboseMsg ("Check ELF64 Header Information"); - if (mEhdr->e_ident[EI_CLASS] != ELFCLASS64) { - Error (NULL, 0, 3000, "Unsupported", "ELF EI_DATA not ELFCLASS64"); - return FALSE; - } - if (mEhdr->e_ident[EI_DATA] != ELFDATA2LSB) { - Error (NULL, 0, 3000, "Unsupported", "ELF EI_DATA not ELFDATA2LSB"); - return FALSE; - } - if ((mEhdr->e_type != ET_EXEC) && (mEhdr->e_type != ET_DYN)) { - Error (NULL, 0, 3000, "Unsupported", "ELF e_type not ET_EXEC or ET_DYN"); - return FALSE; - } - if (!((mEhdr->e_machine == EM_X86_64) || (mEhdr->e_machine == EM_AARCH64))) { - Error (NULL, 0, 3000, "Unsupported", "ELF e_machine not EM_X86_64 or EM_AARCH64"); - return FALSE; - } - if (mEhdr->e_version != EV_CURRENT) { - Error (NULL, 0, 3000, "Unsupported", "ELF e_version (%u) not EV_CURRENT (%d)", (unsigned) mEhdr->e_version, EV_CURRENT); - return FALSE; - } - - // - // Update section header pointers - // - VerboseMsg ("Update Header Pointers"); - mShdrBase = (Elf_Shdr *)((UINT8 *)mEhdr + mEhdr->e_shoff); - mPhdrBase = (Elf_Phdr *)((UINT8 *)mEhdr + mEhdr->e_phoff); - - // - // Create COFF Section offset buffer and zero. - // - VerboseMsg ("Create COFF Section Offset Buffer"); - mCoffSectionsOffset = (UINT32 *)malloc(mEhdr->e_shnum * sizeof (UINT32)); - memset(mCoffSectionsOffset, 0, mEhdr->e_shnum * sizeof(UINT32)); - - // - // Fill in function pointers. - // - VerboseMsg ("Fill in Function Pointers"); - ElfFunctions->ScanSections = ScanSections64; - ElfFunctions->WriteSections = WriteSections64; - ElfFunctions->WriteRelocations = WriteRelocations64; - ElfFunctions->WriteDebug = WriteDebug64; - ElfFunctions->SetImageSize = SetImageSize64; - ElfFunctions->CleanUp = CleanUp64; - - return TRUE; -} - - -// -// Header by Index functions -// -STATIC -Elf_Shdr* -GetShdrByIndex ( - UINT32 Num - ) -{ - if (Num >= mEhdr->e_shnum) - return NULL; - return (Elf_Shdr*)((UINT8*)mShdrBase + Num * mEhdr->e_shentsize); -} - -STATIC -UINT32 -CoffAlign ( - UINT32 Offset - ) -{ - return (Offset + mCoffAlignment - 1) & ~(mCoffAlignment - 1); -} - -// -// filter functions -// -STATIC -BOOLEAN -IsTextShdr ( - Elf_Shdr *Shdr - ) -{ - return (BOOLEAN) ((Shdr->sh_flags & (SHF_WRITE | SHF_ALLOC)) == SHF_ALLOC); -} - -STATIC -BOOLEAN -IsHiiRsrcShdr ( - Elf_Shdr *Shdr - ) -{ - Elf_Shdr *Namedr = GetShdrByIndex(mEhdr->e_shstrndx); - - return (BOOLEAN) (strcmp((CHAR8*)mEhdr + Namedr->sh_offset + Shdr->sh_name, ELF_HII_SECTION_NAME) == 0); -} - -STATIC -BOOLEAN -IsDataShdr ( - Elf_Shdr *Shdr - ) -{ - if (IsHiiRsrcShdr(Shdr)) { - return FALSE; - } - return (BOOLEAN) (Shdr->sh_flags & (SHF_WRITE | SHF_ALLOC)) == (SHF_ALLOC | SHF_WRITE); -} - -// -// Elf functions interface implementation -// - -STATIC -VOID -ScanSections64 ( - VOID - ) -{ - UINT32 i; - EFI_IMAGE_DOS_HEADER *DosHdr; - EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr; - UINT32 CoffEntry; - UINT32 SectionCount; - BOOLEAN FoundText; - - CoffEntry = 0; - mCoffOffset = 0; - mTextOffset = 0; - FoundText = FALSE; - - // - // Coff file start with a DOS header. - // - mCoffOffset = sizeof(EFI_IMAGE_DOS_HEADER) + 0x40; - mNtHdrOffset = mCoffOffset; - switch (mEhdr->e_machine) { - case EM_X86_64: - case EM_IA_64: - case EM_AARCH64: - mCoffOffset += sizeof (EFI_IMAGE_NT_HEADERS64); - break; - default: - VerboseMsg ("%s unknown e_machine type. Assume X64", (UINTN)mEhdr->e_machine); - mCoffOffset += sizeof (EFI_IMAGE_NT_HEADERS64); - break; - } - - mTableOffset = mCoffOffset; - mCoffOffset += mCoffNbrSections * sizeof(EFI_IMAGE_SECTION_HEADER); - - // - // First text sections. - // - mCoffOffset = CoffAlign(mCoffOffset); - SectionCount = 0; - for (i = 0; i < mEhdr->e_shnum; i++) { - Elf_Shdr *shdr = GetShdrByIndex(i); - if (IsTextShdr(shdr)) { - if ((shdr->sh_addralign != 0) && (shdr->sh_addralign != 1)) { - // the alignment field is valid - if ((shdr->sh_addr & (shdr->sh_addralign - 1)) == 0) { - // if the section address is aligned we must align PE/COFF - mCoffOffset = (UINT32) ((mCoffOffset + shdr->sh_addralign - 1) & ~(shdr->sh_addralign - 1)); - } else if ((shdr->sh_addr % shdr->sh_addralign) != (mCoffOffset % shdr->sh_addralign)) { - // ARM RVCT tools have behavior outside of the ELF specification to try - // and make images smaller. If sh_addr is not aligned to sh_addralign - // then the section needs to preserve sh_addr MOD sh_addralign. - // Normally doing nothing here works great. - Error (NULL, 0, 3000, "Invalid", "Unsupported section alignment."); - } - } - - /* Relocate entry. */ - if ((mEhdr->e_entry >= shdr->sh_addr) && - (mEhdr->e_entry < shdr->sh_addr + shdr->sh_size)) { - CoffEntry = (UINT32) (mCoffOffset + mEhdr->e_entry - shdr->sh_addr); - } - - // - // Set mTextOffset with the offset of the first '.text' section - // - if (!FoundText) { - mTextOffset = mCoffOffset; - FoundText = TRUE; - } - - mCoffSectionsOffset[i] = mCoffOffset; - mCoffOffset += (UINT32) shdr->sh_size; - SectionCount ++; - } - } - - if (!FoundText) { - Error (NULL, 0, 3000, "Invalid", "Did not find any '.text' section."); - assert (FALSE); - } - - if (mEhdr->e_machine != EM_ARM) { - mCoffOffset = CoffAlign(mCoffOffset); - } - - if (SectionCount > 1 && mOutImageType == FW_EFI_IMAGE) { - Warning (NULL, 0, 0, NULL, "Mulitple sections in %s are merged into 1 text section. Source level debug might not work correctly.", mInImageName); - } - - // - // Then data sections. - // - mDataOffset = mCoffOffset; - SectionCount = 0; - for (i = 0; i < mEhdr->e_shnum; i++) { - Elf_Shdr *shdr = GetShdrByIndex(i); - if (IsDataShdr(shdr)) { - if ((shdr->sh_addralign != 0) && (shdr->sh_addralign != 1)) { - // the alignment field is valid - if ((shdr->sh_addr & (shdr->sh_addralign - 1)) == 0) { - // if the section address is aligned we must align PE/COFF - mCoffOffset = (UINT32) ((mCoffOffset + shdr->sh_addralign - 1) & ~(shdr->sh_addralign - 1)); - } else if ((shdr->sh_addr % shdr->sh_addralign) != (mCoffOffset % shdr->sh_addralign)) { - // ARM RVCT tools have behavior outside of the ELF specification to try - // and make images smaller. If sh_addr is not aligned to sh_addralign - // then the section needs to preserve sh_addr MOD sh_addralign. - // Normally doing nothing here works great. - Error (NULL, 0, 3000, "Invalid", "Unsupported section alignment."); - } - } - mCoffSectionsOffset[i] = mCoffOffset; - mCoffOffset += (UINT32) shdr->sh_size; - SectionCount ++; - } - } - mCoffOffset = CoffAlign(mCoffOffset); - - if (SectionCount > 1 && mOutImageType == FW_EFI_IMAGE) { - Warning (NULL, 0, 0, NULL, "Mulitple sections in %s are merged into 1 data section. Source level debug might not work correctly.", mInImageName); - } - - // - // The HII resource sections. - // - mHiiRsrcOffset = mCoffOffset; - for (i = 0; i < mEhdr->e_shnum; i++) { - Elf_Shdr *shdr = GetShdrByIndex(i); - if (IsHiiRsrcShdr(shdr)) { - if ((shdr->sh_addralign != 0) && (shdr->sh_addralign != 1)) { - // the alignment field is valid - if ((shdr->sh_addr & (shdr->sh_addralign - 1)) == 0) { - // if the section address is aligned we must align PE/COFF - mCoffOffset = (UINT32) ((mCoffOffset + shdr->sh_addralign - 1) & ~(shdr->sh_addralign - 1)); - } else if ((shdr->sh_addr % shdr->sh_addralign) != (mCoffOffset % shdr->sh_addralign)) { - // ARM RVCT tools have behavior outside of the ELF specification to try - // and make images smaller. If sh_addr is not aligned to sh_addralign - // then the section needs to preserve sh_addr MOD sh_addralign. - // Normally doing nothing here works great. - Error (NULL, 0, 3000, "Invalid", "Unsupported section alignment."); - } - } - if (shdr->sh_size != 0) { - mCoffSectionsOffset[i] = mCoffOffset; - mCoffOffset += (UINT32) shdr->sh_size; - mCoffOffset = CoffAlign(mCoffOffset); - SetHiiResourceHeader ((UINT8*) mEhdr + shdr->sh_offset, mHiiRsrcOffset); - } - break; - } - } - - mRelocOffset = mCoffOffset; - - // - // Allocate base Coff file. Will be expanded later for relocations. - // - mCoffFile = (UINT8 *)malloc(mCoffOffset); - memset(mCoffFile, 0, mCoffOffset); - - // - // Fill headers. - // - DosHdr = (EFI_IMAGE_DOS_HEADER *)mCoffFile; - DosHdr->e_magic = EFI_IMAGE_DOS_SIGNATURE; - DosHdr->e_lfanew = mNtHdrOffset; - - NtHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION*)(mCoffFile + mNtHdrOffset); - - NtHdr->Pe32Plus.Signature = EFI_IMAGE_NT_SIGNATURE; - - switch (mEhdr->e_machine) { - case EM_X86_64: - NtHdr->Pe32Plus.FileHeader.Machine = EFI_IMAGE_MACHINE_X64; - NtHdr->Pe32Plus.OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC; - break; - case EM_IA_64: - NtHdr->Pe32Plus.FileHeader.Machine = EFI_IMAGE_MACHINE_IPF; - NtHdr->Pe32Plus.OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC; - break; - case EM_AARCH64: - NtHdr->Pe32Plus.FileHeader.Machine = EFI_IMAGE_MACHINE_AARCH64; - NtHdr->Pe32Plus.OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC; - break; - default: - VerboseMsg ("%s unknown e_machine type. Assume X64", (UINTN)mEhdr->e_machine); - NtHdr->Pe32Plus.FileHeader.Machine = EFI_IMAGE_MACHINE_X64; - NtHdr->Pe32Plus.OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC; - } - - NtHdr->Pe32Plus.FileHeader.NumberOfSections = mCoffNbrSections; - NtHdr->Pe32Plus.FileHeader.TimeDateStamp = (UINT32) time(NULL); - mImageTimeStamp = NtHdr->Pe32Plus.FileHeader.TimeDateStamp; - NtHdr->Pe32Plus.FileHeader.PointerToSymbolTable = 0; - NtHdr->Pe32Plus.FileHeader.NumberOfSymbols = 0; - NtHdr->Pe32Plus.FileHeader.SizeOfOptionalHeader = sizeof(NtHdr->Pe32Plus.OptionalHeader); - NtHdr->Pe32Plus.FileHeader.Characteristics = EFI_IMAGE_FILE_EXECUTABLE_IMAGE - | EFI_IMAGE_FILE_LINE_NUMS_STRIPPED - | EFI_IMAGE_FILE_LOCAL_SYMS_STRIPPED - | EFI_IMAGE_FILE_LARGE_ADDRESS_AWARE; - - NtHdr->Pe32Plus.OptionalHeader.SizeOfCode = mDataOffset - mTextOffset; - NtHdr->Pe32Plus.OptionalHeader.SizeOfInitializedData = mRelocOffset - mDataOffset; - NtHdr->Pe32Plus.OptionalHeader.SizeOfUninitializedData = 0; - NtHdr->Pe32Plus.OptionalHeader.AddressOfEntryPoint = CoffEntry; - - NtHdr->Pe32Plus.OptionalHeader.BaseOfCode = mTextOffset; - - NtHdr->Pe32Plus.OptionalHeader.ImageBase = 0; - NtHdr->Pe32Plus.OptionalHeader.SectionAlignment = mCoffAlignment; - NtHdr->Pe32Plus.OptionalHeader.FileAlignment = mCoffAlignment; - NtHdr->Pe32Plus.OptionalHeader.SizeOfImage = 0; - - NtHdr->Pe32Plus.OptionalHeader.SizeOfHeaders = mTextOffset; - NtHdr->Pe32Plus.OptionalHeader.NumberOfRvaAndSizes = EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES; - - // - // Section headers. - // - if ((mDataOffset - mTextOffset) > 0) { - CreateSectionHeader (".text", mTextOffset, mDataOffset - mTextOffset, - EFI_IMAGE_SCN_CNT_CODE - | EFI_IMAGE_SCN_MEM_EXECUTE - | EFI_IMAGE_SCN_MEM_READ); - } else { - // Don't make a section of size 0. - NtHdr->Pe32Plus.FileHeader.NumberOfSections--; - } - - if ((mHiiRsrcOffset - mDataOffset) > 0) { - CreateSectionHeader (".data", mDataOffset, mHiiRsrcOffset - mDataOffset, - EFI_IMAGE_SCN_CNT_INITIALIZED_DATA - | EFI_IMAGE_SCN_MEM_WRITE - | EFI_IMAGE_SCN_MEM_READ); - } else { - // Don't make a section of size 0. - NtHdr->Pe32Plus.FileHeader.NumberOfSections--; - } - - if ((mRelocOffset - mHiiRsrcOffset) > 0) { - CreateSectionHeader (".rsrc", mHiiRsrcOffset, mRelocOffset - mHiiRsrcOffset, - EFI_IMAGE_SCN_CNT_INITIALIZED_DATA - | EFI_IMAGE_SCN_MEM_READ); - - NtHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].Size = mRelocOffset - mHiiRsrcOffset; - NtHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress = mHiiRsrcOffset; - } else { - // Don't make a section of size 0. - NtHdr->Pe32Plus.FileHeader.NumberOfSections--; - } - -} - -STATIC -BOOLEAN -WriteSections64 ( - SECTION_FILTER_TYPES FilterType - ) -{ - UINT32 Idx; - Elf_Shdr *SecShdr; - UINT32 SecOffset; - BOOLEAN (*Filter)(Elf_Shdr *); - - // - // Initialize filter pointer - // - switch (FilterType) { - case SECTION_TEXT: - Filter = IsTextShdr; - break; - case SECTION_HII: - Filter = IsHiiRsrcShdr; - break; - case SECTION_DATA: - Filter = IsDataShdr; - break; - default: - return FALSE; - } - - // - // First: copy sections. - // - for (Idx = 0; Idx < mEhdr->e_shnum; Idx++) { - Elf_Shdr *Shdr = GetShdrByIndex(Idx); - if ((*Filter)(Shdr)) { - switch (Shdr->sh_type) { - case SHT_PROGBITS: - /* Copy. */ - memcpy(mCoffFile + mCoffSectionsOffset[Idx], - (UINT8*)mEhdr + Shdr->sh_offset, - (size_t) Shdr->sh_size); - break; - - case SHT_NOBITS: - memset(mCoffFile + mCoffSectionsOffset[Idx], 0, (size_t) Shdr->sh_size); - break; - - default: - // - // Ignore for unkown section type. - // - VerboseMsg ("%s unknown section type %x. We directly copy this section into Coff file", mInImageName, (unsigned)Shdr->sh_type); - break; - } - } - } - - // - // Second: apply relocations. - // - VerboseMsg ("Applying Relocations..."); - for (Idx = 0; Idx < mEhdr->e_shnum; Idx++) { - // - // Determine if this is a relocation section. - // - Elf_Shdr *RelShdr = GetShdrByIndex(Idx); - if ((RelShdr->sh_type != SHT_REL) && (RelShdr->sh_type != SHT_RELA)) { - continue; - } - - // - // Relocation section found. Now extract section information that the relocations - // apply to in the ELF data and the new COFF data. - // - SecShdr = GetShdrByIndex(RelShdr->sh_info); - SecOffset = mCoffSectionsOffset[RelShdr->sh_info]; - - // - // Only process relocations for the current filter type. - // - if (RelShdr->sh_type == SHT_RELA && (*Filter)(SecShdr)) { - UINT64 RelIdx; - - // - // Determine the symbol table referenced by the relocation data. - // - Elf_Shdr *SymtabShdr = GetShdrByIndex(RelShdr->sh_link); - UINT8 *Symtab = (UINT8*)mEhdr + SymtabShdr->sh_offset; - - // - // Process all relocation entries for this section. - // - for (RelIdx = 0; RelIdx < RelShdr->sh_size; RelIdx += (UINT32) RelShdr->sh_entsize) { - - // - // Set pointer to relocation entry - // - Elf_Rela *Rel = (Elf_Rela *)((UINT8*)mEhdr + RelShdr->sh_offset + RelIdx); - - // - // Set pointer to symbol table entry associated with the relocation entry. - // - Elf_Sym *Sym = (Elf_Sym *)(Symtab + ELF_R_SYM(Rel->r_info) * SymtabShdr->sh_entsize); - - Elf_Shdr *SymShdr; - UINT8 *Targ; - - // - // Check section header index found in symbol table and get the section - // header location. - // - if (Sym->st_shndx == SHN_UNDEF - || Sym->st_shndx == SHN_ABS - || Sym->st_shndx > mEhdr->e_shnum) { - Error (NULL, 0, 3000, "Invalid", "%s bad symbol definition.", mInImageName); - } - SymShdr = GetShdrByIndex(Sym->st_shndx); - - // - // Convert the relocation data to a pointer into the coff file. - // - // Note: - // r_offset is the virtual address of the storage unit to be relocated. - // sh_addr is the virtual address for the base of the section. - // - // r_offset in a memory address. - // Convert it to a pointer in the coff file. - // - Targ = mCoffFile + SecOffset + (Rel->r_offset - SecShdr->sh_addr); - - // - // Determine how to handle each relocation type based on the machine type. - // - if (mEhdr->e_machine == EM_X86_64) { - switch (ELF_R_TYPE(Rel->r_info)) { - case R_X86_64_NONE: - break; - case R_X86_64_64: - // - // Absolute relocation. - // - VerboseMsg ("R_X86_64_64"); - VerboseMsg ("Offset: 0x%08X, Addend: 0x%016LX", - (UINT32)(SecOffset + (Rel->r_offset - SecShdr->sh_addr)), - *(UINT64 *)Targ); - *(UINT64 *)Targ = *(UINT64 *)Targ - SymShdr->sh_addr + mCoffSectionsOffset[Sym->st_shndx]; - VerboseMsg ("Relocation: 0x%016LX", *(UINT64*)Targ); - break; - case R_X86_64_32: - VerboseMsg ("R_X86_64_32"); - VerboseMsg ("Offset: 0x%08X, Addend: 0x%08X", - (UINT32)(SecOffset + (Rel->r_offset - SecShdr->sh_addr)), - *(UINT32 *)Targ); - *(UINT32 *)Targ = (UINT32)((UINT64)(*(UINT32 *)Targ) - SymShdr->sh_addr + mCoffSectionsOffset[Sym->st_shndx]); - VerboseMsg ("Relocation: 0x%08X", *(UINT32*)Targ); - break; - case R_X86_64_32S: - VerboseMsg ("R_X86_64_32S"); - VerboseMsg ("Offset: 0x%08X, Addend: 0x%08X", - (UINT32)(SecOffset + (Rel->r_offset - SecShdr->sh_addr)), - *(UINT32 *)Targ); - *(INT32 *)Targ = (INT32)((INT64)(*(INT32 *)Targ) - SymShdr->sh_addr + mCoffSectionsOffset[Sym->st_shndx]); - VerboseMsg ("Relocation: 0x%08X", *(UINT32*)Targ); - break; - case R_X86_64_PC32: - // - // Relative relocation: Symbol - Ip + Addend - // - VerboseMsg ("R_X86_64_PC32"); - VerboseMsg ("Offset: 0x%08X, Addend: 0x%08X", - (UINT32)(SecOffset + (Rel->r_offset - SecShdr->sh_addr)), - *(UINT32 *)Targ); - *(UINT32 *)Targ = (UINT32) (*(UINT32 *)Targ - + (mCoffSectionsOffset[Sym->st_shndx] - SymShdr->sh_addr) - - (SecOffset - SecShdr->sh_addr)); - VerboseMsg ("Relocation: 0x%08X", *(UINT32 *)Targ); - break; - default: - Error (NULL, 0, 3000, "Invalid", "%s unsupported ELF EM_X86_64 relocation 0x%x.", mInImageName, (unsigned) ELF_R_TYPE(Rel->r_info)); - } - } else if (mEhdr->e_machine == EM_AARCH64) { - - // AARCH64 GCC uses RELA relocation, so all relocations have to be fixed up. - // As opposed to ARM32 using REL. - - switch (ELF_R_TYPE(Rel->r_info)) { - - case R_AARCH64_LD_PREL_LO19: - if (Rel->r_addend != 0 ) { /* TODO */ - Error (NULL, 0, 3000, "Invalid", "AArch64: R_AARCH64_LD_PREL_LO19 Need to fixup with addend!."); - } - break; - - case R_AARCH64_CALL26: - if (Rel->r_addend != 0 ) { /* TODO */ - Error (NULL, 0, 3000, "Invalid", "AArch64: R_AARCH64_CALL26 Need to fixup with addend!."); - } - break; - - case R_AARCH64_JUMP26: - if (Rel->r_addend != 0 ) { /* TODO : AArch64 '-O2' optimisation. */ - Error (NULL, 0, 3000, "Invalid", "AArch64: R_AARCH64_JUMP26 Need to fixup with addend!."); - } - break; - - case R_AARCH64_ADR_PREL_PG_HI21: - // TODO : AArch64 'small' memory model. - Error (NULL, 0, 3000, "Invalid", "WriteSections64(): %s unsupported ELF EM_AARCH64 relocation R_AARCH64_ADR_PREL_PG_HI21.", mInImageName); - break; - - case R_AARCH64_ADD_ABS_LO12_NC: - // TODO : AArch64 'small' memory model. - Error (NULL, 0, 3000, "Invalid", "WriteSections64(): %s unsupported ELF EM_AARCH64 relocation R_AARCH64_ADD_ABS_LO12_NC.", mInImageName); - break; - - // Absolute relocations. - case R_AARCH64_ABS64: - *(UINT64 *)Targ = *(UINT64 *)Targ - SymShdr->sh_addr + mCoffSectionsOffset[Sym->st_shndx]; - break; - - default: - Error (NULL, 0, 3000, "Invalid", "WriteSections64(): %s unsupported ELF EM_AARCH64 relocation 0x%x.", mInImageName, (unsigned) ELF_R_TYPE(Rel->r_info)); - } - } else { - Error (NULL, 0, 3000, "Invalid", "Not a supported machine type"); - } - } - } - } - - return TRUE; -} - -STATIC -VOID -WriteRelocations64 ( - VOID - ) -{ - UINT32 Index; - EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr; - EFI_IMAGE_DATA_DIRECTORY *Dir; - - for (Index = 0; Index < mEhdr->e_shnum; Index++) { - Elf_Shdr *RelShdr = GetShdrByIndex(Index); - if ((RelShdr->sh_type == SHT_REL) || (RelShdr->sh_type == SHT_RELA)) { - Elf_Shdr *SecShdr = GetShdrByIndex (RelShdr->sh_info); - if (IsTextShdr(SecShdr) || IsDataShdr(SecShdr)) { - UINT64 RelIdx; - - for (RelIdx = 0; RelIdx < RelShdr->sh_size; RelIdx += RelShdr->sh_entsize) { - Elf_Rela *Rel = (Elf_Rela *)((UINT8*)mEhdr + RelShdr->sh_offset + RelIdx); - - if (mEhdr->e_machine == EM_X86_64) { - switch (ELF_R_TYPE(Rel->r_info)) { - case R_X86_64_NONE: - case R_X86_64_PC32: - break; - case R_X86_64_64: - VerboseMsg ("EFI_IMAGE_REL_BASED_DIR64 Offset: 0x%08X", - mCoffSectionsOffset[RelShdr->sh_info] + (Rel->r_offset - SecShdr->sh_addr)); - CoffAddFixup( - (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info] - + (Rel->r_offset - SecShdr->sh_addr)), - EFI_IMAGE_REL_BASED_DIR64); - break; - case R_X86_64_32S: - case R_X86_64_32: - VerboseMsg ("EFI_IMAGE_REL_BASED_HIGHLOW Offset: 0x%08X", - mCoffSectionsOffset[RelShdr->sh_info] + (Rel->r_offset - SecShdr->sh_addr)); - CoffAddFixup( - (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info] - + (Rel->r_offset - SecShdr->sh_addr)), - EFI_IMAGE_REL_BASED_HIGHLOW); - break; - default: - Error (NULL, 0, 3000, "Invalid", "%s unsupported ELF EM_X86_64 relocation 0x%x.", mInImageName, (unsigned) ELF_R_TYPE(Rel->r_info)); - } - } else if (mEhdr->e_machine == EM_AARCH64) { - // AArch64 GCC uses RELA relocation, so all relocations has to be fixed up. ARM32 uses REL. - switch (ELF_R_TYPE(Rel->r_info)) { - case R_AARCH64_LD_PREL_LO19: - break; - - case R_AARCH64_CALL26: - break; - - case R_AARCH64_JUMP26: - break; - - case R_AARCH64_ADR_PREL_PG_HI21: - // TODO : AArch64 'small' memory model. - Error (NULL, 0, 3000, "Invalid", "WriteRelocations64(): %s unsupported ELF EM_AARCH64 relocation R_AARCH64_ADR_PREL_PG_HI21.", mInImageName); - break; - - case R_AARCH64_ADD_ABS_LO12_NC: - // TODO : AArch64 'small' memory model. - Error (NULL, 0, 3000, "Invalid", "WriteRelocations64(): %s unsupported ELF EM_AARCH64 relocation R_AARCH64_ADD_ABS_LO12_NC.", mInImageName); - break; - - case R_AARCH64_ABS64: - CoffAddFixup( - (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info] - + (Rel->r_offset - SecShdr->sh_addr)), - EFI_IMAGE_REL_BASED_DIR64); - break; - - case R_AARCH64_ABS32: - CoffAddFixup( - (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info] - + (Rel->r_offset - SecShdr->sh_addr)), - EFI_IMAGE_REL_BASED_HIGHLOW); - break; - - default: - Error (NULL, 0, 3000, "Invalid", "WriteRelocations64(): %s unsupported ELF EM_AARCH64 relocation 0x%x.", mInImageName, (unsigned) ELF_R_TYPE(Rel->r_info)); - } - } else { - Error (NULL, 0, 3000, "Not Supported", "This tool does not support relocations for ELF with e_machine %u (processor type).", (unsigned) mEhdr->e_machine); - } - } - } - } - } - - // - // Pad by adding empty entries. - // - while (mCoffOffset & (mCoffAlignment - 1)) { - CoffAddFixupEntry(0); - } - - NtHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(mCoffFile + mNtHdrOffset); - Dir = &NtHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC]; - Dir->Size = mCoffOffset - mRelocOffset; - if (Dir->Size == 0) { - // If no relocations, null out the directory entry and don't add the .reloc section - Dir->VirtualAddress = 0; - NtHdr->Pe32Plus.FileHeader.NumberOfSections--; - } else { - Dir->VirtualAddress = mRelocOffset; - CreateSectionHeader (".reloc", mRelocOffset, mCoffOffset - mRelocOffset, - EFI_IMAGE_SCN_CNT_INITIALIZED_DATA - | EFI_IMAGE_SCN_MEM_DISCARDABLE - | EFI_IMAGE_SCN_MEM_READ); - } -} - -STATIC -VOID -WriteDebug64 ( - VOID - ) -{ - UINT32 Len; - UINT32 DebugOffset; - EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr; - EFI_IMAGE_DATA_DIRECTORY *DataDir; - EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *Dir; - EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY *Nb10; - - Len = strlen(mInImageName) + 1; - DebugOffset = mCoffOffset; - - mCoffOffset += sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY) - + sizeof(EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY) - + Len; - mCoffOffset = CoffAlign(mCoffOffset); - - mCoffFile = realloc(mCoffFile, mCoffOffset); - memset(mCoffFile + DebugOffset, 0, mCoffOffset - DebugOffset); - - Dir = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY*)(mCoffFile + DebugOffset); - Dir->Type = EFI_IMAGE_DEBUG_TYPE_CODEVIEW; - Dir->SizeOfData = sizeof(EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY) + Len; - Dir->RVA = DebugOffset + sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY); - Dir->FileOffset = DebugOffset + sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY); - - Nb10 = (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY*)(Dir + 1); - Nb10->Signature = CODEVIEW_SIGNATURE_NB10; - strcpy ((char *)(Nb10 + 1), mInImageName); - - - NtHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(mCoffFile + mNtHdrOffset); - DataDir = &NtHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]; - DataDir->VirtualAddress = DebugOffset; - DataDir->Size = mCoffOffset - DebugOffset; - if (DataDir->Size == 0) { - // If no debug, null out the directory entry and don't add the .debug section - DataDir->VirtualAddress = 0; - NtHdr->Pe32Plus.FileHeader.NumberOfSections--; - } else { - DataDir->VirtualAddress = DebugOffset; - CreateSectionHeader (".debug", DebugOffset, mCoffOffset - DebugOffset, - EFI_IMAGE_SCN_CNT_INITIALIZED_DATA - | EFI_IMAGE_SCN_MEM_DISCARDABLE - | EFI_IMAGE_SCN_MEM_READ); - - } -} - -STATIC -VOID -SetImageSize64 ( - VOID - ) -{ - EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr; - - // - // Set image size - // - NtHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(mCoffFile + mNtHdrOffset); - NtHdr->Pe32Plus.OptionalHeader.SizeOfImage = mCoffOffset; -} - -STATIC -VOID -CleanUp64 ( - VOID - ) -{ - if (mCoffSectionsOffset != NULL) { - free (mCoffSectionsOffset); - } -} - - +/** @file + +Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.
+Portions copyright (c) 2013, ARM Ltd. All rights reserved.
+ +This program and the accompanying materials are licensed and made available +under the terms and conditions of the BSD License which accompanies this +distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "WinNtInclude.h" + +#ifndef __GNUC__ +#include +#include +#endif +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "PeCoffLib.h" +#include "EfiUtilityMsgs.h" + +#include "GenFw.h" +#include "ElfConvert.h" +#include "Elf64Convert.h" + +STATIC +VOID +ScanSections64 ( + VOID + ); + +STATIC +BOOLEAN +WriteSections64 ( + SECTION_FILTER_TYPES FilterType + ); + +STATIC +VOID +WriteRelocations64 ( + VOID + ); + +STATIC +VOID +WriteDebug64 ( + VOID + ); + +STATIC +VOID +SetImageSize64 ( + VOID + ); + +STATIC +VOID +CleanUp64 ( + VOID + ); + +// +// Rename ELF32 strucutres to common names to help when porting to ELF64. +// +typedef Elf64_Shdr Elf_Shdr; +typedef Elf64_Ehdr Elf_Ehdr; +typedef Elf64_Rel Elf_Rel; +typedef Elf64_Rela Elf_Rela; +typedef Elf64_Sym Elf_Sym; +typedef Elf64_Phdr Elf_Phdr; +typedef Elf64_Dyn Elf_Dyn; +#define ELFCLASS ELFCLASS64 +#define ELF_R_TYPE(r) ELF64_R_TYPE(r) +#define ELF_R_SYM(r) ELF64_R_SYM(r) + +// +// Well known ELF structures. +// +STATIC Elf_Ehdr *mEhdr; +STATIC Elf_Shdr *mShdrBase; +STATIC Elf_Phdr *mPhdrBase; + +// +// Coff information +// +STATIC const UINT32 mCoffAlignment = 0x20; + +// +// PE section alignment. +// +STATIC const UINT16 mCoffNbrSections = 5; + +// +// ELF sections to offset in Coff file. +// +STATIC UINT32 *mCoffSectionsOffset = NULL; + +// +// Offsets in COFF file +// +STATIC UINT32 mNtHdrOffset; +STATIC UINT32 mTextOffset; +STATIC UINT32 mDataOffset; +STATIC UINT32 mHiiRsrcOffset; +STATIC UINT32 mRelocOffset; + +// +// Initialization Function +// +BOOLEAN +InitializeElf64 ( + UINT8 *FileBuffer, + ELF_FUNCTION_TABLE *ElfFunctions + ) +{ + // + // Initialize data pointer and structures. + // + VerboseMsg ("Set EHDR"); + mEhdr = (Elf_Ehdr*) FileBuffer; + + // + // Check the ELF64 specific header information. + // + VerboseMsg ("Check ELF64 Header Information"); + if (mEhdr->e_ident[EI_CLASS] != ELFCLASS64) { + Error (NULL, 0, 3000, "Unsupported", "ELF EI_DATA not ELFCLASS64"); + return FALSE; + } + if (mEhdr->e_ident[EI_DATA] != ELFDATA2LSB) { + Error (NULL, 0, 3000, "Unsupported", "ELF EI_DATA not ELFDATA2LSB"); + return FALSE; + } + if ((mEhdr->e_type != ET_EXEC) && (mEhdr->e_type != ET_DYN)) { + Error (NULL, 0, 3000, "Unsupported", "ELF e_type not ET_EXEC or ET_DYN"); + return FALSE; + } + if (!((mEhdr->e_machine == EM_X86_64) || (mEhdr->e_machine == EM_AARCH64))) { + Error (NULL, 0, 3000, "Unsupported", "ELF e_machine not EM_X86_64 or EM_AARCH64"); + return FALSE; + } + if (mEhdr->e_version != EV_CURRENT) { + Error (NULL, 0, 3000, "Unsupported", "ELF e_version (%u) not EV_CURRENT (%d)", (unsigned) mEhdr->e_version, EV_CURRENT); + return FALSE; + } + + // + // Update section header pointers + // + VerboseMsg ("Update Header Pointers"); + mShdrBase = (Elf_Shdr *)((UINT8 *)mEhdr + mEhdr->e_shoff); + mPhdrBase = (Elf_Phdr *)((UINT8 *)mEhdr + mEhdr->e_phoff); + + // + // Create COFF Section offset buffer and zero. + // + VerboseMsg ("Create COFF Section Offset Buffer"); + mCoffSectionsOffset = (UINT32 *)malloc(mEhdr->e_shnum * sizeof (UINT32)); + memset(mCoffSectionsOffset, 0, mEhdr->e_shnum * sizeof(UINT32)); + + // + // Fill in function pointers. + // + VerboseMsg ("Fill in Function Pointers"); + ElfFunctions->ScanSections = ScanSections64; + ElfFunctions->WriteSections = WriteSections64; + ElfFunctions->WriteRelocations = WriteRelocations64; + ElfFunctions->WriteDebug = WriteDebug64; + ElfFunctions->SetImageSize = SetImageSize64; + ElfFunctions->CleanUp = CleanUp64; + + return TRUE; +} + + +// +// Header by Index functions +// +STATIC +Elf_Shdr* +GetShdrByIndex ( + UINT32 Num + ) +{ + if (Num >= mEhdr->e_shnum) + return NULL; + return (Elf_Shdr*)((UINT8*)mShdrBase + Num * mEhdr->e_shentsize); +} + +STATIC +UINT32 +CoffAlign ( + UINT32 Offset + ) +{ + return (Offset + mCoffAlignment - 1) & ~(mCoffAlignment - 1); +} + +// +// filter functions +// +STATIC +BOOLEAN +IsTextShdr ( + Elf_Shdr *Shdr + ) +{ + return (BOOLEAN) ((Shdr->sh_flags & (SHF_WRITE | SHF_ALLOC)) == SHF_ALLOC); +} + +STATIC +BOOLEAN +IsHiiRsrcShdr ( + Elf_Shdr *Shdr + ) +{ + Elf_Shdr *Namedr = GetShdrByIndex(mEhdr->e_shstrndx); + + return (BOOLEAN) (strcmp((CHAR8*)mEhdr + Namedr->sh_offset + Shdr->sh_name, ELF_HII_SECTION_NAME) == 0); +} + +STATIC +BOOLEAN +IsDataShdr ( + Elf_Shdr *Shdr + ) +{ + if (IsHiiRsrcShdr(Shdr)) { + return FALSE; + } + return (BOOLEAN) (Shdr->sh_flags & (SHF_WRITE | SHF_ALLOC)) == (SHF_ALLOC | SHF_WRITE); +} + +// +// Elf functions interface implementation +// + +STATIC +VOID +ScanSections64 ( + VOID + ) +{ + UINT32 i; + EFI_IMAGE_DOS_HEADER *DosHdr; + EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr; + UINT32 CoffEntry; + UINT32 SectionCount; + BOOLEAN FoundText; + + CoffEntry = 0; + mCoffOffset = 0; + mTextOffset = 0; + FoundText = FALSE; + + // + // Coff file start with a DOS header. + // + mCoffOffset = sizeof(EFI_IMAGE_DOS_HEADER) + 0x40; + mNtHdrOffset = mCoffOffset; + switch (mEhdr->e_machine) { + case EM_X86_64: + case EM_IA_64: + case EM_AARCH64: + mCoffOffset += sizeof (EFI_IMAGE_NT_HEADERS64); + break; + default: + VerboseMsg ("%s unknown e_machine type. Assume X64", (UINTN)mEhdr->e_machine); + mCoffOffset += sizeof (EFI_IMAGE_NT_HEADERS64); + break; + } + + mTableOffset = mCoffOffset; + mCoffOffset += mCoffNbrSections * sizeof(EFI_IMAGE_SECTION_HEADER); + + // + // First text sections. + // + mCoffOffset = CoffAlign(mCoffOffset); + SectionCount = 0; + for (i = 0; i < mEhdr->e_shnum; i++) { + Elf_Shdr *shdr = GetShdrByIndex(i); + if (IsTextShdr(shdr)) { + if ((shdr->sh_addralign != 0) && (shdr->sh_addralign != 1)) { + // the alignment field is valid + if ((shdr->sh_addr & (shdr->sh_addralign - 1)) == 0) { + // if the section address is aligned we must align PE/COFF + mCoffOffset = (UINT32) ((mCoffOffset + shdr->sh_addralign - 1) & ~(shdr->sh_addralign - 1)); + } else if ((shdr->sh_addr % shdr->sh_addralign) != (mCoffOffset % shdr->sh_addralign)) { + // ARM RVCT tools have behavior outside of the ELF specification to try + // and make images smaller. If sh_addr is not aligned to sh_addralign + // then the section needs to preserve sh_addr MOD sh_addralign. + // Normally doing nothing here works great. + Error (NULL, 0, 3000, "Invalid", "Unsupported section alignment."); + } + } + + /* Relocate entry. */ + if ((mEhdr->e_entry >= shdr->sh_addr) && + (mEhdr->e_entry < shdr->sh_addr + shdr->sh_size)) { + CoffEntry = (UINT32) (mCoffOffset + mEhdr->e_entry - shdr->sh_addr); + } + + // + // Set mTextOffset with the offset of the first '.text' section + // + if (!FoundText) { + mTextOffset = mCoffOffset; + FoundText = TRUE; + } + + mCoffSectionsOffset[i] = mCoffOffset; + mCoffOffset += (UINT32) shdr->sh_size; + SectionCount ++; + } + } + + if (!FoundText) { + Error (NULL, 0, 3000, "Invalid", "Did not find any '.text' section."); + assert (FALSE); + } + + if (mEhdr->e_machine != EM_ARM) { + mCoffOffset = CoffAlign(mCoffOffset); + } + + if (SectionCount > 1 && mOutImageType == FW_EFI_IMAGE) { + Warning (NULL, 0, 0, NULL, "Mulitple sections in %s are merged into 1 text section. Source level debug might not work correctly.", mInImageName); + } + + // + // Then data sections. + // + mDataOffset = mCoffOffset; + SectionCount = 0; + for (i = 0; i < mEhdr->e_shnum; i++) { + Elf_Shdr *shdr = GetShdrByIndex(i); + if (IsDataShdr(shdr)) { + if ((shdr->sh_addralign != 0) && (shdr->sh_addralign != 1)) { + // the alignment field is valid + if ((shdr->sh_addr & (shdr->sh_addralign - 1)) == 0) { + // if the section address is aligned we must align PE/COFF + mCoffOffset = (UINT32) ((mCoffOffset + shdr->sh_addralign - 1) & ~(shdr->sh_addralign - 1)); + } else if ((shdr->sh_addr % shdr->sh_addralign) != (mCoffOffset % shdr->sh_addralign)) { + // ARM RVCT tools have behavior outside of the ELF specification to try + // and make images smaller. If sh_addr is not aligned to sh_addralign + // then the section needs to preserve sh_addr MOD sh_addralign. + // Normally doing nothing here works great. + Error (NULL, 0, 3000, "Invalid", "Unsupported section alignment."); + } + } + mCoffSectionsOffset[i] = mCoffOffset; + mCoffOffset += (UINT32) shdr->sh_size; + SectionCount ++; + } + } + mCoffOffset = CoffAlign(mCoffOffset); + + if (SectionCount > 1 && mOutImageType == FW_EFI_IMAGE) { + Warning (NULL, 0, 0, NULL, "Mulitple sections in %s are merged into 1 data section. Source level debug might not work correctly.", mInImageName); + } + + // + // The HII resource sections. + // + mHiiRsrcOffset = mCoffOffset; + for (i = 0; i < mEhdr->e_shnum; i++) { + Elf_Shdr *shdr = GetShdrByIndex(i); + if (IsHiiRsrcShdr(shdr)) { + if ((shdr->sh_addralign != 0) && (shdr->sh_addralign != 1)) { + // the alignment field is valid + if ((shdr->sh_addr & (shdr->sh_addralign - 1)) == 0) { + // if the section address is aligned we must align PE/COFF + mCoffOffset = (UINT32) ((mCoffOffset + shdr->sh_addralign - 1) & ~(shdr->sh_addralign - 1)); + } else if ((shdr->sh_addr % shdr->sh_addralign) != (mCoffOffset % shdr->sh_addralign)) { + // ARM RVCT tools have behavior outside of the ELF specification to try + // and make images smaller. If sh_addr is not aligned to sh_addralign + // then the section needs to preserve sh_addr MOD sh_addralign. + // Normally doing nothing here works great. + Error (NULL, 0, 3000, "Invalid", "Unsupported section alignment."); + } + } + if (shdr->sh_size != 0) { + mCoffSectionsOffset[i] = mCoffOffset; + mCoffOffset += (UINT32) shdr->sh_size; + mCoffOffset = CoffAlign(mCoffOffset); + SetHiiResourceHeader ((UINT8*) mEhdr + shdr->sh_offset, mHiiRsrcOffset); + } + break; + } + } + + mRelocOffset = mCoffOffset; + + // + // Allocate base Coff file. Will be expanded later for relocations. + // + mCoffFile = (UINT8 *)malloc(mCoffOffset); + memset(mCoffFile, 0, mCoffOffset); + + // + // Fill headers. + // + DosHdr = (EFI_IMAGE_DOS_HEADER *)mCoffFile; + DosHdr->e_magic = EFI_IMAGE_DOS_SIGNATURE; + DosHdr->e_lfanew = mNtHdrOffset; + + NtHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION*)(mCoffFile + mNtHdrOffset); + + NtHdr->Pe32Plus.Signature = EFI_IMAGE_NT_SIGNATURE; + + switch (mEhdr->e_machine) { + case EM_X86_64: + NtHdr->Pe32Plus.FileHeader.Machine = EFI_IMAGE_MACHINE_X64; + NtHdr->Pe32Plus.OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC; + break; + case EM_IA_64: + NtHdr->Pe32Plus.FileHeader.Machine = EFI_IMAGE_MACHINE_IPF; + NtHdr->Pe32Plus.OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC; + break; + case EM_AARCH64: + NtHdr->Pe32Plus.FileHeader.Machine = EFI_IMAGE_MACHINE_AARCH64; + NtHdr->Pe32Plus.OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC; + break; + default: + VerboseMsg ("%s unknown e_machine type. Assume X64", (UINTN)mEhdr->e_machine); + NtHdr->Pe32Plus.FileHeader.Machine = EFI_IMAGE_MACHINE_X64; + NtHdr->Pe32Plus.OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC; + } + + NtHdr->Pe32Plus.FileHeader.NumberOfSections = mCoffNbrSections; + NtHdr->Pe32Plus.FileHeader.TimeDateStamp = (UINT32) time(NULL); + mImageTimeStamp = NtHdr->Pe32Plus.FileHeader.TimeDateStamp; + NtHdr->Pe32Plus.FileHeader.PointerToSymbolTable = 0; + NtHdr->Pe32Plus.FileHeader.NumberOfSymbols = 0; + NtHdr->Pe32Plus.FileHeader.SizeOfOptionalHeader = sizeof(NtHdr->Pe32Plus.OptionalHeader); + NtHdr->Pe32Plus.FileHeader.Characteristics = EFI_IMAGE_FILE_EXECUTABLE_IMAGE + | EFI_IMAGE_FILE_LINE_NUMS_STRIPPED + | EFI_IMAGE_FILE_LOCAL_SYMS_STRIPPED + | EFI_IMAGE_FILE_LARGE_ADDRESS_AWARE; + + NtHdr->Pe32Plus.OptionalHeader.SizeOfCode = mDataOffset - mTextOffset; + NtHdr->Pe32Plus.OptionalHeader.SizeOfInitializedData = mRelocOffset - mDataOffset; + NtHdr->Pe32Plus.OptionalHeader.SizeOfUninitializedData = 0; + NtHdr->Pe32Plus.OptionalHeader.AddressOfEntryPoint = CoffEntry; + + NtHdr->Pe32Plus.OptionalHeader.BaseOfCode = mTextOffset; + + NtHdr->Pe32Plus.OptionalHeader.ImageBase = 0; + NtHdr->Pe32Plus.OptionalHeader.SectionAlignment = mCoffAlignment; + NtHdr->Pe32Plus.OptionalHeader.FileAlignment = mCoffAlignment; + NtHdr->Pe32Plus.OptionalHeader.SizeOfImage = 0; + + NtHdr->Pe32Plus.OptionalHeader.SizeOfHeaders = mTextOffset; + NtHdr->Pe32Plus.OptionalHeader.NumberOfRvaAndSizes = EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES; + + // + // Section headers. + // + if ((mDataOffset - mTextOffset) > 0) { + CreateSectionHeader (".text", mTextOffset, mDataOffset - mTextOffset, + EFI_IMAGE_SCN_CNT_CODE + | EFI_IMAGE_SCN_MEM_EXECUTE + | EFI_IMAGE_SCN_MEM_READ); + } else { + // Don't make a section of size 0. + NtHdr->Pe32Plus.FileHeader.NumberOfSections--; + } + + if ((mHiiRsrcOffset - mDataOffset) > 0) { + CreateSectionHeader (".data", mDataOffset, mHiiRsrcOffset - mDataOffset, + EFI_IMAGE_SCN_CNT_INITIALIZED_DATA + | EFI_IMAGE_SCN_MEM_WRITE + | EFI_IMAGE_SCN_MEM_READ); + } else { + // Don't make a section of size 0. + NtHdr->Pe32Plus.FileHeader.NumberOfSections--; + } + + if ((mRelocOffset - mHiiRsrcOffset) > 0) { + CreateSectionHeader (".rsrc", mHiiRsrcOffset, mRelocOffset - mHiiRsrcOffset, + EFI_IMAGE_SCN_CNT_INITIALIZED_DATA + | EFI_IMAGE_SCN_MEM_READ); + + NtHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].Size = mRelocOffset - mHiiRsrcOffset; + NtHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress = mHiiRsrcOffset; + } else { + // Don't make a section of size 0. + NtHdr->Pe32Plus.FileHeader.NumberOfSections--; + } + +} + +STATIC +BOOLEAN +WriteSections64 ( + SECTION_FILTER_TYPES FilterType + ) +{ + UINT32 Idx; + Elf_Shdr *SecShdr; + UINT32 SecOffset; + BOOLEAN (*Filter)(Elf_Shdr *); + + // + // Initialize filter pointer + // + switch (FilterType) { + case SECTION_TEXT: + Filter = IsTextShdr; + break; + case SECTION_HII: + Filter = IsHiiRsrcShdr; + break; + case SECTION_DATA: + Filter = IsDataShdr; + break; + default: + return FALSE; + } + + // + // First: copy sections. + // + for (Idx = 0; Idx < mEhdr->e_shnum; Idx++) { + Elf_Shdr *Shdr = GetShdrByIndex(Idx); + if ((*Filter)(Shdr)) { + switch (Shdr->sh_type) { + case SHT_PROGBITS: + /* Copy. */ + memcpy(mCoffFile + mCoffSectionsOffset[Idx], + (UINT8*)mEhdr + Shdr->sh_offset, + (size_t) Shdr->sh_size); + break; + + case SHT_NOBITS: + memset(mCoffFile + mCoffSectionsOffset[Idx], 0, (size_t) Shdr->sh_size); + break; + + default: + // + // Ignore for unkown section type. + // + VerboseMsg ("%s unknown section type %x. We directly copy this section into Coff file", mInImageName, (unsigned)Shdr->sh_type); + break; + } + } + } + + // + // Second: apply relocations. + // + VerboseMsg ("Applying Relocations..."); + for (Idx = 0; Idx < mEhdr->e_shnum; Idx++) { + // + // Determine if this is a relocation section. + // + Elf_Shdr *RelShdr = GetShdrByIndex(Idx); + if ((RelShdr->sh_type != SHT_REL) && (RelShdr->sh_type != SHT_RELA)) { + continue; + } + + // + // Relocation section found. Now extract section information that the relocations + // apply to in the ELF data and the new COFF data. + // + SecShdr = GetShdrByIndex(RelShdr->sh_info); + SecOffset = mCoffSectionsOffset[RelShdr->sh_info]; + + // + // Only process relocations for the current filter type. + // + if (RelShdr->sh_type == SHT_RELA && (*Filter)(SecShdr)) { + UINT64 RelIdx; + + // + // Determine the symbol table referenced by the relocation data. + // + Elf_Shdr *SymtabShdr = GetShdrByIndex(RelShdr->sh_link); + UINT8 *Symtab = (UINT8*)mEhdr + SymtabShdr->sh_offset; + + // + // Process all relocation entries for this section. + // + for (RelIdx = 0; RelIdx < RelShdr->sh_size; RelIdx += (UINT32) RelShdr->sh_entsize) { + + // + // Set pointer to relocation entry + // + Elf_Rela *Rel = (Elf_Rela *)((UINT8*)mEhdr + RelShdr->sh_offset + RelIdx); + + // + // Set pointer to symbol table entry associated with the relocation entry. + // + Elf_Sym *Sym = (Elf_Sym *)(Symtab + ELF_R_SYM(Rel->r_info) * SymtabShdr->sh_entsize); + + Elf_Shdr *SymShdr; + UINT8 *Targ; + + // + // Check section header index found in symbol table and get the section + // header location. + // + if (Sym->st_shndx == SHN_UNDEF + || Sym->st_shndx == SHN_ABS + || Sym->st_shndx > mEhdr->e_shnum) { + Error (NULL, 0, 3000, "Invalid", "%s bad symbol definition.", mInImageName); + } + SymShdr = GetShdrByIndex(Sym->st_shndx); + + // + // Convert the relocation data to a pointer into the coff file. + // + // Note: + // r_offset is the virtual address of the storage unit to be relocated. + // sh_addr is the virtual address for the base of the section. + // + // r_offset in a memory address. + // Convert it to a pointer in the coff file. + // + Targ = mCoffFile + SecOffset + (Rel->r_offset - SecShdr->sh_addr); + + // + // Determine how to handle each relocation type based on the machine type. + // + if (mEhdr->e_machine == EM_X86_64) { + switch (ELF_R_TYPE(Rel->r_info)) { + case R_X86_64_NONE: + break; + case R_X86_64_64: + // + // Absolute relocation. + // + VerboseMsg ("R_X86_64_64"); + VerboseMsg ("Offset: 0x%08X, Addend: 0x%016LX", + (UINT32)(SecOffset + (Rel->r_offset - SecShdr->sh_addr)), + *(UINT64 *)Targ); + *(UINT64 *)Targ = *(UINT64 *)Targ - SymShdr->sh_addr + mCoffSectionsOffset[Sym->st_shndx]; + VerboseMsg ("Relocation: 0x%016LX", *(UINT64*)Targ); + break; + case R_X86_64_32: + VerboseMsg ("R_X86_64_32"); + VerboseMsg ("Offset: 0x%08X, Addend: 0x%08X", + (UINT32)(SecOffset + (Rel->r_offset - SecShdr->sh_addr)), + *(UINT32 *)Targ); + *(UINT32 *)Targ = (UINT32)((UINT64)(*(UINT32 *)Targ) - SymShdr->sh_addr + mCoffSectionsOffset[Sym->st_shndx]); + VerboseMsg ("Relocation: 0x%08X", *(UINT32*)Targ); + break; + case R_X86_64_32S: + VerboseMsg ("R_X86_64_32S"); + VerboseMsg ("Offset: 0x%08X, Addend: 0x%08X", + (UINT32)(SecOffset + (Rel->r_offset - SecShdr->sh_addr)), + *(UINT32 *)Targ); + *(INT32 *)Targ = (INT32)((INT64)(*(INT32 *)Targ) - SymShdr->sh_addr + mCoffSectionsOffset[Sym->st_shndx]); + VerboseMsg ("Relocation: 0x%08X", *(UINT32*)Targ); + break; + case R_X86_64_PC32: + // + // Relative relocation: Symbol - Ip + Addend + // + VerboseMsg ("R_X86_64_PC32"); + VerboseMsg ("Offset: 0x%08X, Addend: 0x%08X", + (UINT32)(SecOffset + (Rel->r_offset - SecShdr->sh_addr)), + *(UINT32 *)Targ); + *(UINT32 *)Targ = (UINT32) (*(UINT32 *)Targ + + (mCoffSectionsOffset[Sym->st_shndx] - SymShdr->sh_addr) + - (SecOffset - SecShdr->sh_addr)); + VerboseMsg ("Relocation: 0x%08X", *(UINT32 *)Targ); + break; + default: + Error (NULL, 0, 3000, "Invalid", "%s unsupported ELF EM_X86_64 relocation 0x%x.", mInImageName, (unsigned) ELF_R_TYPE(Rel->r_info)); + } + } else if (mEhdr->e_machine == EM_AARCH64) { + + // AARCH64 GCC uses RELA relocation, so all relocations have to be fixed up. + // As opposed to ARM32 using REL. + + switch (ELF_R_TYPE(Rel->r_info)) { + + case R_AARCH64_LD_PREL_LO19: + if (Rel->r_addend != 0 ) { /* TODO */ + Error (NULL, 0, 3000, "Invalid", "AArch64: R_AARCH64_LD_PREL_LO19 Need to fixup with addend!."); + } + break; + + case R_AARCH64_CALL26: + if (Rel->r_addend != 0 ) { /* TODO */ + Error (NULL, 0, 3000, "Invalid", "AArch64: R_AARCH64_CALL26 Need to fixup with addend!."); + } + break; + + case R_AARCH64_JUMP26: + if (Rel->r_addend != 0 ) { /* TODO : AArch64 '-O2' optimisation. */ + Error (NULL, 0, 3000, "Invalid", "AArch64: R_AARCH64_JUMP26 Need to fixup with addend!."); + } + break; + + case R_AARCH64_ADR_PREL_PG_HI21: + // TODO : AArch64 'small' memory model. + Error (NULL, 0, 3000, "Invalid", "WriteSections64(): %s unsupported ELF EM_AARCH64 relocation R_AARCH64_ADR_PREL_PG_HI21.", mInImageName); + break; + + case R_AARCH64_ADD_ABS_LO12_NC: + // TODO : AArch64 'small' memory model. + Error (NULL, 0, 3000, "Invalid", "WriteSections64(): %s unsupported ELF EM_AARCH64 relocation R_AARCH64_ADD_ABS_LO12_NC.", mInImageName); + break; + + // Absolute relocations. + case R_AARCH64_ABS64: + *(UINT64 *)Targ = *(UINT64 *)Targ - SymShdr->sh_addr + mCoffSectionsOffset[Sym->st_shndx]; + break; + + default: + Error (NULL, 0, 3000, "Invalid", "WriteSections64(): %s unsupported ELF EM_AARCH64 relocation 0x%x.", mInImageName, (unsigned) ELF_R_TYPE(Rel->r_info)); + } + } else { + Error (NULL, 0, 3000, "Invalid", "Not a supported machine type"); + } + } + } + } + + return TRUE; +} + +STATIC +VOID +WriteRelocations64 ( + VOID + ) +{ + UINT32 Index; + EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr; + EFI_IMAGE_DATA_DIRECTORY *Dir; + + for (Index = 0; Index < mEhdr->e_shnum; Index++) { + Elf_Shdr *RelShdr = GetShdrByIndex(Index); + if ((RelShdr->sh_type == SHT_REL) || (RelShdr->sh_type == SHT_RELA)) { + Elf_Shdr *SecShdr = GetShdrByIndex (RelShdr->sh_info); + if (IsTextShdr(SecShdr) || IsDataShdr(SecShdr)) { + UINT64 RelIdx; + + for (RelIdx = 0; RelIdx < RelShdr->sh_size; RelIdx += RelShdr->sh_entsize) { + Elf_Rela *Rel = (Elf_Rela *)((UINT8*)mEhdr + RelShdr->sh_offset + RelIdx); + + if (mEhdr->e_machine == EM_X86_64) { + switch (ELF_R_TYPE(Rel->r_info)) { + case R_X86_64_NONE: + case R_X86_64_PC32: + break; + case R_X86_64_64: + VerboseMsg ("EFI_IMAGE_REL_BASED_DIR64 Offset: 0x%08X", + mCoffSectionsOffset[RelShdr->sh_info] + (Rel->r_offset - SecShdr->sh_addr)); + CoffAddFixup( + (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info] + + (Rel->r_offset - SecShdr->sh_addr)), + EFI_IMAGE_REL_BASED_DIR64); + break; + case R_X86_64_32S: + case R_X86_64_32: + VerboseMsg ("EFI_IMAGE_REL_BASED_HIGHLOW Offset: 0x%08X", + mCoffSectionsOffset[RelShdr->sh_info] + (Rel->r_offset - SecShdr->sh_addr)); + CoffAddFixup( + (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info] + + (Rel->r_offset - SecShdr->sh_addr)), + EFI_IMAGE_REL_BASED_HIGHLOW); + break; + default: + Error (NULL, 0, 3000, "Invalid", "%s unsupported ELF EM_X86_64 relocation 0x%x.", mInImageName, (unsigned) ELF_R_TYPE(Rel->r_info)); + } + } else if (mEhdr->e_machine == EM_AARCH64) { + // AArch64 GCC uses RELA relocation, so all relocations has to be fixed up. ARM32 uses REL. + switch (ELF_R_TYPE(Rel->r_info)) { + case R_AARCH64_LD_PREL_LO19: + break; + + case R_AARCH64_CALL26: + break; + + case R_AARCH64_JUMP26: + break; + + case R_AARCH64_ADR_PREL_PG_HI21: + // TODO : AArch64 'small' memory model. + Error (NULL, 0, 3000, "Invalid", "WriteRelocations64(): %s unsupported ELF EM_AARCH64 relocation R_AARCH64_ADR_PREL_PG_HI21.", mInImageName); + break; + + case R_AARCH64_ADD_ABS_LO12_NC: + // TODO : AArch64 'small' memory model. + Error (NULL, 0, 3000, "Invalid", "WriteRelocations64(): %s unsupported ELF EM_AARCH64 relocation R_AARCH64_ADD_ABS_LO12_NC.", mInImageName); + break; + + case R_AARCH64_ABS64: + CoffAddFixup( + (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info] + + (Rel->r_offset - SecShdr->sh_addr)), + EFI_IMAGE_REL_BASED_DIR64); + break; + + case R_AARCH64_ABS32: + CoffAddFixup( + (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info] + + (Rel->r_offset - SecShdr->sh_addr)), + EFI_IMAGE_REL_BASED_HIGHLOW); + break; + + default: + Error (NULL, 0, 3000, "Invalid", "WriteRelocations64(): %s unsupported ELF EM_AARCH64 relocation 0x%x.", mInImageName, (unsigned) ELF_R_TYPE(Rel->r_info)); + } + } else { + Error (NULL, 0, 3000, "Not Supported", "This tool does not support relocations for ELF with e_machine %u (processor type).", (unsigned) mEhdr->e_machine); + } + } + } + } + } + + // + // Pad by adding empty entries. + // + while (mCoffOffset & (mCoffAlignment - 1)) { + CoffAddFixupEntry(0); + } + + NtHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(mCoffFile + mNtHdrOffset); + Dir = &NtHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC]; + Dir->Size = mCoffOffset - mRelocOffset; + if (Dir->Size == 0) { + // If no relocations, null out the directory entry and don't add the .reloc section + Dir->VirtualAddress = 0; + NtHdr->Pe32Plus.FileHeader.NumberOfSections--; + } else { + Dir->VirtualAddress = mRelocOffset; + CreateSectionHeader (".reloc", mRelocOffset, mCoffOffset - mRelocOffset, + EFI_IMAGE_SCN_CNT_INITIALIZED_DATA + | EFI_IMAGE_SCN_MEM_DISCARDABLE + | EFI_IMAGE_SCN_MEM_READ); + } +} + +STATIC +VOID +WriteDebug64 ( + VOID + ) +{ + UINT32 Len; + UINT32 DebugOffset; + EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr; + EFI_IMAGE_DATA_DIRECTORY *DataDir; + EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *Dir; + EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY *Nb10; + + Len = strlen(mInImageName) + 1; + DebugOffset = mCoffOffset; + + mCoffOffset += sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY) + + sizeof(EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY) + + Len; + mCoffOffset = CoffAlign(mCoffOffset); + + mCoffFile = realloc(mCoffFile, mCoffOffset); + memset(mCoffFile + DebugOffset, 0, mCoffOffset - DebugOffset); + + Dir = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY*)(mCoffFile + DebugOffset); + Dir->Type = EFI_IMAGE_DEBUG_TYPE_CODEVIEW; + Dir->SizeOfData = sizeof(EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY) + Len; + Dir->RVA = DebugOffset + sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY); + Dir->FileOffset = DebugOffset + sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY); + + Nb10 = (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY*)(Dir + 1); + Nb10->Signature = CODEVIEW_SIGNATURE_NB10; + strcpy ((char *)(Nb10 + 1), mInImageName); + + + NtHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(mCoffFile + mNtHdrOffset); + DataDir = &NtHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]; + DataDir->VirtualAddress = DebugOffset; + DataDir->Size = mCoffOffset - DebugOffset; + if (DataDir->Size == 0) { + // If no debug, null out the directory entry and don't add the .debug section + DataDir->VirtualAddress = 0; + NtHdr->Pe32Plus.FileHeader.NumberOfSections--; + } else { + DataDir->VirtualAddress = DebugOffset; + CreateSectionHeader (".debug", DebugOffset, mCoffOffset - DebugOffset, + EFI_IMAGE_SCN_CNT_INITIALIZED_DATA + | EFI_IMAGE_SCN_MEM_DISCARDABLE + | EFI_IMAGE_SCN_MEM_READ); + + } +} + +STATIC +VOID +SetImageSize64 ( + VOID + ) +{ + EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr; + + // + // Set image size + // + NtHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(mCoffFile + mNtHdrOffset); + NtHdr->Pe32Plus.OptionalHeader.SizeOfImage = mCoffOffset; +} + +STATIC +VOID +CleanUp64 ( + VOID + ) +{ + if (mCoffSectionsOffset != NULL) { + free (mCoffSectionsOffset); + } +} + + diff --git a/BaseTools/Source/C/GenFw/Elf64Convert.h b/BaseTools/Source/C/GenFw/Elf64Convert.h index 1fb95a8e42..1e3a0dfcc2 100644 --- a/BaseTools/Source/C/GenFw/Elf64Convert.h +++ b/BaseTools/Source/C/GenFw/Elf64Convert.h @@ -1,24 +1,24 @@ -/** @file - -Copyright (c) 2010, Intel Corporation. All rights reserved.
- -This program and the accompanying materials are licensed and made available -under the terms and conditions of the BSD License which accompanies this -distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _ELF_64_CONVERT_ -#define _ELF_64_CONVERT_ - -BOOLEAN -InitializeElf64 ( - UINT8 *FileBuffer, - ELF_FUNCTION_TABLE *ElfFunctions - ); - -#endif +/** @file + +Copyright (c) 2010, Intel Corporation. All rights reserved.
+ +This program and the accompanying materials are licensed and made available +under the terms and conditions of the BSD License which accompanies this +distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _ELF_64_CONVERT_ +#define _ELF_64_CONVERT_ + +BOOLEAN +InitializeElf64 ( + UINT8 *FileBuffer, + ELF_FUNCTION_TABLE *ElfFunctions + ); + +#endif diff --git a/BaseTools/Source/C/GenFw/ElfConvert.c b/BaseTools/Source/C/GenFw/ElfConvert.c index e573554d03..17689cf27f 100644 --- a/BaseTools/Source/C/GenFw/ElfConvert.c +++ b/BaseTools/Source/C/GenFw/ElfConvert.c @@ -1,233 +1,233 @@ -/** @file - -Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.
- -This program and the accompanying materials are licensed and made available -under the terms and conditions of the BSD License which accompanies this -distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "WinNtInclude.h" - -#ifndef __GNUC__ -#include -#include -#endif -#include -#include -#include -#include -#include - -#include -#include - -#include "EfiUtilityMsgs.h" - -#include "GenFw.h" -#include "ElfConvert.h" -#include "Elf32Convert.h" -#include "Elf64Convert.h" - -// -// Result Coff file in memory. -// -UINT8 *mCoffFile = NULL; - -// -// COFF relocation data -// -EFI_IMAGE_BASE_RELOCATION *mCoffBaseRel; -UINT16 *mCoffEntryRel; - -// -// Current offset in coff file. -// -UINT32 mCoffOffset; - -// -// Offset in Coff file of headers and sections. -// -UINT32 mTableOffset; - -// -//***************************************************************************** -// Common ELF Functions -//***************************************************************************** -// - -VOID -CoffAddFixupEntry( - UINT16 Val - ) -{ - *mCoffEntryRel = Val; - mCoffEntryRel++; - mCoffBaseRel->SizeOfBlock += 2; - mCoffOffset += 2; -} - -VOID -CoffAddFixup( - UINT32 Offset, - UINT8 Type - ) -{ - if (mCoffBaseRel == NULL - || mCoffBaseRel->VirtualAddress != (Offset & ~0xfff)) { - if (mCoffBaseRel != NULL) { - // - // Add a null entry (is it required ?) - // - CoffAddFixupEntry (0); - - // - // Pad for alignment. - // - if (mCoffOffset % 4 != 0) - CoffAddFixupEntry (0); - } - - mCoffFile = realloc ( - mCoffFile, - mCoffOffset + sizeof(EFI_IMAGE_BASE_RELOCATION) + 2*0x1000 - ); - memset ( - mCoffFile + mCoffOffset, 0, - sizeof(EFI_IMAGE_BASE_RELOCATION) + 2*0x1000 - ); - - mCoffBaseRel = (EFI_IMAGE_BASE_RELOCATION*)(mCoffFile + mCoffOffset); - mCoffBaseRel->VirtualAddress = Offset & ~0xfff; - mCoffBaseRel->SizeOfBlock = sizeof(EFI_IMAGE_BASE_RELOCATION); - - mCoffEntryRel = (UINT16 *)(mCoffBaseRel + 1); - mCoffOffset += sizeof(EFI_IMAGE_BASE_RELOCATION); - } - - // - // Fill the entry. - // - CoffAddFixupEntry((UINT16) ((Type << 12) | (Offset & 0xfff))); -} - -VOID -CreateSectionHeader ( - const CHAR8 *Name, - UINT32 Offset, - UINT32 Size, - UINT32 Flags - ) -{ - EFI_IMAGE_SECTION_HEADER *Hdr; - Hdr = (EFI_IMAGE_SECTION_HEADER*)(mCoffFile + mTableOffset); - - strcpy((char *)Hdr->Name, Name); - Hdr->Misc.VirtualSize = Size; - Hdr->VirtualAddress = Offset; - Hdr->SizeOfRawData = Size; - Hdr->PointerToRawData = Offset; - Hdr->PointerToRelocations = 0; - Hdr->PointerToLinenumbers = 0; - Hdr->NumberOfRelocations = 0; - Hdr->NumberOfLinenumbers = 0; - Hdr->Characteristics = Flags; - - mTableOffset += sizeof (EFI_IMAGE_SECTION_HEADER); -} - -// -//***************************************************************************** -// Functions called from GenFw main code. -//***************************************************************************** -// - -INTN -IsElfHeader ( - UINT8 *FileBuffer -) -{ - return (FileBuffer[EI_MAG0] == ELFMAG0 && - FileBuffer[EI_MAG1] == ELFMAG1 && - FileBuffer[EI_MAG2] == ELFMAG2 && - FileBuffer[EI_MAG3] == ELFMAG3); -} - -BOOLEAN -ConvertElf ( - UINT8 **FileBuffer, - UINT32 *FileLength - ) -{ - ELF_FUNCTION_TABLE ElfFunctions; - UINT8 EiClass; - - // - // Determine ELF type and set function table pointer correctly. - // - VerboseMsg ("Check Elf Image Header"); - EiClass = (*FileBuffer)[EI_CLASS]; - if (EiClass == ELFCLASS32) { - if (!InitializeElf32 (*FileBuffer, &ElfFunctions)) { - return FALSE; - } - } else if (EiClass == ELFCLASS64) { - if (!InitializeElf64 (*FileBuffer, &ElfFunctions)) { - return FALSE; - } - } else { - Error (NULL, 0, 3000, "Unsupported", "ELF EI_CLASS not supported."); - return FALSE; - } - - // - // Compute sections new address. - // - VerboseMsg ("Compute sections new address."); - ElfFunctions.ScanSections (); - - // - // Write and relocate sections. - // - VerboseMsg ("Write and relocate sections."); - ElfFunctions.WriteSections (SECTION_TEXT); - ElfFunctions.WriteSections (SECTION_DATA); - ElfFunctions.WriteSections (SECTION_HII); - - // - // Translate and write relocations. - // - VerboseMsg ("Translate and write relocations."); - ElfFunctions.WriteRelocations (); - - // - // Write debug info. - // - VerboseMsg ("Write debug info."); - ElfFunctions.WriteDebug (); - - // - // Make sure image size is correct before returning the new image. - // - VerboseMsg ("Set image size."); - ElfFunctions.SetImageSize (); - - // - // Replace. - // - free (*FileBuffer); - *FileBuffer = mCoffFile; - *FileLength = mCoffOffset; - - // - // Free resources used by ELF functions. - // - ElfFunctions.CleanUp (); - - return TRUE; -} +/** @file + +Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.
+ +This program and the accompanying materials are licensed and made available +under the terms and conditions of the BSD License which accompanies this +distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "WinNtInclude.h" + +#ifndef __GNUC__ +#include +#include +#endif +#include +#include +#include +#include +#include + +#include +#include + +#include "EfiUtilityMsgs.h" + +#include "GenFw.h" +#include "ElfConvert.h" +#include "Elf32Convert.h" +#include "Elf64Convert.h" + +// +// Result Coff file in memory. +// +UINT8 *mCoffFile = NULL; + +// +// COFF relocation data +// +EFI_IMAGE_BASE_RELOCATION *mCoffBaseRel; +UINT16 *mCoffEntryRel; + +// +// Current offset in coff file. +// +UINT32 mCoffOffset; + +// +// Offset in Coff file of headers and sections. +// +UINT32 mTableOffset; + +// +//***************************************************************************** +// Common ELF Functions +//***************************************************************************** +// + +VOID +CoffAddFixupEntry( + UINT16 Val + ) +{ + *mCoffEntryRel = Val; + mCoffEntryRel++; + mCoffBaseRel->SizeOfBlock += 2; + mCoffOffset += 2; +} + +VOID +CoffAddFixup( + UINT32 Offset, + UINT8 Type + ) +{ + if (mCoffBaseRel == NULL + || mCoffBaseRel->VirtualAddress != (Offset & ~0xfff)) { + if (mCoffBaseRel != NULL) { + // + // Add a null entry (is it required ?) + // + CoffAddFixupEntry (0); + + // + // Pad for alignment. + // + if (mCoffOffset % 4 != 0) + CoffAddFixupEntry (0); + } + + mCoffFile = realloc ( + mCoffFile, + mCoffOffset + sizeof(EFI_IMAGE_BASE_RELOCATION) + 2*0x1000 + ); + memset ( + mCoffFile + mCoffOffset, 0, + sizeof(EFI_IMAGE_BASE_RELOCATION) + 2*0x1000 + ); + + mCoffBaseRel = (EFI_IMAGE_BASE_RELOCATION*)(mCoffFile + mCoffOffset); + mCoffBaseRel->VirtualAddress = Offset & ~0xfff; + mCoffBaseRel->SizeOfBlock = sizeof(EFI_IMAGE_BASE_RELOCATION); + + mCoffEntryRel = (UINT16 *)(mCoffBaseRel + 1); + mCoffOffset += sizeof(EFI_IMAGE_BASE_RELOCATION); + } + + // + // Fill the entry. + // + CoffAddFixupEntry((UINT16) ((Type << 12) | (Offset & 0xfff))); +} + +VOID +CreateSectionHeader ( + const CHAR8 *Name, + UINT32 Offset, + UINT32 Size, + UINT32 Flags + ) +{ + EFI_IMAGE_SECTION_HEADER *Hdr; + Hdr = (EFI_IMAGE_SECTION_HEADER*)(mCoffFile + mTableOffset); + + strcpy((char *)Hdr->Name, Name); + Hdr->Misc.VirtualSize = Size; + Hdr->VirtualAddress = Offset; + Hdr->SizeOfRawData = Size; + Hdr->PointerToRawData = Offset; + Hdr->PointerToRelocations = 0; + Hdr->PointerToLinenumbers = 0; + Hdr->NumberOfRelocations = 0; + Hdr->NumberOfLinenumbers = 0; + Hdr->Characteristics = Flags; + + mTableOffset += sizeof (EFI_IMAGE_SECTION_HEADER); +} + +// +//***************************************************************************** +// Functions called from GenFw main code. +//***************************************************************************** +// + +INTN +IsElfHeader ( + UINT8 *FileBuffer +) +{ + return (FileBuffer[EI_MAG0] == ELFMAG0 && + FileBuffer[EI_MAG1] == ELFMAG1 && + FileBuffer[EI_MAG2] == ELFMAG2 && + FileBuffer[EI_MAG3] == ELFMAG3); +} + +BOOLEAN +ConvertElf ( + UINT8 **FileBuffer, + UINT32 *FileLength + ) +{ + ELF_FUNCTION_TABLE ElfFunctions; + UINT8 EiClass; + + // + // Determine ELF type and set function table pointer correctly. + // + VerboseMsg ("Check Elf Image Header"); + EiClass = (*FileBuffer)[EI_CLASS]; + if (EiClass == ELFCLASS32) { + if (!InitializeElf32 (*FileBuffer, &ElfFunctions)) { + return FALSE; + } + } else if (EiClass == ELFCLASS64) { + if (!InitializeElf64 (*FileBuffer, &ElfFunctions)) { + return FALSE; + } + } else { + Error (NULL, 0, 3000, "Unsupported", "ELF EI_CLASS not supported."); + return FALSE; + } + + // + // Compute sections new address. + // + VerboseMsg ("Compute sections new address."); + ElfFunctions.ScanSections (); + + // + // Write and relocate sections. + // + VerboseMsg ("Write and relocate sections."); + ElfFunctions.WriteSections (SECTION_TEXT); + ElfFunctions.WriteSections (SECTION_DATA); + ElfFunctions.WriteSections (SECTION_HII); + + // + // Translate and write relocations. + // + VerboseMsg ("Translate and write relocations."); + ElfFunctions.WriteRelocations (); + + // + // Write debug info. + // + VerboseMsg ("Write debug info."); + ElfFunctions.WriteDebug (); + + // + // Make sure image size is correct before returning the new image. + // + VerboseMsg ("Set image size."); + ElfFunctions.SetImageSize (); + + // + // Replace. + // + free (*FileBuffer); + *FileBuffer = mCoffFile; + *FileLength = mCoffOffset; + + // + // Free resources used by ELF functions. + // + ElfFunctions.CleanUp (); + + return TRUE; +} diff --git a/BaseTools/Source/C/GenFw/ElfConvert.h b/BaseTools/Source/C/GenFw/ElfConvert.h index 185dbb759c..241dd6f44f 100644 --- a/BaseTools/Source/C/GenFw/ElfConvert.h +++ b/BaseTools/Source/C/GenFw/ElfConvert.h @@ -1,83 +1,83 @@ -/** @file - -Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.
- -This program and the accompanying materials are licensed and made available -under the terms and conditions of the BSD License which accompanies this -distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _ELF_CONVERT_H_ -#define _ELF_CONVERT_H_ - -#include "elf_common.h" -#include "elf32.h" -#include "elf64.h" - -// -// Externally defined variables -// -extern UINT32 mCoffOffset; -extern CHAR8 *mInImageName; -extern UINT32 mImageTimeStamp; -extern UINT8 *mCoffFile; -extern UINT32 mTableOffset; -extern UINT32 mOutImageType; - -// -// Common EFI specific data. -// -#define ELF_HII_SECTION_NAME ".hii" - -// -// Filter Types -// -typedef enum { - SECTION_TEXT, - SECTION_HII, - SECTION_DATA - -} SECTION_FILTER_TYPES; - -// -// FunctionTalbe -// -typedef struct { - VOID (*ScanSections) (); - BOOLEAN (*WriteSections) (SECTION_FILTER_TYPES FilterType); - VOID (*WriteRelocations) (); - VOID (*WriteDebug) (); - VOID (*SetImageSize) (); - VOID (*CleanUp) (); - -} ELF_FUNCTION_TABLE; - -// -// Common functions -// -VOID -CoffAddFixup ( - UINT32 Offset, - UINT8 Type - ); - -VOID -CoffAddFixupEntry ( - UINT16 Val - ); - - -VOID -CreateSectionHeader ( - const CHAR8 *Name, - UINT32 Offset, - UINT32 Size, - UINT32 Flags - ); - -#endif +/** @file + +Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.
+ +This program and the accompanying materials are licensed and made available +under the terms and conditions of the BSD License which accompanies this +distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _ELF_CONVERT_H_ +#define _ELF_CONVERT_H_ + +#include "elf_common.h" +#include "elf32.h" +#include "elf64.h" + +// +// Externally defined variables +// +extern UINT32 mCoffOffset; +extern CHAR8 *mInImageName; +extern UINT32 mImageTimeStamp; +extern UINT8 *mCoffFile; +extern UINT32 mTableOffset; +extern UINT32 mOutImageType; + +// +// Common EFI specific data. +// +#define ELF_HII_SECTION_NAME ".hii" + +// +// Filter Types +// +typedef enum { + SECTION_TEXT, + SECTION_HII, + SECTION_DATA + +} SECTION_FILTER_TYPES; + +// +// FunctionTalbe +// +typedef struct { + VOID (*ScanSections) (); + BOOLEAN (*WriteSections) (SECTION_FILTER_TYPES FilterType); + VOID (*WriteRelocations) (); + VOID (*WriteDebug) (); + VOID (*SetImageSize) (); + VOID (*CleanUp) (); + +} ELF_FUNCTION_TABLE; + +// +// Common functions +// +VOID +CoffAddFixup ( + UINT32 Offset, + UINT8 Type + ); + +VOID +CoffAddFixupEntry ( + UINT16 Val + ); + + +VOID +CreateSectionHeader ( + const CHAR8 *Name, + UINT32 Offset, + UINT32 Size, + UINT32 Flags + ); + +#endif diff --git a/BaseTools/Source/C/GenFw/GenFw.h b/BaseTools/Source/C/GenFw/GenFw.h index e36dc085ff..5249337745 100644 --- a/BaseTools/Source/C/GenFw/GenFw.h +++ b/BaseTools/Source/C/GenFw/GenFw.h @@ -1,55 +1,55 @@ -/** @file - -Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.
- -This program and the accompanying materials are licensed and made available -under the terms and conditions of the BSD License which accompanies this -distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _GEN_FW_H_ -#define _GEN_FW_H_ - -// -// Action for this tool. -// -#define FW_DUMMY_IMAGE 0 -#define FW_EFI_IMAGE 1 -#define FW_TE_IMAGE 2 -#define FW_ACPI_IMAGE 3 -#define FW_BIN_IMAGE 4 -#define FW_ZERO_DEBUG_IMAGE 5 -#define FW_SET_STAMP_IMAGE 6 -#define FW_MCI_IMAGE 7 -#define FW_MERGE_IMAGE 8 -#define FW_RELOC_STRIPEED_IMAGE 9 -#define FW_HII_PACKAGE_LIST_RCIMAGE 10 -#define FW_HII_PACKAGE_LIST_BINIMAGE 11 -#define FW_REBASE_IMAGE 12 -#define FW_SET_ADDRESS_IMAGE 13 - -#define DUMP_TE_HEADER 0x11 - -VOID -SetHiiResourceHeader ( - UINT8 *HiiBinData, - UINT32 OffsetToFile - ); - -INTN -IsElfHeader ( - UINT8 *FileBuffer - ); - -BOOLEAN -ConvertElf ( - UINT8 **FileBuffer, - UINT32 *FileLength - ); - -#endif +/** @file + +Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.
+ +This program and the accompanying materials are licensed and made available +under the terms and conditions of the BSD License which accompanies this +distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _GEN_FW_H_ +#define _GEN_FW_H_ + +// +// Action for this tool. +// +#define FW_DUMMY_IMAGE 0 +#define FW_EFI_IMAGE 1 +#define FW_TE_IMAGE 2 +#define FW_ACPI_IMAGE 3 +#define FW_BIN_IMAGE 4 +#define FW_ZERO_DEBUG_IMAGE 5 +#define FW_SET_STAMP_IMAGE 6 +#define FW_MCI_IMAGE 7 +#define FW_MERGE_IMAGE 8 +#define FW_RELOC_STRIPEED_IMAGE 9 +#define FW_HII_PACKAGE_LIST_RCIMAGE 10 +#define FW_HII_PACKAGE_LIST_BINIMAGE 11 +#define FW_REBASE_IMAGE 12 +#define FW_SET_ADDRESS_IMAGE 13 + +#define DUMP_TE_HEADER 0x11 + +VOID +SetHiiResourceHeader ( + UINT8 *HiiBinData, + UINT32 OffsetToFile + ); + +INTN +IsElfHeader ( + UINT8 *FileBuffer + ); + +BOOLEAN +ConvertElf ( + UINT8 **FileBuffer, + UINT32 *FileLength + ); + +#endif diff --git a/BaseTools/Source/C/GenFw/elf32.h b/BaseTools/Source/C/GenFw/elf32.h index 63946aad84..dd4e132598 100644 --- a/BaseTools/Source/C/GenFw/elf32.h +++ b/BaseTools/Source/C/GenFw/elf32.h @@ -1,258 +1,258 @@ -/** @file -Ported ELF include files from FreeBSD - -Copyright (c) 2009 - 2010, Apple Inc. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - -**/ -/*- - * Copyright (c) 1996-1998 John D. Polstra. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD: src/sys/sys/elf32.h,v 1.8.14.2 2007/12/03 21:30:36 marius Exp $ - */ - -#ifndef _SYS_ELF32_H_ -#define _SYS_ELF32_H_ 1 - - -/* - * ELF definitions common to all 32-bit architectures. - */ - -typedef UINT32 Elf32_Addr; -typedef UINT16 Elf32_Half; -typedef UINT32 Elf32_Off; -typedef INT32 Elf32_Sword; -typedef UINT32 Elf32_Word; -typedef UINT64 Elf32_Lword; - -typedef Elf32_Word Elf32_Hashelt; - -/* Non-standard class-dependent datatype used for abstraction. */ -typedef Elf32_Word Elf32_Size; -typedef Elf32_Sword Elf32_Ssize; - -/* - * ELF header. - */ - -typedef struct { - unsigned char e_ident[EI_NIDENT]; /* File identification. */ - Elf32_Half e_type; /* File type. */ - Elf32_Half e_machine; /* Machine architecture. */ - Elf32_Word e_version; /* ELF format version. */ - Elf32_Addr e_entry; /* Entry point. */ - Elf32_Off e_phoff; /* Program header file offset. */ - Elf32_Off e_shoff; /* Section header file offset. */ - Elf32_Word e_flags; /* Architecture-specific flags. */ - Elf32_Half e_ehsize; /* Size of ELF header in bytes. */ - Elf32_Half e_phentsize; /* Size of program header entry. */ - Elf32_Half e_phnum; /* Number of program header entries. */ - Elf32_Half e_shentsize; /* Size of section header entry. */ - Elf32_Half e_shnum; /* Number of section header entries. */ - Elf32_Half e_shstrndx; /* Section name strings section. */ -} Elf32_Ehdr; - -/* - * Section header. - */ - -typedef struct { - Elf32_Word sh_name; /* Section name (index into the - section header string table). */ - Elf32_Word sh_type; /* Section type. */ - Elf32_Word sh_flags; /* Section flags. */ - Elf32_Addr sh_addr; /* Address in memory image. */ - Elf32_Off sh_offset; /* Offset in file. */ - Elf32_Word sh_size; /* Size in bytes. */ - Elf32_Word sh_link; /* Index of a related section. */ - Elf32_Word sh_info; /* Depends on section type. */ - Elf32_Word sh_addralign; /* Alignment in bytes. */ - Elf32_Word sh_entsize; /* Size of each entry in section. */ -} Elf32_Shdr; - -/* - * Program header. - */ - -typedef struct { - Elf32_Word p_type; /* Entry type. */ - Elf32_Off p_offset; /* File offset of contents. */ - Elf32_Addr p_vaddr; /* Virtual address in memory image. */ - Elf32_Addr p_paddr; /* Physical address (not used). */ - Elf32_Word p_filesz; /* Size of contents in file. */ - Elf32_Word p_memsz; /* Size of contents in memory. */ - Elf32_Word p_flags; /* Access permission flags. */ - Elf32_Word p_align; /* Alignment in memory and file. */ -} Elf32_Phdr; - -/* - * Dynamic structure. The ".dynamic" section contains an array of them. - */ - -typedef struct { - Elf32_Sword d_tag; /* Entry type. */ - union { - Elf32_Word d_val; /* Integer value. */ - Elf32_Addr d_ptr; /* Address value. */ - } d_un; -} Elf32_Dyn; - -/* - * Relocation entries. - */ - -/* Relocations that don't need an addend field. */ -typedef struct { - Elf32_Addr r_offset; /* Location to be relocated. */ - Elf32_Word r_info; /* Relocation type and symbol index. */ -} Elf32_Rel; - -/* Relocations that need an addend field. */ -typedef struct { - Elf32_Addr r_offset; /* Location to be relocated. */ - Elf32_Word r_info; /* Relocation type and symbol index. */ - Elf32_Sword r_addend; /* Addend. */ -} Elf32_Rela; - -/* Macros for accessing the fields of r_info. */ -#define ELF32_R_SYM(info) ((info) >> 8) -#define ELF32_R_TYPE(info) ((unsigned char)(info)) - -/* Macro for constructing r_info from field values. */ -#define ELF32_R_INFO(sym, type) (((sym) << 8) + (unsigned char)(type)) - -/* - * Note entry header - */ -typedef Elf_Note Elf32_Nhdr; - -/* - * Move entry - */ -typedef struct { - Elf32_Lword m_value; /* symbol value */ - Elf32_Word m_info; /* size + index */ - Elf32_Word m_poffset; /* symbol offset */ - Elf32_Half m_repeat; /* repeat count */ - Elf32_Half m_stride; /* stride info */ -} Elf32_Move; - -/* - * The macros compose and decompose values for Move.r_info - * - * sym = ELF32_M_SYM(M.m_info) - * size = ELF32_M_SIZE(M.m_info) - * M.m_info = ELF32_M_INFO(sym, size) - */ -#define ELF32_M_SYM(info) ((info)>>8) -#define ELF32_M_SIZE(info) ((unsigned char)(info)) -#define ELF32_M_INFO(sym, size) (((sym)<<8)+(unsigned char)(size)) - -/* - * Hardware/Software capabilities entry - */ -typedef struct { - Elf32_Word c_tag; /* how to interpret value */ - union { - Elf32_Word c_val; - Elf32_Addr c_ptr; - } c_un; -} Elf32_Cap; - -/* - * Symbol table entries. - */ - -typedef struct { - Elf32_Word st_name; /* String table index of name. */ - Elf32_Addr st_value; /* Symbol value. */ - Elf32_Word st_size; /* Size of associated object. */ - unsigned char st_info; /* Type and binding information. */ - unsigned char st_other; /* Reserved (not used). */ - Elf32_Half st_shndx; /* Section index of symbol. */ -} Elf32_Sym; - -/* Macros for accessing the fields of st_info. */ -#define ELF32_ST_BIND(info) ((info) >> 4) -#define ELF32_ST_TYPE(info) ((info) & 0xf) - -/* Macro for constructing st_info from field values. */ -#define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf)) - -/* Macro for accessing the fields of st_other. */ -#define ELF32_ST_VISIBILITY(oth) ((oth) & 0x3) - -/* Structures used by Sun & GNU symbol versioning. */ -typedef struct -{ - Elf32_Half vd_version; - Elf32_Half vd_flags; - Elf32_Half vd_ndx; - Elf32_Half vd_cnt; - Elf32_Word vd_hash; - Elf32_Word vd_aux; - Elf32_Word vd_next; -} Elf32_Verdef; - -typedef struct -{ - Elf32_Word vda_name; - Elf32_Word vda_next; -} Elf32_Verdaux; - -typedef struct -{ - Elf32_Half vn_version; - Elf32_Half vn_cnt; - Elf32_Word vn_file; - Elf32_Word vn_aux; - Elf32_Word vn_next; -} Elf32_Verneed; - -typedef struct -{ - Elf32_Word vna_hash; - Elf32_Half vna_flags; - Elf32_Half vna_other; - Elf32_Word vna_name; - Elf32_Word vna_next; -} Elf32_Vernaux; - -typedef Elf32_Half Elf32_Versym; - -typedef struct { - Elf32_Half si_boundto; /* direct bindings - symbol bound to */ - Elf32_Half si_flags; /* per symbol flags */ -} Elf32_Syminfo; - -#endif /* !_SYS_ELF32_H_ */ +/** @file +Ported ELF include files from FreeBSD + +Copyright (c) 2009 - 2010, Apple Inc. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + +**/ +/*- + * Copyright (c) 1996-1998 John D. Polstra. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/sys/sys/elf32.h,v 1.8.14.2 2007/12/03 21:30:36 marius Exp $ + */ + +#ifndef _SYS_ELF32_H_ +#define _SYS_ELF32_H_ 1 + + +/* + * ELF definitions common to all 32-bit architectures. + */ + +typedef UINT32 Elf32_Addr; +typedef UINT16 Elf32_Half; +typedef UINT32 Elf32_Off; +typedef INT32 Elf32_Sword; +typedef UINT32 Elf32_Word; +typedef UINT64 Elf32_Lword; + +typedef Elf32_Word Elf32_Hashelt; + +/* Non-standard class-dependent datatype used for abstraction. */ +typedef Elf32_Word Elf32_Size; +typedef Elf32_Sword Elf32_Ssize; + +/* + * ELF header. + */ + +typedef struct { + unsigned char e_ident[EI_NIDENT]; /* File identification. */ + Elf32_Half e_type; /* File type. */ + Elf32_Half e_machine; /* Machine architecture. */ + Elf32_Word e_version; /* ELF format version. */ + Elf32_Addr e_entry; /* Entry point. */ + Elf32_Off e_phoff; /* Program header file offset. */ + Elf32_Off e_shoff; /* Section header file offset. */ + Elf32_Word e_flags; /* Architecture-specific flags. */ + Elf32_Half e_ehsize; /* Size of ELF header in bytes. */ + Elf32_Half e_phentsize; /* Size of program header entry. */ + Elf32_Half e_phnum; /* Number of program header entries. */ + Elf32_Half e_shentsize; /* Size of section header entry. */ + Elf32_Half e_shnum; /* Number of section header entries. */ + Elf32_Half e_shstrndx; /* Section name strings section. */ +} Elf32_Ehdr; + +/* + * Section header. + */ + +typedef struct { + Elf32_Word sh_name; /* Section name (index into the + section header string table). */ + Elf32_Word sh_type; /* Section type. */ + Elf32_Word sh_flags; /* Section flags. */ + Elf32_Addr sh_addr; /* Address in memory image. */ + Elf32_Off sh_offset; /* Offset in file. */ + Elf32_Word sh_size; /* Size in bytes. */ + Elf32_Word sh_link; /* Index of a related section. */ + Elf32_Word sh_info; /* Depends on section type. */ + Elf32_Word sh_addralign; /* Alignment in bytes. */ + Elf32_Word sh_entsize; /* Size of each entry in section. */ +} Elf32_Shdr; + +/* + * Program header. + */ + +typedef struct { + Elf32_Word p_type; /* Entry type. */ + Elf32_Off p_offset; /* File offset of contents. */ + Elf32_Addr p_vaddr; /* Virtual address in memory image. */ + Elf32_Addr p_paddr; /* Physical address (not used). */ + Elf32_Word p_filesz; /* Size of contents in file. */ + Elf32_Word p_memsz; /* Size of contents in memory. */ + Elf32_Word p_flags; /* Access permission flags. */ + Elf32_Word p_align; /* Alignment in memory and file. */ +} Elf32_Phdr; + +/* + * Dynamic structure. The ".dynamic" section contains an array of them. + */ + +typedef struct { + Elf32_Sword d_tag; /* Entry type. */ + union { + Elf32_Word d_val; /* Integer value. */ + Elf32_Addr d_ptr; /* Address value. */ + } d_un; +} Elf32_Dyn; + +/* + * Relocation entries. + */ + +/* Relocations that don't need an addend field. */ +typedef struct { + Elf32_Addr r_offset; /* Location to be relocated. */ + Elf32_Word r_info; /* Relocation type and symbol index. */ +} Elf32_Rel; + +/* Relocations that need an addend field. */ +typedef struct { + Elf32_Addr r_offset; /* Location to be relocated. */ + Elf32_Word r_info; /* Relocation type and symbol index. */ + Elf32_Sword r_addend; /* Addend. */ +} Elf32_Rela; + +/* Macros for accessing the fields of r_info. */ +#define ELF32_R_SYM(info) ((info) >> 8) +#define ELF32_R_TYPE(info) ((unsigned char)(info)) + +/* Macro for constructing r_info from field values. */ +#define ELF32_R_INFO(sym, type) (((sym) << 8) + (unsigned char)(type)) + +/* + * Note entry header + */ +typedef Elf_Note Elf32_Nhdr; + +/* + * Move entry + */ +typedef struct { + Elf32_Lword m_value; /* symbol value */ + Elf32_Word m_info; /* size + index */ + Elf32_Word m_poffset; /* symbol offset */ + Elf32_Half m_repeat; /* repeat count */ + Elf32_Half m_stride; /* stride info */ +} Elf32_Move; + +/* + * The macros compose and decompose values for Move.r_info + * + * sym = ELF32_M_SYM(M.m_info) + * size = ELF32_M_SIZE(M.m_info) + * M.m_info = ELF32_M_INFO(sym, size) + */ +#define ELF32_M_SYM(info) ((info)>>8) +#define ELF32_M_SIZE(info) ((unsigned char)(info)) +#define ELF32_M_INFO(sym, size) (((sym)<<8)+(unsigned char)(size)) + +/* + * Hardware/Software capabilities entry + */ +typedef struct { + Elf32_Word c_tag; /* how to interpret value */ + union { + Elf32_Word c_val; + Elf32_Addr c_ptr; + } c_un; +} Elf32_Cap; + +/* + * Symbol table entries. + */ + +typedef struct { + Elf32_Word st_name; /* String table index of name. */ + Elf32_Addr st_value; /* Symbol value. */ + Elf32_Word st_size; /* Size of associated object. */ + unsigned char st_info; /* Type and binding information. */ + unsigned char st_other; /* Reserved (not used). */ + Elf32_Half st_shndx; /* Section index of symbol. */ +} Elf32_Sym; + +/* Macros for accessing the fields of st_info. */ +#define ELF32_ST_BIND(info) ((info) >> 4) +#define ELF32_ST_TYPE(info) ((info) & 0xf) + +/* Macro for constructing st_info from field values. */ +#define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf)) + +/* Macro for accessing the fields of st_other. */ +#define ELF32_ST_VISIBILITY(oth) ((oth) & 0x3) + +/* Structures used by Sun & GNU symbol versioning. */ +typedef struct +{ + Elf32_Half vd_version; + Elf32_Half vd_flags; + Elf32_Half vd_ndx; + Elf32_Half vd_cnt; + Elf32_Word vd_hash; + Elf32_Word vd_aux; + Elf32_Word vd_next; +} Elf32_Verdef; + +typedef struct +{ + Elf32_Word vda_name; + Elf32_Word vda_next; +} Elf32_Verdaux; + +typedef struct +{ + Elf32_Half vn_version; + Elf32_Half vn_cnt; + Elf32_Word vn_file; + Elf32_Word vn_aux; + Elf32_Word vn_next; +} Elf32_Verneed; + +typedef struct +{ + Elf32_Word vna_hash; + Elf32_Half vna_flags; + Elf32_Half vna_other; + Elf32_Word vna_name; + Elf32_Word vna_next; +} Elf32_Vernaux; + +typedef Elf32_Half Elf32_Versym; + +typedef struct { + Elf32_Half si_boundto; /* direct bindings - symbol bound to */ + Elf32_Half si_flags; /* per symbol flags */ +} Elf32_Syminfo; + +#endif /* !_SYS_ELF32_H_ */ diff --git a/BaseTools/Source/C/GenFw/elf64.h b/BaseTools/Source/C/GenFw/elf64.h index 6c87207ede..572085995d 100644 --- a/BaseTools/Source/C/GenFw/elf64.h +++ b/BaseTools/Source/C/GenFw/elf64.h @@ -1,260 +1,260 @@ -/** @file -Ported ELF include files from FreeBSD - -Copyright (c) 2009 - 2010, Apple Inc. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ -/*- - * Copyright (c) 1996-1998 John D. Polstra. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD: src/sys/sys/elf64.h,v 1.10.14.2 2007/12/03 21:30:36 marius Exp $ - */ - -#ifndef _SYS_ELF64_H_ -#define _SYS_ELF64_H_ 1 - - -/* - * ELF definitions common to all 64-bit architectures. - */ - -typedef UINT64 Elf64_Addr; -typedef UINT16 Elf64_Half; -typedef UINT64 Elf64_Off; -typedef INT32 Elf64_Sword; -typedef INT64 Elf64_Sxword; -typedef UINT32 Elf64_Word; -typedef UINT64 Elf64_Lword; -typedef UINT64 Elf64_Xword; - -/* - * Types of dynamic symbol hash table bucket and chain elements. - * - * This is inconsistent among 64 bit architectures, so a machine dependent - * typedef is required. - */ - -typedef Elf64_Word Elf64_Hashelt; - -/* Non-standard class-dependent datatype used for abstraction. */ -typedef Elf64_Xword Elf64_Size; -typedef Elf64_Sxword Elf64_Ssize; - -/* - * ELF header. - */ - -typedef struct { - unsigned char e_ident[EI_NIDENT]; /* File identification. */ - Elf64_Half e_type; /* File type. */ - Elf64_Half e_machine; /* Machine architecture. */ - Elf64_Word e_version; /* ELF format version. */ - Elf64_Addr e_entry; /* Entry point. */ - Elf64_Off e_phoff; /* Program header file offset. */ - Elf64_Off e_shoff; /* Section header file offset. */ - Elf64_Word e_flags; /* Architecture-specific flags. */ - Elf64_Half e_ehsize; /* Size of ELF header in bytes. */ - Elf64_Half e_phentsize; /* Size of program header entry. */ - Elf64_Half e_phnum; /* Number of program header entries. */ - Elf64_Half e_shentsize; /* Size of section header entry. */ - Elf64_Half e_shnum; /* Number of section header entries. */ - Elf64_Half e_shstrndx; /* Section name strings section. */ -} Elf64_Ehdr; - -/* - * Section header. - */ - -typedef struct { - Elf64_Word sh_name; /* Section name (index into the - section header string table). */ - Elf64_Word sh_type; /* Section type. */ - Elf64_Xword sh_flags; /* Section flags. */ - Elf64_Addr sh_addr; /* Address in memory image. */ - Elf64_Off sh_offset; /* Offset in file. */ - Elf64_Xword sh_size; /* Size in bytes. */ - Elf64_Word sh_link; /* Index of a related section. */ - Elf64_Word sh_info; /* Depends on section type. */ - Elf64_Xword sh_addralign; /* Alignment in bytes. */ - Elf64_Xword sh_entsize; /* Size of each entry in section. */ -} Elf64_Shdr; - -/* - * Program header. - */ - -typedef struct { - Elf64_Word p_type; /* Entry type. */ - Elf64_Word p_flags; /* Access permission flags. */ - Elf64_Off p_offset; /* File offset of contents. */ - Elf64_Addr p_vaddr; /* Virtual address in memory image. */ - Elf64_Addr p_paddr; /* Physical address (not used). */ - Elf64_Xword p_filesz; /* Size of contents in file. */ - Elf64_Xword p_memsz; /* Size of contents in memory. */ - Elf64_Xword p_align; /* Alignment in memory and file. */ -} Elf64_Phdr; - -/* - * Dynamic structure. The ".dynamic" section contains an array of them. - */ - -typedef struct { - Elf64_Sxword d_tag; /* Entry type. */ - union { - Elf64_Xword d_val; /* Integer value. */ - Elf64_Addr d_ptr; /* Address value. */ - } d_un; -} Elf64_Dyn; - -/* - * Relocation entries. - */ - -/* Relocations that don't need an addend field. */ -typedef struct { - Elf64_Addr r_offset; /* Location to be relocated. */ - Elf64_Xword r_info; /* Relocation type and symbol index. */ -} Elf64_Rel; - -/* Relocations that need an addend field. */ -typedef struct { - Elf64_Addr r_offset; /* Location to be relocated. */ - Elf64_Xword r_info; /* Relocation type and symbol index. */ - Elf64_Sxword r_addend; /* Addend. */ -} Elf64_Rela; - -/* Macros for accessing the fields of r_info. */ -#define ELF64_R_SYM(info) ((info) >> 32) -#define ELF64_R_TYPE(info) ((info) & 0xffffffffL) - -/* Macro for constructing r_info from field values. */ -#define ELF64_R_INFO(sym, type) (((sym) << 32) + ((type) & 0xffffffffL)) - -#define ELF64_R_TYPE_DATA(info) (((Elf64_Xword)(info)<<32)>>40) -#define ELF64_R_TYPE_ID(info) (((Elf64_Xword)(info)<<56)>>56) -#define ELF64_R_TYPE_INFO(data, type) \ - (((Elf64_Xword)(data)<<8)+(Elf64_Xword)(type)) - -/* - * Note entry header - */ -typedef Elf_Note Elf64_Nhdr; - -/* - * Move entry - */ -typedef struct { - Elf64_Lword m_value; /* symbol value */ - Elf64_Xword m_info; /* size + index */ - Elf64_Xword m_poffset; /* symbol offset */ - Elf64_Half m_repeat; /* repeat count */ - Elf64_Half m_stride; /* stride info */ -} Elf64_Move; - -#define ELF64_M_SYM(info) ((info)>>8) -#define ELF64_M_SIZE(info) ((unsigned char)(info)) -#define ELF64_M_INFO(sym, size) (((sym)<<8)+(unsigned char)(size)) - -/* - * Hardware/Software capabilities entry - */ -typedef struct { - Elf64_Xword c_tag; /* how to interpret value */ - union { - Elf64_Xword c_val; - Elf64_Addr c_ptr; - } c_un; -} Elf64_Cap; - -/* - * Symbol table entries. - */ - -typedef struct { - Elf64_Word st_name; /* String table index of name. */ - unsigned char st_info; /* Type and binding information. */ - unsigned char st_other; /* Reserved (not used). */ - Elf64_Half st_shndx; /* Section index of symbol. */ - Elf64_Addr st_value; /* Symbol value. */ - Elf64_Xword st_size; /* Size of associated object. */ -} Elf64_Sym; - -/* Macros for accessing the fields of st_info. */ -#define ELF64_ST_BIND(info) ((info) >> 4) -#define ELF64_ST_TYPE(info) ((info) & 0xf) - -/* Macro for constructing st_info from field values. */ -#define ELF64_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf)) - -/* Macro for accessing the fields of st_other. */ -#define ELF64_ST_VISIBILITY(oth) ((oth) & 0x3) - -/* Structures used by Sun & GNU-style symbol versioning. */ -typedef struct { - Elf64_Half vd_version; - Elf64_Half vd_flags; - Elf64_Half vd_ndx; - Elf64_Half vd_cnt; - Elf64_Word vd_hash; - Elf64_Word vd_aux; - Elf64_Word vd_next; -} Elf64_Verdef; - -typedef struct { - Elf64_Word vda_name; - Elf64_Word vda_next; -} Elf64_Verdaux; - -typedef struct { - Elf64_Half vn_version; - Elf64_Half vn_cnt; - Elf64_Word vn_file; - Elf64_Word vn_aux; - Elf64_Word vn_next; -} Elf64_Verneed; - -typedef struct { - Elf64_Word vna_hash; - Elf64_Half vna_flags; - Elf64_Half vna_other; - Elf64_Word vna_name; - Elf64_Word vna_next; -} Elf64_Vernaux; - -typedef Elf64_Half Elf64_Versym; - -typedef struct { - Elf64_Half si_boundto; /* direct bindings - symbol bound to */ - Elf64_Half si_flags; /* per symbol flags */ -} Elf64_Syminfo; - -#endif /* !_SYS_ELF64_H_ */ +/** @file +Ported ELF include files from FreeBSD + +Copyright (c) 2009 - 2010, Apple Inc. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ +/*- + * Copyright (c) 1996-1998 John D. Polstra. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/sys/sys/elf64.h,v 1.10.14.2 2007/12/03 21:30:36 marius Exp $ + */ + +#ifndef _SYS_ELF64_H_ +#define _SYS_ELF64_H_ 1 + + +/* + * ELF definitions common to all 64-bit architectures. + */ + +typedef UINT64 Elf64_Addr; +typedef UINT16 Elf64_Half; +typedef UINT64 Elf64_Off; +typedef INT32 Elf64_Sword; +typedef INT64 Elf64_Sxword; +typedef UINT32 Elf64_Word; +typedef UINT64 Elf64_Lword; +typedef UINT64 Elf64_Xword; + +/* + * Types of dynamic symbol hash table bucket and chain elements. + * + * This is inconsistent among 64 bit architectures, so a machine dependent + * typedef is required. + */ + +typedef Elf64_Word Elf64_Hashelt; + +/* Non-standard class-dependent datatype used for abstraction. */ +typedef Elf64_Xword Elf64_Size; +typedef Elf64_Sxword Elf64_Ssize; + +/* + * ELF header. + */ + +typedef struct { + unsigned char e_ident[EI_NIDENT]; /* File identification. */ + Elf64_Half e_type; /* File type. */ + Elf64_Half e_machine; /* Machine architecture. */ + Elf64_Word e_version; /* ELF format version. */ + Elf64_Addr e_entry; /* Entry point. */ + Elf64_Off e_phoff; /* Program header file offset. */ + Elf64_Off e_shoff; /* Section header file offset. */ + Elf64_Word e_flags; /* Architecture-specific flags. */ + Elf64_Half e_ehsize; /* Size of ELF header in bytes. */ + Elf64_Half e_phentsize; /* Size of program header entry. */ + Elf64_Half e_phnum; /* Number of program header entries. */ + Elf64_Half e_shentsize; /* Size of section header entry. */ + Elf64_Half e_shnum; /* Number of section header entries. */ + Elf64_Half e_shstrndx; /* Section name strings section. */ +} Elf64_Ehdr; + +/* + * Section header. + */ + +typedef struct { + Elf64_Word sh_name; /* Section name (index into the + section header string table). */ + Elf64_Word sh_type; /* Section type. */ + Elf64_Xword sh_flags; /* Section flags. */ + Elf64_Addr sh_addr; /* Address in memory image. */ + Elf64_Off sh_offset; /* Offset in file. */ + Elf64_Xword sh_size; /* Size in bytes. */ + Elf64_Word sh_link; /* Index of a related section. */ + Elf64_Word sh_info; /* Depends on section type. */ + Elf64_Xword sh_addralign; /* Alignment in bytes. */ + Elf64_Xword sh_entsize; /* Size of each entry in section. */ +} Elf64_Shdr; + +/* + * Program header. + */ + +typedef struct { + Elf64_Word p_type; /* Entry type. */ + Elf64_Word p_flags; /* Access permission flags. */ + Elf64_Off p_offset; /* File offset of contents. */ + Elf64_Addr p_vaddr; /* Virtual address in memory image. */ + Elf64_Addr p_paddr; /* Physical address (not used). */ + Elf64_Xword p_filesz; /* Size of contents in file. */ + Elf64_Xword p_memsz; /* Size of contents in memory. */ + Elf64_Xword p_align; /* Alignment in memory and file. */ +} Elf64_Phdr; + +/* + * Dynamic structure. The ".dynamic" section contains an array of them. + */ + +typedef struct { + Elf64_Sxword d_tag; /* Entry type. */ + union { + Elf64_Xword d_val; /* Integer value. */ + Elf64_Addr d_ptr; /* Address value. */ + } d_un; +} Elf64_Dyn; + +/* + * Relocation entries. + */ + +/* Relocations that don't need an addend field. */ +typedef struct { + Elf64_Addr r_offset; /* Location to be relocated. */ + Elf64_Xword r_info; /* Relocation type and symbol index. */ +} Elf64_Rel; + +/* Relocations that need an addend field. */ +typedef struct { + Elf64_Addr r_offset; /* Location to be relocated. */ + Elf64_Xword r_info; /* Relocation type and symbol index. */ + Elf64_Sxword r_addend; /* Addend. */ +} Elf64_Rela; + +/* Macros for accessing the fields of r_info. */ +#define ELF64_R_SYM(info) ((info) >> 32) +#define ELF64_R_TYPE(info) ((info) & 0xffffffffL) + +/* Macro for constructing r_info from field values. */ +#define ELF64_R_INFO(sym, type) (((sym) << 32) + ((type) & 0xffffffffL)) + +#define ELF64_R_TYPE_DATA(info) (((Elf64_Xword)(info)<<32)>>40) +#define ELF64_R_TYPE_ID(info) (((Elf64_Xword)(info)<<56)>>56) +#define ELF64_R_TYPE_INFO(data, type) \ + (((Elf64_Xword)(data)<<8)+(Elf64_Xword)(type)) + +/* + * Note entry header + */ +typedef Elf_Note Elf64_Nhdr; + +/* + * Move entry + */ +typedef struct { + Elf64_Lword m_value; /* symbol value */ + Elf64_Xword m_info; /* size + index */ + Elf64_Xword m_poffset; /* symbol offset */ + Elf64_Half m_repeat; /* repeat count */ + Elf64_Half m_stride; /* stride info */ +} Elf64_Move; + +#define ELF64_M_SYM(info) ((info)>>8) +#define ELF64_M_SIZE(info) ((unsigned char)(info)) +#define ELF64_M_INFO(sym, size) (((sym)<<8)+(unsigned char)(size)) + +/* + * Hardware/Software capabilities entry + */ +typedef struct { + Elf64_Xword c_tag; /* how to interpret value */ + union { + Elf64_Xword c_val; + Elf64_Addr c_ptr; + } c_un; +} Elf64_Cap; + +/* + * Symbol table entries. + */ + +typedef struct { + Elf64_Word st_name; /* String table index of name. */ + unsigned char st_info; /* Type and binding information. */ + unsigned char st_other; /* Reserved (not used). */ + Elf64_Half st_shndx; /* Section index of symbol. */ + Elf64_Addr st_value; /* Symbol value. */ + Elf64_Xword st_size; /* Size of associated object. */ +} Elf64_Sym; + +/* Macros for accessing the fields of st_info. */ +#define ELF64_ST_BIND(info) ((info) >> 4) +#define ELF64_ST_TYPE(info) ((info) & 0xf) + +/* Macro for constructing st_info from field values. */ +#define ELF64_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf)) + +/* Macro for accessing the fields of st_other. */ +#define ELF64_ST_VISIBILITY(oth) ((oth) & 0x3) + +/* Structures used by Sun & GNU-style symbol versioning. */ +typedef struct { + Elf64_Half vd_version; + Elf64_Half vd_flags; + Elf64_Half vd_ndx; + Elf64_Half vd_cnt; + Elf64_Word vd_hash; + Elf64_Word vd_aux; + Elf64_Word vd_next; +} Elf64_Verdef; + +typedef struct { + Elf64_Word vda_name; + Elf64_Word vda_next; +} Elf64_Verdaux; + +typedef struct { + Elf64_Half vn_version; + Elf64_Half vn_cnt; + Elf64_Word vn_file; + Elf64_Word vn_aux; + Elf64_Word vn_next; +} Elf64_Verneed; + +typedef struct { + Elf64_Word vna_hash; + Elf64_Half vna_flags; + Elf64_Half vna_other; + Elf64_Word vna_name; + Elf64_Word vna_next; +} Elf64_Vernaux; + +typedef Elf64_Half Elf64_Versym; + +typedef struct { + Elf64_Half si_boundto; /* direct bindings - symbol bound to */ + Elf64_Half si_flags; /* per symbol flags */ +} Elf64_Syminfo; + +#endif /* !_SYS_ELF64_H_ */ diff --git a/BaseTools/Source/C/GenFw/elf_common.h b/BaseTools/Source/C/GenFw/elf_common.h index df22472dc2..766d0e42ef 100644 --- a/BaseTools/Source/C/GenFw/elf_common.h +++ b/BaseTools/Source/C/GenFw/elf_common.h @@ -1,750 +1,750 @@ -/** @file -Ported ELF include files from FreeBSD - -Copyright (c) 2009 - 2010, Apple Inc. All rights reserved.
-Portions Copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - -**/ -/*- - * Copyright (c) 1998 John D. Polstra. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD: src/sys/sys/elf_common.h,v 1.15.8.2 2007/12/03 21:30:36 marius Exp $ - */ - -#ifndef _SYS_ELF_COMMON_H_ -#define _SYS_ELF_COMMON_H_ 1 - -/* - * ELF definitions that are independent of architecture or word size. - */ - -/* - * Note header. The ".note" section contains an array of notes. Each - * begins with this header, aligned to a word boundary. Immediately - * following the note header is n_namesz bytes of name, padded to the - * next word boundary. Then comes n_descsz bytes of descriptor, again - * padded to a word boundary. The values of n_namesz and n_descsz do - * not include the padding. - */ - -typedef struct { - UINT32 n_namesz; /* Length of name. */ - UINT32 n_descsz; /* Length of descriptor. */ - UINT32 n_type; /* Type of this note. */ -} Elf_Note; - -/* Indexes into the e_ident array. Keep synced with - http://www.sco.com/developers/gabi/latest/ch4.eheader.html */ -#define EI_MAG0 0 /* Magic number, byte 0. */ -#define EI_MAG1 1 /* Magic number, byte 1. */ -#define EI_MAG2 2 /* Magic number, byte 2. */ -#define EI_MAG3 3 /* Magic number, byte 3. */ -#define EI_CLASS 4 /* Class of machine. */ -#define EI_DATA 5 /* Data format. */ -#define EI_VERSION 6 /* ELF format version. */ -#define EI_OSABI 7 /* Operating system / ABI identification */ -#define EI_ABIVERSION 8 /* ABI version */ -#define OLD_EI_BRAND 8 /* Start of architecture identification. */ -#define EI_PAD 9 /* Start of padding (per SVR4 ABI). */ -#define EI_NIDENT 16 /* Size of e_ident array. */ - -/* Values for the magic number bytes. */ -#define ELFMAG0 0x7f -#define ELFMAG1 'E' -#define ELFMAG2 'L' -#define ELFMAG3 'F' -#define ELFMAG "\177ELF" /* magic string */ -#define SELFMAG 4 /* magic string size */ - -/* Values for e_ident[EI_VERSION] and e_version. */ -#define EV_NONE 0 -#define EV_CURRENT 1 - -/* Values for e_ident[EI_CLASS]. */ -#define ELFCLASSNONE 0 /* Unknown class. */ -#define ELFCLASS32 1 /* 32-bit architecture. */ -#define ELFCLASS64 2 /* 64-bit architecture. */ - -/* Values for e_ident[EI_DATA]. */ -#define ELFDATANONE 0 /* Unknown data format. */ -#define ELFDATA2LSB 1 /* 2's complement little-endian. */ -#define ELFDATA2MSB 2 /* 2's complement big-endian. */ - -/* Values for e_ident[EI_OSABI]. */ -#define ELFOSABI_NONE 0 /* UNIX System V ABI */ -#define ELFOSABI_HPUX 1 /* HP-UX operating system */ -#define ELFOSABI_NETBSD 2 /* NetBSD */ -#define ELFOSABI_LINUX 3 /* GNU/Linux */ -#define ELFOSABI_HURD 4 /* GNU/Hurd */ -#define ELFOSABI_86OPEN 5 /* 86Open common IA32 ABI */ -#define ELFOSABI_SOLARIS 6 /* Solaris */ -#define ELFOSABI_AIX 7 /* AIX */ -#define ELFOSABI_IRIX 8 /* IRIX */ -#define ELFOSABI_FREEBSD 9 /* FreeBSD */ -#define ELFOSABI_TRU64 10 /* TRU64 UNIX */ -#define ELFOSABI_MODESTO 11 /* Novell Modesto */ -#define ELFOSABI_OPENBSD 12 /* OpenBSD */ -#define ELFOSABI_OPENVMS 13 /* Open VMS */ -#define ELFOSABI_NSK 14 /* HP Non-Stop Kernel */ -#define ELFOSABI_ARM 97 /* ARM */ -#define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */ - -#define ELFOSABI_SYSV ELFOSABI_NONE /* symbol used in old spec */ -#define ELFOSABI_MONTEREY ELFOSABI_AIX /* Monterey */ - -/* e_ident */ -#define IS_ELF(ehdr) ((ehdr).e_ident[EI_MAG0] == ELFMAG0 && \ - (ehdr).e_ident[EI_MAG1] == ELFMAG1 && \ - (ehdr).e_ident[EI_MAG2] == ELFMAG2 && \ - (ehdr).e_ident[EI_MAG3] == ELFMAG3) - -/* Values for e_type. */ -#define ET_NONE 0 /* Unknown type. */ -#define ET_REL 1 /* Relocatable. */ -#define ET_EXEC 2 /* Executable. */ -#define ET_DYN 3 /* Shared object. */ -#define ET_CORE 4 /* Core file. */ -#define ET_LOOS 0xfe00 /* First operating system specific. */ -#define ET_HIOS 0xfeff /* Last operating system-specific. */ -#define ET_LOPROC 0xff00 /* First processor-specific. */ -#define ET_HIPROC 0xffff /* Last processor-specific. */ - -/* Values for e_machine. */ -#define EM_NONE 0 /* Unknown machine. */ -#define EM_M32 1 /* AT&T WE32100. */ -#define EM_SPARC 2 /* Sun SPARC. */ -#define EM_386 3 /* Intel i386. */ -#define EM_68K 4 /* Motorola 68000. */ -#define EM_88K 5 /* Motorola 88000. */ -#define EM_860 7 /* Intel i860. */ -#define EM_MIPS 8 /* MIPS R3000 Big-Endian only. */ -#define EM_S370 9 /* IBM System/370. */ -#define EM_MIPS_RS3_LE 10 /* MIPS R3000 Little-Endian. */ -#define EM_PARISC 15 /* HP PA-RISC. */ -#define EM_VPP500 17 /* Fujitsu VPP500. */ -#define EM_SPARC32PLUS 18 /* SPARC v8plus. */ -#define EM_960 19 /* Intel 80960. */ -#define EM_PPC 20 /* PowerPC 32-bit. */ -#define EM_PPC64 21 /* PowerPC 64-bit. */ -#define EM_S390 22 /* IBM System/390. */ -#define EM_V800 36 /* NEC V800. */ -#define EM_FR20 37 /* Fujitsu FR20. */ -#define EM_RH32 38 /* TRW RH-32. */ -#define EM_RCE 39 /* Motorola RCE. */ -#define EM_ARM 40 /* ARM. */ -#define EM_SH 42 /* Hitachi SH. */ -#define EM_SPARCV9 43 /* SPARC v9 64-bit. */ -#define EM_TRICORE 44 /* Siemens TriCore embedded processor. */ -#define EM_ARC 45 /* Argonaut RISC Core. */ -#define EM_H8_300 46 /* Hitachi H8/300. */ -#define EM_H8_300H 47 /* Hitachi H8/300H. */ -#define EM_H8S 48 /* Hitachi H8S. */ -#define EM_H8_500 49 /* Hitachi H8/500. */ -#define EM_IA_64 50 /* Intel IA-64 Processor. */ -#define EM_MIPS_X 51 /* Stanford MIPS-X. */ -#define EM_COLDFIRE 52 /* Motorola ColdFire. */ -#define EM_68HC12 53 /* Motorola M68HC12. */ -#define EM_MMA 54 /* Fujitsu MMA. */ -#define EM_PCP 55 /* Siemens PCP. */ -#define EM_NCPU 56 /* Sony nCPU. */ -#define EM_NDR1 57 /* Denso NDR1 microprocessor. */ -#define EM_STARCORE 58 /* Motorola Star*Core processor. */ -#define EM_ME16 59 /* Toyota ME16 processor. */ -#define EM_ST100 60 /* STMicroelectronics ST100 processor. */ -#define EM_TINYJ 61 /* Advanced Logic Corp. TinyJ processor. */ -#define EM_X86_64 62 /* Advanced Micro Devices x86-64 */ -#define EM_AMD64 EM_X86_64 /* Advanced Micro Devices x86-64 (compat) */ -#define EM_AARCH64 183 /* ARM 64bit Architecture */ - -/* Non-standard or deprecated. */ -#define EM_486 6 /* Intel i486. */ -#define EM_MIPS_RS4_BE 10 /* MIPS R4000 Big-Endian */ -#define EM_ALPHA_STD 41 /* Digital Alpha (standard value). */ -#define EM_ALPHA 0x9026 /* Alpha (written in the absence of an ABI) */ - -/* Special section indexes. */ -#define SHN_UNDEF 0 /* Undefined, missing, irrelevant. */ -#define SHN_LORESERVE 0xff00 /* First of reserved range. */ -#define SHN_LOPROC 0xff00 /* First processor-specific. */ -#define SHN_HIPROC 0xff1f /* Last processor-specific. */ -#define SHN_LOOS 0xff20 /* First operating system-specific. */ -#define SHN_HIOS 0xff3f /* Last operating system-specific. */ -#define SHN_ABS 0xfff1 /* Absolute values. */ -#define SHN_COMMON 0xfff2 /* Common data. */ -#define SHN_XINDEX 0xffff /* Escape -- index stored elsewhere. */ -#define SHN_HIRESERVE 0xffff /* Last of reserved range. */ - -/* sh_type */ -#define SHT_NULL 0 /* inactive */ -#define SHT_PROGBITS 1 /* program defined information */ -#define SHT_SYMTAB 2 /* symbol table section */ -#define SHT_STRTAB 3 /* string table section */ -#define SHT_RELA 4 /* relocation section with addends */ -#define SHT_HASH 5 /* symbol hash table section */ -#define SHT_DYNAMIC 6 /* dynamic section */ -#define SHT_NOTE 7 /* note section */ -#define SHT_NOBITS 8 /* no space section */ -#define SHT_REL 9 /* relocation section - no addends */ -#define SHT_SHLIB 10 /* reserved - purpose unknown */ -#define SHT_DYNSYM 11 /* dynamic symbol table section */ -#define SHT_INIT_ARRAY 14 /* Initialization function pointers. */ -#define SHT_FINI_ARRAY 15 /* Termination function pointers. */ -#define SHT_PREINIT_ARRAY 16 /* Pre-initialization function ptrs. */ -#define SHT_GROUP 17 /* Section group. */ -#define SHT_SYMTAB_SHNDX 18 /* Section indexes (see SHN_XINDEX). */ -#define SHT_LOOS 0x60000000 /* First of OS specific semantics */ -#define SHT_LOSUNW 0x6ffffff4 -#define SHT_SUNW_dof 0x6ffffff4 -#define SHT_SUNW_cap 0x6ffffff5 -#define SHT_SUNW_SIGNATURE 0x6ffffff6 -#define SHT_SUNW_ANNOTATE 0x6ffffff7 -#define SHT_SUNW_DEBUGSTR 0x6ffffff8 -#define SHT_SUNW_DEBUG 0x6ffffff9 -#define SHT_SUNW_move 0x6ffffffa -#define SHT_SUNW_COMDAT 0x6ffffffb -#define SHT_SUNW_syminfo 0x6ffffffc -#define SHT_SUNW_verdef 0x6ffffffd -#define SHT_GNU_verdef 0x6ffffffd /* Symbol versions provided */ -#define SHT_SUNW_verneed 0x6ffffffe -#define SHT_GNU_verneed 0x6ffffffe /* Symbol versions required */ -#define SHT_SUNW_versym 0x6fffffff -#define SHT_GNU_versym 0x6fffffff /* Symbol version table */ -#define SHT_HISUNW 0x6fffffff -#define SHT_HIOS 0x6fffffff /* Last of OS specific semantics */ -#define SHT_LOPROC 0x70000000 /* reserved range for processor */ -#define SHT_AMD64_UNWIND 0x70000001 /* unwind information */ -#define SHT_HIPROC 0x7fffffff /* specific section header types */ -#define SHT_LOUSER 0x80000000 /* reserved range for application */ -#define SHT_HIUSER 0xffffffff /* specific indexes */ - -/* Flags for sh_flags. */ -#define SHF_WRITE 0x1 /* Section contains writable data. */ -#define SHF_ALLOC 0x2 /* Section occupies memory. */ -#define SHF_EXECINSTR 0x4 /* Section contains instructions. */ -#define SHF_MERGE 0x10 /* Section may be merged. */ -#define SHF_STRINGS 0x20 /* Section contains strings. */ -#define SHF_INFO_LINK 0x40 /* sh_info holds section index. */ -#define SHF_LINK_ORDER 0x80 /* Special ordering requirements. */ -#define SHF_OS_NONCONFORMING 0x100 /* OS-specific processing required. */ -#define SHF_GROUP 0x200 /* Member of section group. */ -#define SHF_TLS 0x400 /* Section contains TLS data. */ -#define SHF_MASKOS 0x0ff00000 /* OS-specific semantics. */ -#define SHF_MASKPROC 0xf0000000 /* Processor-specific semantics. */ - -/* Values for p_type. */ -#define PT_NULL 0 /* Unused entry. */ -#define PT_LOAD 1 /* Loadable segment. */ -#define PT_DYNAMIC 2 /* Dynamic linking information segment. */ -#define PT_INTERP 3 /* Pathname of interpreter. */ -#define PT_NOTE 4 /* Auxiliary information. */ -#define PT_SHLIB 5 /* Reserved (not used). */ -#define PT_PHDR 6 /* Location of program header itself. */ -#define PT_TLS 7 /* Thread local storage segment */ -#define PT_LOOS 0x60000000 /* First OS-specific. */ -#define PT_SUNW_UNWIND 0x6464e550 /* amd64 UNWIND program header */ -#define PT_GNU_EH_FRAME 0x6474e550 -#define PT_LOSUNW 0x6ffffffa -#define PT_SUNWBSS 0x6ffffffa /* Sun Specific segment */ -#define PT_SUNWSTACK 0x6ffffffb /* describes the stack segment */ -#define PT_SUNWDTRACE 0x6ffffffc /* private */ -#define PT_SUNWCAP 0x6ffffffd /* hard/soft capabilities segment */ -#define PT_HISUNW 0x6fffffff -#define PT_HIOS 0x6fffffff /* Last OS-specific. */ -#define PT_LOPROC 0x70000000 /* First processor-specific type. */ -#define PT_HIPROC 0x7fffffff /* Last processor-specific type. */ - -/* Values for p_flags. */ -#define PF_X 0x1 /* Executable. */ -#define PF_W 0x2 /* Writable. */ -#define PF_R 0x4 /* Readable. */ -#define PF_MASKOS 0x0ff00000 /* Operating system-specific. */ -#define PF_MASKPROC 0xf0000000 /* Processor-specific. */ - -/* Extended program header index. */ -#define PN_XNUM 0xffff - -/* Values for d_tag. */ -#define DT_NULL 0 /* Terminating entry. */ -#define DT_NEEDED 1 /* String table offset of a needed shared - library. */ -#define DT_PLTRELSZ 2 /* Total size in bytes of PLT relocations. */ -#define DT_PLTGOT 3 /* Processor-dependent address. */ -#define DT_HASH 4 /* Address of symbol hash table. */ -#define DT_STRTAB 5 /* Address of string table. */ -#define DT_SYMTAB 6 /* Address of symbol table. */ -#define DT_RELA 7 /* Address of ElfNN_Rela relocations. */ -#define DT_RELASZ 8 /* Total size of ElfNN_Rela relocations. */ -#define DT_RELAENT 9 /* Size of each ElfNN_Rela relocation entry. */ -#define DT_STRSZ 10 /* Size of string table. */ -#define DT_SYMENT 11 /* Size of each symbol table entry. */ -#define DT_INIT 12 /* Address of initialization function. */ -#define DT_FINI 13 /* Address of finalization function. */ -#define DT_SONAME 14 /* String table offset of shared object - name. */ -#define DT_RPATH 15 /* String table offset of library path. [sup] */ -#define DT_SYMBOLIC 16 /* Indicates "symbolic" linking. [sup] */ -#define DT_REL 17 /* Address of ElfNN_Rel relocations. */ -#define DT_RELSZ 18 /* Total size of ElfNN_Rel relocations. */ -#define DT_RELENT 19 /* Size of each ElfNN_Rel relocation. */ -#define DT_PLTREL 20 /* Type of relocation used for PLT. */ -#define DT_DEBUG 21 /* Reserved (not used). */ -#define DT_TEXTREL 22 /* Indicates there may be relocations in - non-writable segments. [sup] */ -#define DT_JMPREL 23 /* Address of PLT relocations. */ -#define DT_BIND_NOW 24 /* [sup] */ -#define DT_INIT_ARRAY 25 /* Address of the array of pointers to - initialization functions */ -#define DT_FINI_ARRAY 26 /* Address of the array of pointers to - termination functions */ -#define DT_INIT_ARRAYSZ 27 /* Size in bytes of the array of - initialization functions. */ -#define DT_FINI_ARRAYSZ 28 /* Size in bytes of the array of - terminationfunctions. */ -#define DT_RUNPATH 29 /* String table offset of a null-terminated - library search path string. */ -#define DT_FLAGS 30 /* Object specific flag values. */ -#define DT_ENCODING 32 /* Values greater than or equal to DT_ENCODING - and less than DT_LOOS follow the rules for - the interpretation of the d_un union - as follows: even == 'd_ptr', even == 'd_val' - or none */ -#define DT_PREINIT_ARRAY 32 /* Address of the array of pointers to - pre-initialization functions. */ -#define DT_PREINIT_ARRAYSZ 33 /* Size in bytes of the array of - pre-initialization functions. */ -#define DT_MAXPOSTAGS 34 /* number of positive tags */ -#define DT_LOOS 0x6000000d /* First OS-specific */ -#define DT_SUNW_AUXILIARY 0x6000000d /* symbol auxiliary name */ -#define DT_SUNW_RTLDINF 0x6000000e /* ld.so.1 info (private) */ -#define DT_SUNW_FILTER 0x6000000f /* symbol filter name */ -#define DT_SUNW_CAP 0x60000010 /* hardware/software */ -#define DT_HIOS 0x6ffff000 /* Last OS-specific */ - -/* - * DT_* entries which fall between DT_VALRNGHI & DT_VALRNGLO use the - * Dyn.d_un.d_val field of the Elf*_Dyn structure. - */ -#define DT_VALRNGLO 0x6ffffd00 -#define DT_CHECKSUM 0x6ffffdf8 /* elf checksum */ -#define DT_PLTPADSZ 0x6ffffdf9 /* pltpadding size */ -#define DT_MOVEENT 0x6ffffdfa /* move table entry size */ -#define DT_MOVESZ 0x6ffffdfb /* move table size */ -#define DT_FEATURE_1 0x6ffffdfc /* feature holder */ -#define DT_POSFLAG_1 0x6ffffdfd /* flags for DT_* entries, effecting */ - /* the following DT_* entry. */ - /* See DF_P1_* definitions */ -#define DT_SYMINSZ 0x6ffffdfe /* syminfo table size (in bytes) */ -#define DT_SYMINENT 0x6ffffdff /* syminfo entry size (in bytes) */ -#define DT_VALRNGHI 0x6ffffdff - -/* - * DT_* entries which fall between DT_ADDRRNGHI & DT_ADDRRNGLO use the - * Dyn.d_un.d_ptr field of the Elf*_Dyn structure. - * - * If any adjustment is made to the ELF object after it has been - * built, these entries will need to be adjusted. - */ -#define DT_ADDRRNGLO 0x6ffffe00 -#define DT_CONFIG 0x6ffffefa /* configuration information */ -#define DT_DEPAUDIT 0x6ffffefb /* dependency auditing */ -#define DT_AUDIT 0x6ffffefc /* object auditing */ -#define DT_PLTPAD 0x6ffffefd /* pltpadding (sparcv9) */ -#define DT_MOVETAB 0x6ffffefe /* move table */ -#define DT_SYMINFO 0x6ffffeff /* syminfo table */ -#define DT_ADDRRNGHI 0x6ffffeff - -#define DT_VERSYM 0x6ffffff0 /* Address of versym section. */ -#define DT_RELACOUNT 0x6ffffff9 /* number of RELATIVE relocations */ -#define DT_RELCOUNT 0x6ffffffa /* number of RELATIVE relocations */ -#define DT_FLAGS_1 0x6ffffffb /* state flags - see DF_1_* defs */ -#define DT_VERDEF 0x6ffffffc /* Address of verdef section. */ -#define DT_VERDEFNUM 0x6ffffffd /* Number of elems in verdef section */ -#define DT_VERNEED 0x6ffffffe /* Address of verneed section. */ -#define DT_VERNEEDNUM 0x6fffffff /* Number of elems in verneed section */ - -#define DT_LOPROC 0x70000000 /* First processor-specific type. */ -#define DT_DEPRECATED_SPARC_REGISTER 0x7000001 -#define DT_AUXILIARY 0x7ffffffd /* shared library auxiliary name */ -#define DT_USED 0x7ffffffe /* ignored - same as needed */ -#define DT_FILTER 0x7fffffff /* shared library filter name */ -#define DT_HIPROC 0x7fffffff /* Last processor-specific type. */ - -/* Values for DT_FLAGS */ -#define DF_ORIGIN 0x0001 /* Indicates that the object being loaded may - make reference to the $ORIGIN substitution - string */ -#define DF_SYMBOLIC 0x0002 /* Indicates "symbolic" linking. */ -#define DF_TEXTREL 0x0004 /* Indicates there may be relocations in - non-writable segments. */ -#define DF_BIND_NOW 0x0008 /* Indicates that the dynamic linker should - process all relocations for the object - containing this entry before transferring - control to the program. */ -#define DF_STATIC_TLS 0x0010 /* Indicates that the shared object or - executable contains code using a static - thread-local storage scheme. */ - -/* Values for n_type. Used in core files. */ -#define NT_PRSTATUS 1 /* Process status. */ -#define NT_FPREGSET 2 /* Floating point registers. */ -#define NT_PRPSINFO 3 /* Process state info. */ - -/* Symbol Binding - ELFNN_ST_BIND - st_info */ -#define STB_LOCAL 0 /* Local symbol */ -#define STB_GLOBAL 1 /* Global symbol */ -#define STB_WEAK 2 /* like global - lower precedence */ -#define STB_LOOS 10 /* Reserved range for operating system */ -#define STB_HIOS 12 /* specific semantics. */ -#define STB_LOPROC 13 /* reserved range for processor */ -#define STB_HIPROC 15 /* specific semantics. */ - -/* Symbol type - ELFNN_ST_TYPE - st_info */ -#define STT_NOTYPE 0 /* Unspecified type. */ -#define STT_OBJECT 1 /* Data object. */ -#define STT_FUNC 2 /* Function. */ -#define STT_SECTION 3 /* Section. */ -#define STT_FILE 4 /* Source file. */ -#define STT_COMMON 5 /* Uninitialized common block. */ -#define STT_TLS 6 /* TLS object. */ -#define STT_NUM 7 -#define STT_LOOS 10 /* Reserved range for operating system */ -#define STT_HIOS 12 /* specific semantics. */ -#define STT_LOPROC 13 /* reserved range for processor */ -#define STT_HIPROC 15 /* specific semantics. */ - -/* Symbol visibility - ELFNN_ST_VISIBILITY - st_other */ -#define STV_DEFAULT 0x0 /* Default visibility (see binding). */ -#define STV_INTERNAL 0x1 /* Special meaning in relocatable objects. */ -#define STV_HIDDEN 0x2 /* Not visible. */ -#define STV_PROTECTED 0x3 /* Visible but not preemptible. */ - -/* Special symbol table indexes. */ -#define STN_UNDEF 0 /* Undefined symbol index. */ - -/* Symbol versioning flags. */ -#define VER_DEF_CURRENT 1 -#define VER_DEF_IDX(x) VER_NDX(x) - -#define VER_FLG_BASE 0x01 -#define VER_FLG_WEAK 0x02 - -#define VER_NEED_CURRENT 1 -#define VER_NEED_WEAK (1u << 15) -#define VER_NEED_HIDDEN VER_NDX_HIDDEN -#define VER_NEED_IDX(x) VER_NDX(x) - -#define VER_NDX_LOCAL 0 -#define VER_NDX_GLOBAL 1 -#define VER_NDX_GIVEN 2 - -#define VER_NDX_HIDDEN (1u << 15) -#define VER_NDX(x) ((x) & ~(1u << 15)) - -#define CA_SUNW_NULL 0 -#define CA_SUNW_HW_1 1 /* first hardware capabilities entry */ -#define CA_SUNW_SF_1 2 /* first software capabilities entry */ - -/* - * Syminfo flag values - */ -#define SYMINFO_FLG_DIRECT 0x0001 /* symbol ref has direct association */ - /* to object containing defn. */ -#define SYMINFO_FLG_PASSTHRU 0x0002 /* ignored - see SYMINFO_FLG_FILTER */ -#define SYMINFO_FLG_COPY 0x0004 /* symbol is a copy-reloc */ -#define SYMINFO_FLG_LAZYLOAD 0x0008 /* object containing defn should be */ - /* lazily-loaded */ -#define SYMINFO_FLG_DIRECTBIND 0x0010 /* ref should be bound directly to */ - /* object containing defn. */ -#define SYMINFO_FLG_NOEXTDIRECT 0x0020 /* don't let an external reference */ - /* directly bind to this symbol */ -#define SYMINFO_FLG_FILTER 0x0002 /* symbol ref is associated to a */ -#define SYMINFO_FLG_AUXILIARY 0x0040 /* standard or auxiliary filter */ - -/* - * Syminfo.si_boundto values. - */ -#define SYMINFO_BT_SELF 0xffff /* symbol bound to self */ -#define SYMINFO_BT_PARENT 0xfffe /* symbol bound to parent */ -#define SYMINFO_BT_NONE 0xfffd /* no special symbol binding */ -#define SYMINFO_BT_EXTERN 0xfffc /* symbol defined as external */ -#define SYMINFO_BT_LOWRESERVE 0xff00 /* beginning of reserved entries */ - -/* - * Syminfo version values. - */ -#define SYMINFO_NONE 0 /* Syminfo version */ -#define SYMINFO_CURRENT 1 -#define SYMINFO_NUM 2 - -/* - * Relocation types. - * - * All machine architectures are defined here to allow tools on one to - * handle others. - */ - -#define R_386_NONE 0 /* No relocation. */ -#define R_386_32 1 /* Add symbol value. */ -#define R_386_PC32 2 /* Add PC-relative symbol value. */ -#define R_386_GOT32 3 /* Add PC-relative GOT offset. */ -#define R_386_PLT32 4 /* Add PC-relative PLT offset. */ -#define R_386_COPY 5 /* Copy data from shared object. */ -#define R_386_GLOB_DAT 6 /* Set GOT entry to data address. */ -#define R_386_JMP_SLOT 7 /* Set GOT entry to code address. */ -#define R_386_RELATIVE 8 /* Add load address of shared object. */ -#define R_386_GOTOFF 9 /* Add GOT-relative symbol address. */ -#define R_386_GOTPC 10 /* Add PC-relative GOT table address. */ -#define R_386_TLS_TPOFF 14 /* Negative offset in static TLS block */ -#define R_386_TLS_IE 15 /* Absolute address of GOT for -ve static TLS */ -#define R_386_TLS_GOTIE 16 /* GOT entry for negative static TLS block */ -#define R_386_TLS_LE 17 /* Negative offset relative to static TLS */ -#define R_386_TLS_GD 18 /* 32 bit offset to GOT (index,off) pair */ -#define R_386_TLS_LDM 19 /* 32 bit offset to GOT (index,zero) pair */ -#define R_386_TLS_GD_32 24 /* 32 bit offset to GOT (index,off) pair */ -#define R_386_TLS_GD_PUSH 25 /* pushl instruction for Sun ABI GD sequence */ -#define R_386_TLS_GD_CALL 26 /* call instruction for Sun ABI GD sequence */ -#define R_386_TLS_GD_POP 27 /* popl instruction for Sun ABI GD sequence */ -#define R_386_TLS_LDM_32 28 /* 32 bit offset to GOT (index,zero) pair */ -#define R_386_TLS_LDM_PUSH 29 /* pushl instruction for Sun ABI LD sequence */ -#define R_386_TLS_LDM_CALL 30 /* call instruction for Sun ABI LD sequence */ -#define R_386_TLS_LDM_POP 31 /* popl instruction for Sun ABI LD sequence */ -#define R_386_TLS_LDO_32 32 /* 32 bit offset from start of TLS block */ -#define R_386_TLS_IE_32 33 /* 32 bit offset to GOT static TLS offset entry */ -#define R_386_TLS_LE_32 34 /* 32 bit offset within static TLS block */ -#define R_386_TLS_DTPMOD32 35 /* GOT entry containing TLS index */ -#define R_386_TLS_DTPOFF32 36 /* GOT entry containing TLS offset */ -#define R_386_TLS_TPOFF32 37 /* GOT entry of -ve static TLS offset */ - -/* Null relocation */ -#define R_AARCH64_NONE 256 /* No relocation */ -/* Static AArch64 relocations */ - /* Static data relocations */ -#define R_AARCH64_ABS64 257 /* S + A */ -#define R_AARCH64_ABS32 258 /* S + A */ -#define R_AARCH64_ABS16 259 /* S + A */ -#define R_AARCH64_PREL64 260 /* S + A - P */ -#define R_AARCH64_PREL32 261 /* S + A - P */ -#define R_AARCH64_PREL16 262 /* S + A - P */ - /* Group relocations to create a 16, 32, 48, or 64 bit unsigned data value or address inline */ -#define R_AARCH64_MOVW_UABS_G0 263 /* S + A */ -#define R_AARCH64_MOVW_UABS_G0_NC 264 /* S + A */ -#define R_AARCH64_MOVW_UABS_G1 265 /* S + A */ -#define R_AARCH64_MOVW_UABS_G1_NC 266 /* S + A */ -#define R_AARCH64_MOVW_UABS_G2 267 /* S + A */ -#define R_AARCH64_MOVW_UABS_G2_NC 268 /* S + A */ -#define R_AARCH64_MOVW_UABS_G3 269 /* S + A */ - /* Group relocations to create a 16, 32, 48, or 64 bit signed data or offset value inline */ -#define R_AARCH64_MOVW_SABS_G0 270 /* S + A */ -#define R_AARCH64_MOVW_SABS_G1 271 /* S + A */ -#define R_AARCH64_MOVW_SABS_G2 272 /* S + A */ - /* Relocations to generate 19, 21 and 33 bit PC-relative addresses */ -#define R_AARCH64_LD_PREL_LO19 273 /* S + A - P */ -#define R_AARCH64_ADR_PREL_LO21 274 /* S + A - P */ -#define R_AARCH64_ADR_PREL_PG_HI21 275 /* Page(S+A) - Page(P) */ -#define R_AARCH64_ADR_PREL_PG_HI21_NC 276 /* Page(S+A) - Page(P) */ -#define R_AARCH64_ADD_ABS_LO12_NC 277 /* S + A */ -#define R_AARCH64_LDST8_ABS_LO12_NC 278 /* S + A */ -#define R_AARCH64_LDST16_ABS_LO12_NC 284 /* S + A */ -#define R_AARCH64_LDST32_ABS_LO12_NC 285 /* S + A */ -#define R_AARCH64_LDST64_ABS_LO12_NC 286 /* S + A */ -#define R_AARCH64_LDST128_ABS_LO12_NC 299 /* S + A */ - /* Relocations for control-flow instructions - all offsets are a multiple of 4 */ -#define R_AARCH64_TSTBR14 279 /* S+A-P */ -#define R_AARCH64_CONDBR19 280 /* S+A-P */ -#define R_AARCH64_JUMP26 282 /* S+A-P */ -#define R_AARCH64_CALL26 283 /* S+A-P */ - /* Group relocations to create a 16, 32, 48, or 64 bit PC-relative offset inline */ -#define R_AARCH64_MOVW_PREL_G0 287 /* S+A-P */ -#define R_AARCH64_MOVW_PREL_G0_NC 288 /* S+A-P */ -#define R_AARCH64_MOVW_PREL_G1 289 /* S+A-P */ -#define R_AARCH64_MOVW_PREL_G1_NC 290 /* S+A-P */ -#define R_AARCH64_MOVW_PREL_G2 291 /* S+A-P */ -#define R_AARCH64_MOVW_PREL_G2_NC 292 /* S+A-P */ -#define R_AARCH64_MOVW_PREL_G3 293 /* S+A-P */ - /* Group relocations to create a 16, 32, 48, or 64 bit GOT-relative offsets inline */ -#define R_AARCH64_MOVW_GOTOFF_G0 300 /* G(S)-GOT */ -#define R_AARCH64_MOVW_GOTOFF_G0_NC 301 /* G(S)-GOT */ -#define R_AARCH64_MOVW_GOTOFF_G1 302 /* G(S)-GOT */ -#define R_AARCH64_MOVW_GOTOFF_G1_NC 303 /* G(S)-GOT */ -#define R_AARCH64_MOVW_GOTOFF_G2 304 /* G(S)-GOT */ -#define R_AARCH64_MOVW_GOTOFF_G2_NC 305 /* G(S)-GOT */ -#define R_AARCH64_MOVW_GOTOFF_G3 306 /* G(S)-GOT */ - /* GOT-relative data relocations */ -#define R_AARCH64_GOTREL64 307 /* S+A-GOT */ -#define R_AARCH64_GOTREL32 308 /* S+A-GOT */ - /* GOT-relative instruction relocations */ -#define R_AARCH64_GOT_LD_PREL19 309 /* G(S)-P */ -#define R_AARCH64_LD64_GOTOFF_LO15 310 /* G(S)-GOT */ -#define R_AARCH64_ADR_GOT_PAGE 311 /* Page(G(S))-Page(P) */ -#define R_AARCH64_LD64_GOT_LO12_NC 312 /* G(S) */ -#define R_AARCH64_LD64_GOTPAGE_LO15 313 /* G(S)-Page(GOT) */ -/* Relocations for thread-local storage */ - /* General Dynamic TLS relocations */ -#define R_AARCH64_TLSGD_ADR_PREL21 512 /* G(TLSIDX(S+A)) - P */ -#define R_AARCH64_TLSGD_ADR_PAGE21 513 /* Page(G(TLSIDX(S+A))) - Page(P) */ -#define R_AARCH64_TLSGD_ADD_LO12_NC 514 /* G(TLSIDX(S+A)) */ -#define R_AARCH64_TLSGD_MOVW_G1 515 /* G(TLSIDX(S+A)) - GOT */ -#define R_AARCH64_TLSGD_MOVW_G0_NC 516 /* G(TLSIDX(S+A)) - GOT */ - /* Local Dynamic TLS relocations */ -#define R_AARCH64_TLSLD_ADR_PREL21 517 /* G(LDM(S))) - P */ -#define R_AARCH64_TLSLD_ADR_PAGE21 518 /* Page(G(LDM(S)))-Page(P) */ -#define R_AARCH64_TLSLD_ADD_LO12_NC 519 /* G(LDM(S)) */ -#define R_AARCH64_TLSLD_MOVW_G1 520 /* G(LDM(S)) - GOT */ -#define R_AARCH64_TLSLD_MOVW_G0_NC 521 /* G(LDM(S)) - GOT */ -#define R_AARCH64_TLSLD_LD_PREL19 522 /* G(LDM(S)) - P */ -#define R_AARCH64_TLSLD_MOVW_DTPREL_G2 523 /* DTPREL(S+A) */ -#define R_AARCH64_TLSLD_MOVW_DTPREL_G1 524 /* DTPREL(S+A) */ -#define R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC 525 /* DTPREL(S+A) */ -#define R_AARCH64_TLSLD_MOVW_DTPREL_G0 526 /* DTPREL(S+A) */ -#define R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC 527 /* DTPREL(S+A) */ -#define R_AARCH64_TLSLD_ADD_DTPREL_HI12 528 /* DTPREL(S+A) */ -#define R_AARCH64_TLSLD_ADD_DTPREL_LO12 529 /* DTPREL(S+A) */ -#define R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC 530 /* DTPREL(S+A) */ -#define R_AARCH64_TLSLD_LDST8_DTPREL_LO12 531 /* DTPREL(S+A) */ -#define R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC 532 /* DTPREL(S+A) */ -#define R_AARCH64_TLSLD_LDST16_DTPREL_LO12 533 /* DTPREL(S+A) */ -#define R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC 534 /* DTPREL(S+A) */ -#define R_AARCH64_TLSLD_LDST32_DTPREL_LO12 535 /* DTPREL(S+A) */ -#define R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC 536 /* DTPREL(S+A) */ -#define R_AARCH64_TLSLD_LDST64_DTPREL_LO12 537 /* DTPREL(S+A) */ -#define R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC 538 /* DTPREL(S+A) */ - /* Initial Exec TLS relocations */ -#define R_AARCH64_TLSIE_MOVW_GOTTPREL_G1 539 /* G(TPREL(S+A)) - GOT */ -#define R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC 540 /* G(TPREL(S+A)) - GOT */ -#define R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 541 /* Page(G(TPREL(S+A))) - Page(P) */ -#define R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC 542 /* G(TPREL(S+A)) */ -#define R_AARCH64_TLSIE_LD_GOTTPREL_PREL19 543 /* G(TPREL(S+A)) - P */ - /* Local Exec TLS relocations */ -#define R_AARCH64_TLSLE_MOVW_TPREL_G2 544 /* TPREL(S+A) */ -#define R_AARCH64_TLSLE_MOVW_TPREL_G1 545 /* TPREL(S+A) */ -#define R_AARCH64_TLSLE_MOVW_TPREL_G1_NC 546 /* TPREL(S+A) */ -#define R_AARCH64_TLSLE_MOVW_TPREL_G0 547 /* TPREL(S+A) */ -#define R_AARCH64_TLSLE_MOVW_TPREL_G0_NC 548 /* TPREL(S+A) */ -#define R_AARCH64_TLSLE_ADD_TPREL_HI12 549 /* TPREL(S+A) */ -#define R_AARCH64_TLSLE_ADD_TPREL_LO12 550 /* TPREL(S+A) */ -#define R_AARCH64_TLSLE_ADD_TPREL_LO12_NC 551 /* TPREL(S+A) */ -#define R_AARCH64_TLSLE_LDST8_TPREL_LO12 552 /* TPREL(S+A) */ -#define R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC 553 /* TPREL(S+A) */ -#define R_AARCH64_TLSLE_LDST16_TPREL_LO12 554 /* TPREL(S+A) */ -#define R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC 555 /* TPREL(S+A) */ -#define R_AARCH64_TLSLE_LDST32_TPREL_LO12 556 /* TPREL(S+A) */ -#define R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC 557 /* TPREL(S+A) */ -#define R_AARCH64_TLSLE_LDST64_TPREL_LO12 558 /* TPREL(S+A) */ -#define R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC 559 /* TPREL(S+A) */ -/* Dynamic relocations */ - /* Dynamic relocations */ -#define R_AARCH64_COPY 1024 -#define R_AARCH64_GLOB_DAT 1025 /* S + A */ -#define R_AARCH64_JUMP_SLOT 1026 /* S + A */ -#define R_AARCH64_RELATIVE 1027 /* Delta(S) + A , Delta(P) + A */ -#define R_AARCH64_TLS_DTPREL64 1028 /* DTPREL(S+A) */ -#define R_AARCH64_TLS_DTPMOD64 1029 /* LDM(S) */ -#define R_AARCH64_TLS_TPREL64 1030 /* TPREL(S+A) */ -#define R_AARCH64_TLS_DTPREL32 1031 /* DTPREL(S+A) */ -#define R_AARCH64_TLS_DTPMOD32 1032 /* LDM(S) */ -#define R_AARCH64_TLS_TPREL32 1033 /* DTPREL(S+A) */ - -#define R_ALPHA_NONE 0 /* No reloc */ -#define R_ALPHA_REFLONG 1 /* Direct 32 bit */ -#define R_ALPHA_REFQUAD 2 /* Direct 64 bit */ -#define R_ALPHA_GPREL32 3 /* GP relative 32 bit */ -#define R_ALPHA_LITERAL 4 /* GP relative 16 bit w/optimization */ -#define R_ALPHA_LITUSE 5 /* Optimization hint for LITERAL */ -#define R_ALPHA_GPDISP 6 /* Add displacement to GP */ -#define R_ALPHA_BRADDR 7 /* PC+4 relative 23 bit shifted */ -#define R_ALPHA_HINT 8 /* PC+4 relative 16 bit shifted */ -#define R_ALPHA_SREL16 9 /* PC relative 16 bit */ -#define R_ALPHA_SREL32 10 /* PC relative 32 bit */ -#define R_ALPHA_SREL64 11 /* PC relative 64 bit */ -#define R_ALPHA_OP_PUSH 12 /* OP stack push */ -#define R_ALPHA_OP_STORE 13 /* OP stack pop and store */ -#define R_ALPHA_OP_PSUB 14 /* OP stack subtract */ -#define R_ALPHA_OP_PRSHIFT 15 /* OP stack right shift */ -#define R_ALPHA_GPVALUE 16 -#define R_ALPHA_GPRELHIGH 17 -#define R_ALPHA_GPRELLOW 18 -#define R_ALPHA_IMMED_GP_16 19 -#define R_ALPHA_IMMED_GP_HI32 20 -#define R_ALPHA_IMMED_SCN_HI32 21 -#define R_ALPHA_IMMED_BR_HI32 22 -#define R_ALPHA_IMMED_LO32 23 -#define R_ALPHA_COPY 24 /* Copy symbol at runtime */ -#define R_ALPHA_GLOB_DAT 25 /* Create GOT entry */ -#define R_ALPHA_JMP_SLOT 26 /* Create PLT entry */ -#define R_ALPHA_RELATIVE 27 /* Adjust by program base */ - -#define R_ARM_NONE 0 /* No relocation. */ -#define R_ARM_PC24 1 -#define R_ARM_ABS32 2 -#define R_ARM_REL32 3 -#define R_ARM_PC13 4 -#define R_ARM_ABS16 5 -#define R_ARM_ABS12 6 -#define R_ARM_THM_ABS5 7 -#define R_ARM_ABS8 8 -#define R_ARM_SBREL32 9 -#define R_ARM_THM_PC22 10 -#define R_ARM_THM_PC8 11 -#define R_ARM_AMP_VCALL9 12 -#define R_ARM_SWI24 13 -#define R_ARM_THM_SWI8 14 -#define R_ARM_XPC25 15 -#define R_ARM_THM_XPC22 16 -#define R_ARM_COPY 20 /* Copy data from shared object. */ -#define R_ARM_GLOB_DAT 21 /* Set GOT entry to data address. */ -#define R_ARM_JUMP_SLOT 22 /* Set GOT entry to code address. */ -#define R_ARM_RELATIVE 23 /* Add load address of shared object. */ -#define R_ARM_GOTOFF 24 /* Add GOT-relative symbol address. */ -#define R_ARM_GOTPC 25 /* Add PC-relative GOT table address. */ -#define R_ARM_GOT32 26 /* Add PC-relative GOT offset. */ -#define R_ARM_PLT32 27 /* Add PC-relative PLT offset. */ -#define R_ARM_CALL 28 -#define R_ARM_JMP24 29 -#define R_ARM_THM_MOVW_ABS_NC 47 -#define R_ARM_THM_MOVT_ABS 48 - -// Block of PC-relative relocations added to work around gcc putting -// object relocations in static executables. -#define R_ARM_THM_JUMP24 30 -#define R_ARM_PREL31 42 -#define R_ARM_MOVW_PREL_NC 45 -#define R_ARM_MOVT_PREL 46 -#define R_ARM_THM_MOVW_PREL_NC 49 -#define R_ARM_THM_MOVT_PREL 50 -#define R_ARM_THM_JMP6 52 -#define R_ARM_THM_ALU_PREL_11_0 53 -#define R_ARM_THM_PC12 54 -#define R_ARM_REL32_NOI 56 +/** @file +Ported ELF include files from FreeBSD + +Copyright (c) 2009 - 2010, Apple Inc. All rights reserved.
+Portions Copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + +**/ +/*- + * Copyright (c) 1998 John D. Polstra. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/sys/sys/elf_common.h,v 1.15.8.2 2007/12/03 21:30:36 marius Exp $ + */ + +#ifndef _SYS_ELF_COMMON_H_ +#define _SYS_ELF_COMMON_H_ 1 + +/* + * ELF definitions that are independent of architecture or word size. + */ + +/* + * Note header. The ".note" section contains an array of notes. Each + * begins with this header, aligned to a word boundary. Immediately + * following the note header is n_namesz bytes of name, padded to the + * next word boundary. Then comes n_descsz bytes of descriptor, again + * padded to a word boundary. The values of n_namesz and n_descsz do + * not include the padding. + */ + +typedef struct { + UINT32 n_namesz; /* Length of name. */ + UINT32 n_descsz; /* Length of descriptor. */ + UINT32 n_type; /* Type of this note. */ +} Elf_Note; + +/* Indexes into the e_ident array. Keep synced with + http://www.sco.com/developers/gabi/latest/ch4.eheader.html */ +#define EI_MAG0 0 /* Magic number, byte 0. */ +#define EI_MAG1 1 /* Magic number, byte 1. */ +#define EI_MAG2 2 /* Magic number, byte 2. */ +#define EI_MAG3 3 /* Magic number, byte 3. */ +#define EI_CLASS 4 /* Class of machine. */ +#define EI_DATA 5 /* Data format. */ +#define EI_VERSION 6 /* ELF format version. */ +#define EI_OSABI 7 /* Operating system / ABI identification */ +#define EI_ABIVERSION 8 /* ABI version */ +#define OLD_EI_BRAND 8 /* Start of architecture identification. */ +#define EI_PAD 9 /* Start of padding (per SVR4 ABI). */ +#define EI_NIDENT 16 /* Size of e_ident array. */ + +/* Values for the magic number bytes. */ +#define ELFMAG0 0x7f +#define ELFMAG1 'E' +#define ELFMAG2 'L' +#define ELFMAG3 'F' +#define ELFMAG "\177ELF" /* magic string */ +#define SELFMAG 4 /* magic string size */ + +/* Values for e_ident[EI_VERSION] and e_version. */ +#define EV_NONE 0 +#define EV_CURRENT 1 + +/* Values for e_ident[EI_CLASS]. */ +#define ELFCLASSNONE 0 /* Unknown class. */ +#define ELFCLASS32 1 /* 32-bit architecture. */ +#define ELFCLASS64 2 /* 64-bit architecture. */ + +/* Values for e_ident[EI_DATA]. */ +#define ELFDATANONE 0 /* Unknown data format. */ +#define ELFDATA2LSB 1 /* 2's complement little-endian. */ +#define ELFDATA2MSB 2 /* 2's complement big-endian. */ + +/* Values for e_ident[EI_OSABI]. */ +#define ELFOSABI_NONE 0 /* UNIX System V ABI */ +#define ELFOSABI_HPUX 1 /* HP-UX operating system */ +#define ELFOSABI_NETBSD 2 /* NetBSD */ +#define ELFOSABI_LINUX 3 /* GNU/Linux */ +#define ELFOSABI_HURD 4 /* GNU/Hurd */ +#define ELFOSABI_86OPEN 5 /* 86Open common IA32 ABI */ +#define ELFOSABI_SOLARIS 6 /* Solaris */ +#define ELFOSABI_AIX 7 /* AIX */ +#define ELFOSABI_IRIX 8 /* IRIX */ +#define ELFOSABI_FREEBSD 9 /* FreeBSD */ +#define ELFOSABI_TRU64 10 /* TRU64 UNIX */ +#define ELFOSABI_MODESTO 11 /* Novell Modesto */ +#define ELFOSABI_OPENBSD 12 /* OpenBSD */ +#define ELFOSABI_OPENVMS 13 /* Open VMS */ +#define ELFOSABI_NSK 14 /* HP Non-Stop Kernel */ +#define ELFOSABI_ARM 97 /* ARM */ +#define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */ + +#define ELFOSABI_SYSV ELFOSABI_NONE /* symbol used in old spec */ +#define ELFOSABI_MONTEREY ELFOSABI_AIX /* Monterey */ + +/* e_ident */ +#define IS_ELF(ehdr) ((ehdr).e_ident[EI_MAG0] == ELFMAG0 && \ + (ehdr).e_ident[EI_MAG1] == ELFMAG1 && \ + (ehdr).e_ident[EI_MAG2] == ELFMAG2 && \ + (ehdr).e_ident[EI_MAG3] == ELFMAG3) + +/* Values for e_type. */ +#define ET_NONE 0 /* Unknown type. */ +#define ET_REL 1 /* Relocatable. */ +#define ET_EXEC 2 /* Executable. */ +#define ET_DYN 3 /* Shared object. */ +#define ET_CORE 4 /* Core file. */ +#define ET_LOOS 0xfe00 /* First operating system specific. */ +#define ET_HIOS 0xfeff /* Last operating system-specific. */ +#define ET_LOPROC 0xff00 /* First processor-specific. */ +#define ET_HIPROC 0xffff /* Last processor-specific. */ + +/* Values for e_machine. */ +#define EM_NONE 0 /* Unknown machine. */ +#define EM_M32 1 /* AT&T WE32100. */ +#define EM_SPARC 2 /* Sun SPARC. */ +#define EM_386 3 /* Intel i386. */ +#define EM_68K 4 /* Motorola 68000. */ +#define EM_88K 5 /* Motorola 88000. */ +#define EM_860 7 /* Intel i860. */ +#define EM_MIPS 8 /* MIPS R3000 Big-Endian only. */ +#define EM_S370 9 /* IBM System/370. */ +#define EM_MIPS_RS3_LE 10 /* MIPS R3000 Little-Endian. */ +#define EM_PARISC 15 /* HP PA-RISC. */ +#define EM_VPP500 17 /* Fujitsu VPP500. */ +#define EM_SPARC32PLUS 18 /* SPARC v8plus. */ +#define EM_960 19 /* Intel 80960. */ +#define EM_PPC 20 /* PowerPC 32-bit. */ +#define EM_PPC64 21 /* PowerPC 64-bit. */ +#define EM_S390 22 /* IBM System/390. */ +#define EM_V800 36 /* NEC V800. */ +#define EM_FR20 37 /* Fujitsu FR20. */ +#define EM_RH32 38 /* TRW RH-32. */ +#define EM_RCE 39 /* Motorola RCE. */ +#define EM_ARM 40 /* ARM. */ +#define EM_SH 42 /* Hitachi SH. */ +#define EM_SPARCV9 43 /* SPARC v9 64-bit. */ +#define EM_TRICORE 44 /* Siemens TriCore embedded processor. */ +#define EM_ARC 45 /* Argonaut RISC Core. */ +#define EM_H8_300 46 /* Hitachi H8/300. */ +#define EM_H8_300H 47 /* Hitachi H8/300H. */ +#define EM_H8S 48 /* Hitachi H8S. */ +#define EM_H8_500 49 /* Hitachi H8/500. */ +#define EM_IA_64 50 /* Intel IA-64 Processor. */ +#define EM_MIPS_X 51 /* Stanford MIPS-X. */ +#define EM_COLDFIRE 52 /* Motorola ColdFire. */ +#define EM_68HC12 53 /* Motorola M68HC12. */ +#define EM_MMA 54 /* Fujitsu MMA. */ +#define EM_PCP 55 /* Siemens PCP. */ +#define EM_NCPU 56 /* Sony nCPU. */ +#define EM_NDR1 57 /* Denso NDR1 microprocessor. */ +#define EM_STARCORE 58 /* Motorola Star*Core processor. */ +#define EM_ME16 59 /* Toyota ME16 processor. */ +#define EM_ST100 60 /* STMicroelectronics ST100 processor. */ +#define EM_TINYJ 61 /* Advanced Logic Corp. TinyJ processor. */ +#define EM_X86_64 62 /* Advanced Micro Devices x86-64 */ +#define EM_AMD64 EM_X86_64 /* Advanced Micro Devices x86-64 (compat) */ +#define EM_AARCH64 183 /* ARM 64bit Architecture */ + +/* Non-standard or deprecated. */ +#define EM_486 6 /* Intel i486. */ +#define EM_MIPS_RS4_BE 10 /* MIPS R4000 Big-Endian */ +#define EM_ALPHA_STD 41 /* Digital Alpha (standard value). */ +#define EM_ALPHA 0x9026 /* Alpha (written in the absence of an ABI) */ + +/* Special section indexes. */ +#define SHN_UNDEF 0 /* Undefined, missing, irrelevant. */ +#define SHN_LORESERVE 0xff00 /* First of reserved range. */ +#define SHN_LOPROC 0xff00 /* First processor-specific. */ +#define SHN_HIPROC 0xff1f /* Last processor-specific. */ +#define SHN_LOOS 0xff20 /* First operating system-specific. */ +#define SHN_HIOS 0xff3f /* Last operating system-specific. */ +#define SHN_ABS 0xfff1 /* Absolute values. */ +#define SHN_COMMON 0xfff2 /* Common data. */ +#define SHN_XINDEX 0xffff /* Escape -- index stored elsewhere. */ +#define SHN_HIRESERVE 0xffff /* Last of reserved range. */ + +/* sh_type */ +#define SHT_NULL 0 /* inactive */ +#define SHT_PROGBITS 1 /* program defined information */ +#define SHT_SYMTAB 2 /* symbol table section */ +#define SHT_STRTAB 3 /* string table section */ +#define SHT_RELA 4 /* relocation section with addends */ +#define SHT_HASH 5 /* symbol hash table section */ +#define SHT_DYNAMIC 6 /* dynamic section */ +#define SHT_NOTE 7 /* note section */ +#define SHT_NOBITS 8 /* no space section */ +#define SHT_REL 9 /* relocation section - no addends */ +#define SHT_SHLIB 10 /* reserved - purpose unknown */ +#define SHT_DYNSYM 11 /* dynamic symbol table section */ +#define SHT_INIT_ARRAY 14 /* Initialization function pointers. */ +#define SHT_FINI_ARRAY 15 /* Termination function pointers. */ +#define SHT_PREINIT_ARRAY 16 /* Pre-initialization function ptrs. */ +#define SHT_GROUP 17 /* Section group. */ +#define SHT_SYMTAB_SHNDX 18 /* Section indexes (see SHN_XINDEX). */ +#define SHT_LOOS 0x60000000 /* First of OS specific semantics */ +#define SHT_LOSUNW 0x6ffffff4 +#define SHT_SUNW_dof 0x6ffffff4 +#define SHT_SUNW_cap 0x6ffffff5 +#define SHT_SUNW_SIGNATURE 0x6ffffff6 +#define SHT_SUNW_ANNOTATE 0x6ffffff7 +#define SHT_SUNW_DEBUGSTR 0x6ffffff8 +#define SHT_SUNW_DEBUG 0x6ffffff9 +#define SHT_SUNW_move 0x6ffffffa +#define SHT_SUNW_COMDAT 0x6ffffffb +#define SHT_SUNW_syminfo 0x6ffffffc +#define SHT_SUNW_verdef 0x6ffffffd +#define SHT_GNU_verdef 0x6ffffffd /* Symbol versions provided */ +#define SHT_SUNW_verneed 0x6ffffffe +#define SHT_GNU_verneed 0x6ffffffe /* Symbol versions required */ +#define SHT_SUNW_versym 0x6fffffff +#define SHT_GNU_versym 0x6fffffff /* Symbol version table */ +#define SHT_HISUNW 0x6fffffff +#define SHT_HIOS 0x6fffffff /* Last of OS specific semantics */ +#define SHT_LOPROC 0x70000000 /* reserved range for processor */ +#define SHT_AMD64_UNWIND 0x70000001 /* unwind information */ +#define SHT_HIPROC 0x7fffffff /* specific section header types */ +#define SHT_LOUSER 0x80000000 /* reserved range for application */ +#define SHT_HIUSER 0xffffffff /* specific indexes */ + +/* Flags for sh_flags. */ +#define SHF_WRITE 0x1 /* Section contains writable data. */ +#define SHF_ALLOC 0x2 /* Section occupies memory. */ +#define SHF_EXECINSTR 0x4 /* Section contains instructions. */ +#define SHF_MERGE 0x10 /* Section may be merged. */ +#define SHF_STRINGS 0x20 /* Section contains strings. */ +#define SHF_INFO_LINK 0x40 /* sh_info holds section index. */ +#define SHF_LINK_ORDER 0x80 /* Special ordering requirements. */ +#define SHF_OS_NONCONFORMING 0x100 /* OS-specific processing required. */ +#define SHF_GROUP 0x200 /* Member of section group. */ +#define SHF_TLS 0x400 /* Section contains TLS data. */ +#define SHF_MASKOS 0x0ff00000 /* OS-specific semantics. */ +#define SHF_MASKPROC 0xf0000000 /* Processor-specific semantics. */ + +/* Values for p_type. */ +#define PT_NULL 0 /* Unused entry. */ +#define PT_LOAD 1 /* Loadable segment. */ +#define PT_DYNAMIC 2 /* Dynamic linking information segment. */ +#define PT_INTERP 3 /* Pathname of interpreter. */ +#define PT_NOTE 4 /* Auxiliary information. */ +#define PT_SHLIB 5 /* Reserved (not used). */ +#define PT_PHDR 6 /* Location of program header itself. */ +#define PT_TLS 7 /* Thread local storage segment */ +#define PT_LOOS 0x60000000 /* First OS-specific. */ +#define PT_SUNW_UNWIND 0x6464e550 /* amd64 UNWIND program header */ +#define PT_GNU_EH_FRAME 0x6474e550 +#define PT_LOSUNW 0x6ffffffa +#define PT_SUNWBSS 0x6ffffffa /* Sun Specific segment */ +#define PT_SUNWSTACK 0x6ffffffb /* describes the stack segment */ +#define PT_SUNWDTRACE 0x6ffffffc /* private */ +#define PT_SUNWCAP 0x6ffffffd /* hard/soft capabilities segment */ +#define PT_HISUNW 0x6fffffff +#define PT_HIOS 0x6fffffff /* Last OS-specific. */ +#define PT_LOPROC 0x70000000 /* First processor-specific type. */ +#define PT_HIPROC 0x7fffffff /* Last processor-specific type. */ + +/* Values for p_flags. */ +#define PF_X 0x1 /* Executable. */ +#define PF_W 0x2 /* Writable. */ +#define PF_R 0x4 /* Readable. */ +#define PF_MASKOS 0x0ff00000 /* Operating system-specific. */ +#define PF_MASKPROC 0xf0000000 /* Processor-specific. */ + +/* Extended program header index. */ +#define PN_XNUM 0xffff + +/* Values for d_tag. */ +#define DT_NULL 0 /* Terminating entry. */ +#define DT_NEEDED 1 /* String table offset of a needed shared + library. */ +#define DT_PLTRELSZ 2 /* Total size in bytes of PLT relocations. */ +#define DT_PLTGOT 3 /* Processor-dependent address. */ +#define DT_HASH 4 /* Address of symbol hash table. */ +#define DT_STRTAB 5 /* Address of string table. */ +#define DT_SYMTAB 6 /* Address of symbol table. */ +#define DT_RELA 7 /* Address of ElfNN_Rela relocations. */ +#define DT_RELASZ 8 /* Total size of ElfNN_Rela relocations. */ +#define DT_RELAENT 9 /* Size of each ElfNN_Rela relocation entry. */ +#define DT_STRSZ 10 /* Size of string table. */ +#define DT_SYMENT 11 /* Size of each symbol table entry. */ +#define DT_INIT 12 /* Address of initialization function. */ +#define DT_FINI 13 /* Address of finalization function. */ +#define DT_SONAME 14 /* String table offset of shared object + name. */ +#define DT_RPATH 15 /* String table offset of library path. [sup] */ +#define DT_SYMBOLIC 16 /* Indicates "symbolic" linking. [sup] */ +#define DT_REL 17 /* Address of ElfNN_Rel relocations. */ +#define DT_RELSZ 18 /* Total size of ElfNN_Rel relocations. */ +#define DT_RELENT 19 /* Size of each ElfNN_Rel relocation. */ +#define DT_PLTREL 20 /* Type of relocation used for PLT. */ +#define DT_DEBUG 21 /* Reserved (not used). */ +#define DT_TEXTREL 22 /* Indicates there may be relocations in + non-writable segments. [sup] */ +#define DT_JMPREL 23 /* Address of PLT relocations. */ +#define DT_BIND_NOW 24 /* [sup] */ +#define DT_INIT_ARRAY 25 /* Address of the array of pointers to + initialization functions */ +#define DT_FINI_ARRAY 26 /* Address of the array of pointers to + termination functions */ +#define DT_INIT_ARRAYSZ 27 /* Size in bytes of the array of + initialization functions. */ +#define DT_FINI_ARRAYSZ 28 /* Size in bytes of the array of + terminationfunctions. */ +#define DT_RUNPATH 29 /* String table offset of a null-terminated + library search path string. */ +#define DT_FLAGS 30 /* Object specific flag values. */ +#define DT_ENCODING 32 /* Values greater than or equal to DT_ENCODING + and less than DT_LOOS follow the rules for + the interpretation of the d_un union + as follows: even == 'd_ptr', even == 'd_val' + or none */ +#define DT_PREINIT_ARRAY 32 /* Address of the array of pointers to + pre-initialization functions. */ +#define DT_PREINIT_ARRAYSZ 33 /* Size in bytes of the array of + pre-initialization functions. */ +#define DT_MAXPOSTAGS 34 /* number of positive tags */ +#define DT_LOOS 0x6000000d /* First OS-specific */ +#define DT_SUNW_AUXILIARY 0x6000000d /* symbol auxiliary name */ +#define DT_SUNW_RTLDINF 0x6000000e /* ld.so.1 info (private) */ +#define DT_SUNW_FILTER 0x6000000f /* symbol filter name */ +#define DT_SUNW_CAP 0x60000010 /* hardware/software */ +#define DT_HIOS 0x6ffff000 /* Last OS-specific */ + +/* + * DT_* entries which fall between DT_VALRNGHI & DT_VALRNGLO use the + * Dyn.d_un.d_val field of the Elf*_Dyn structure. + */ +#define DT_VALRNGLO 0x6ffffd00 +#define DT_CHECKSUM 0x6ffffdf8 /* elf checksum */ +#define DT_PLTPADSZ 0x6ffffdf9 /* pltpadding size */ +#define DT_MOVEENT 0x6ffffdfa /* move table entry size */ +#define DT_MOVESZ 0x6ffffdfb /* move table size */ +#define DT_FEATURE_1 0x6ffffdfc /* feature holder */ +#define DT_POSFLAG_1 0x6ffffdfd /* flags for DT_* entries, effecting */ + /* the following DT_* entry. */ + /* See DF_P1_* definitions */ +#define DT_SYMINSZ 0x6ffffdfe /* syminfo table size (in bytes) */ +#define DT_SYMINENT 0x6ffffdff /* syminfo entry size (in bytes) */ +#define DT_VALRNGHI 0x6ffffdff + +/* + * DT_* entries which fall between DT_ADDRRNGHI & DT_ADDRRNGLO use the + * Dyn.d_un.d_ptr field of the Elf*_Dyn structure. + * + * If any adjustment is made to the ELF object after it has been + * built, these entries will need to be adjusted. + */ +#define DT_ADDRRNGLO 0x6ffffe00 +#define DT_CONFIG 0x6ffffefa /* configuration information */ +#define DT_DEPAUDIT 0x6ffffefb /* dependency auditing */ +#define DT_AUDIT 0x6ffffefc /* object auditing */ +#define DT_PLTPAD 0x6ffffefd /* pltpadding (sparcv9) */ +#define DT_MOVETAB 0x6ffffefe /* move table */ +#define DT_SYMINFO 0x6ffffeff /* syminfo table */ +#define DT_ADDRRNGHI 0x6ffffeff + +#define DT_VERSYM 0x6ffffff0 /* Address of versym section. */ +#define DT_RELACOUNT 0x6ffffff9 /* number of RELATIVE relocations */ +#define DT_RELCOUNT 0x6ffffffa /* number of RELATIVE relocations */ +#define DT_FLAGS_1 0x6ffffffb /* state flags - see DF_1_* defs */ +#define DT_VERDEF 0x6ffffffc /* Address of verdef section. */ +#define DT_VERDEFNUM 0x6ffffffd /* Number of elems in verdef section */ +#define DT_VERNEED 0x6ffffffe /* Address of verneed section. */ +#define DT_VERNEEDNUM 0x6fffffff /* Number of elems in verneed section */ + +#define DT_LOPROC 0x70000000 /* First processor-specific type. */ +#define DT_DEPRECATED_SPARC_REGISTER 0x7000001 +#define DT_AUXILIARY 0x7ffffffd /* shared library auxiliary name */ +#define DT_USED 0x7ffffffe /* ignored - same as needed */ +#define DT_FILTER 0x7fffffff /* shared library filter name */ +#define DT_HIPROC 0x7fffffff /* Last processor-specific type. */ + +/* Values for DT_FLAGS */ +#define DF_ORIGIN 0x0001 /* Indicates that the object being loaded may + make reference to the $ORIGIN substitution + string */ +#define DF_SYMBOLIC 0x0002 /* Indicates "symbolic" linking. */ +#define DF_TEXTREL 0x0004 /* Indicates there may be relocations in + non-writable segments. */ +#define DF_BIND_NOW 0x0008 /* Indicates that the dynamic linker should + process all relocations for the object + containing this entry before transferring + control to the program. */ +#define DF_STATIC_TLS 0x0010 /* Indicates that the shared object or + executable contains code using a static + thread-local storage scheme. */ + +/* Values for n_type. Used in core files. */ +#define NT_PRSTATUS 1 /* Process status. */ +#define NT_FPREGSET 2 /* Floating point registers. */ +#define NT_PRPSINFO 3 /* Process state info. */ + +/* Symbol Binding - ELFNN_ST_BIND - st_info */ +#define STB_LOCAL 0 /* Local symbol */ +#define STB_GLOBAL 1 /* Global symbol */ +#define STB_WEAK 2 /* like global - lower precedence */ +#define STB_LOOS 10 /* Reserved range for operating system */ +#define STB_HIOS 12 /* specific semantics. */ +#define STB_LOPROC 13 /* reserved range for processor */ +#define STB_HIPROC 15 /* specific semantics. */ + +/* Symbol type - ELFNN_ST_TYPE - st_info */ +#define STT_NOTYPE 0 /* Unspecified type. */ +#define STT_OBJECT 1 /* Data object. */ +#define STT_FUNC 2 /* Function. */ +#define STT_SECTION 3 /* Section. */ +#define STT_FILE 4 /* Source file. */ +#define STT_COMMON 5 /* Uninitialized common block. */ +#define STT_TLS 6 /* TLS object. */ +#define STT_NUM 7 +#define STT_LOOS 10 /* Reserved range for operating system */ +#define STT_HIOS 12 /* specific semantics. */ +#define STT_LOPROC 13 /* reserved range for processor */ +#define STT_HIPROC 15 /* specific semantics. */ + +/* Symbol visibility - ELFNN_ST_VISIBILITY - st_other */ +#define STV_DEFAULT 0x0 /* Default visibility (see binding). */ +#define STV_INTERNAL 0x1 /* Special meaning in relocatable objects. */ +#define STV_HIDDEN 0x2 /* Not visible. */ +#define STV_PROTECTED 0x3 /* Visible but not preemptible. */ + +/* Special symbol table indexes. */ +#define STN_UNDEF 0 /* Undefined symbol index. */ + +/* Symbol versioning flags. */ +#define VER_DEF_CURRENT 1 +#define VER_DEF_IDX(x) VER_NDX(x) + +#define VER_FLG_BASE 0x01 +#define VER_FLG_WEAK 0x02 + +#define VER_NEED_CURRENT 1 +#define VER_NEED_WEAK (1u << 15) +#define VER_NEED_HIDDEN VER_NDX_HIDDEN +#define VER_NEED_IDX(x) VER_NDX(x) + +#define VER_NDX_LOCAL 0 +#define VER_NDX_GLOBAL 1 +#define VER_NDX_GIVEN 2 + +#define VER_NDX_HIDDEN (1u << 15) +#define VER_NDX(x) ((x) & ~(1u << 15)) + +#define CA_SUNW_NULL 0 +#define CA_SUNW_HW_1 1 /* first hardware capabilities entry */ +#define CA_SUNW_SF_1 2 /* first software capabilities entry */ + +/* + * Syminfo flag values + */ +#define SYMINFO_FLG_DIRECT 0x0001 /* symbol ref has direct association */ + /* to object containing defn. */ +#define SYMINFO_FLG_PASSTHRU 0x0002 /* ignored - see SYMINFO_FLG_FILTER */ +#define SYMINFO_FLG_COPY 0x0004 /* symbol is a copy-reloc */ +#define SYMINFO_FLG_LAZYLOAD 0x0008 /* object containing defn should be */ + /* lazily-loaded */ +#define SYMINFO_FLG_DIRECTBIND 0x0010 /* ref should be bound directly to */ + /* object containing defn. */ +#define SYMINFO_FLG_NOEXTDIRECT 0x0020 /* don't let an external reference */ + /* directly bind to this symbol */ +#define SYMINFO_FLG_FILTER 0x0002 /* symbol ref is associated to a */ +#define SYMINFO_FLG_AUXILIARY 0x0040 /* standard or auxiliary filter */ + +/* + * Syminfo.si_boundto values. + */ +#define SYMINFO_BT_SELF 0xffff /* symbol bound to self */ +#define SYMINFO_BT_PARENT 0xfffe /* symbol bound to parent */ +#define SYMINFO_BT_NONE 0xfffd /* no special symbol binding */ +#define SYMINFO_BT_EXTERN 0xfffc /* symbol defined as external */ +#define SYMINFO_BT_LOWRESERVE 0xff00 /* beginning of reserved entries */ + +/* + * Syminfo version values. + */ +#define SYMINFO_NONE 0 /* Syminfo version */ +#define SYMINFO_CURRENT 1 +#define SYMINFO_NUM 2 + +/* + * Relocation types. + * + * All machine architectures are defined here to allow tools on one to + * handle others. + */ + +#define R_386_NONE 0 /* No relocation. */ +#define R_386_32 1 /* Add symbol value. */ +#define R_386_PC32 2 /* Add PC-relative symbol value. */ +#define R_386_GOT32 3 /* Add PC-relative GOT offset. */ +#define R_386_PLT32 4 /* Add PC-relative PLT offset. */ +#define R_386_COPY 5 /* Copy data from shared object. */ +#define R_386_GLOB_DAT 6 /* Set GOT entry to data address. */ +#define R_386_JMP_SLOT 7 /* Set GOT entry to code address. */ +#define R_386_RELATIVE 8 /* Add load address of shared object. */ +#define R_386_GOTOFF 9 /* Add GOT-relative symbol address. */ +#define R_386_GOTPC 10 /* Add PC-relative GOT table address. */ +#define R_386_TLS_TPOFF 14 /* Negative offset in static TLS block */ +#define R_386_TLS_IE 15 /* Absolute address of GOT for -ve static TLS */ +#define R_386_TLS_GOTIE 16 /* GOT entry for negative static TLS block */ +#define R_386_TLS_LE 17 /* Negative offset relative to static TLS */ +#define R_386_TLS_GD 18 /* 32 bit offset to GOT (index,off) pair */ +#define R_386_TLS_LDM 19 /* 32 bit offset to GOT (index,zero) pair */ +#define R_386_TLS_GD_32 24 /* 32 bit offset to GOT (index,off) pair */ +#define R_386_TLS_GD_PUSH 25 /* pushl instruction for Sun ABI GD sequence */ +#define R_386_TLS_GD_CALL 26 /* call instruction for Sun ABI GD sequence */ +#define R_386_TLS_GD_POP 27 /* popl instruction for Sun ABI GD sequence */ +#define R_386_TLS_LDM_32 28 /* 32 bit offset to GOT (index,zero) pair */ +#define R_386_TLS_LDM_PUSH 29 /* pushl instruction for Sun ABI LD sequence */ +#define R_386_TLS_LDM_CALL 30 /* call instruction for Sun ABI LD sequence */ +#define R_386_TLS_LDM_POP 31 /* popl instruction for Sun ABI LD sequence */ +#define R_386_TLS_LDO_32 32 /* 32 bit offset from start of TLS block */ +#define R_386_TLS_IE_32 33 /* 32 bit offset to GOT static TLS offset entry */ +#define R_386_TLS_LE_32 34 /* 32 bit offset within static TLS block */ +#define R_386_TLS_DTPMOD32 35 /* GOT entry containing TLS index */ +#define R_386_TLS_DTPOFF32 36 /* GOT entry containing TLS offset */ +#define R_386_TLS_TPOFF32 37 /* GOT entry of -ve static TLS offset */ + +/* Null relocation */ +#define R_AARCH64_NONE 256 /* No relocation */ +/* Static AArch64 relocations */ + /* Static data relocations */ +#define R_AARCH64_ABS64 257 /* S + A */ +#define R_AARCH64_ABS32 258 /* S + A */ +#define R_AARCH64_ABS16 259 /* S + A */ +#define R_AARCH64_PREL64 260 /* S + A - P */ +#define R_AARCH64_PREL32 261 /* S + A - P */ +#define R_AARCH64_PREL16 262 /* S + A - P */ + /* Group relocations to create a 16, 32, 48, or 64 bit unsigned data value or address inline */ +#define R_AARCH64_MOVW_UABS_G0 263 /* S + A */ +#define R_AARCH64_MOVW_UABS_G0_NC 264 /* S + A */ +#define R_AARCH64_MOVW_UABS_G1 265 /* S + A */ +#define R_AARCH64_MOVW_UABS_G1_NC 266 /* S + A */ +#define R_AARCH64_MOVW_UABS_G2 267 /* S + A */ +#define R_AARCH64_MOVW_UABS_G2_NC 268 /* S + A */ +#define R_AARCH64_MOVW_UABS_G3 269 /* S + A */ + /* Group relocations to create a 16, 32, 48, or 64 bit signed data or offset value inline */ +#define R_AARCH64_MOVW_SABS_G0 270 /* S + A */ +#define R_AARCH64_MOVW_SABS_G1 271 /* S + A */ +#define R_AARCH64_MOVW_SABS_G2 272 /* S + A */ + /* Relocations to generate 19, 21 and 33 bit PC-relative addresses */ +#define R_AARCH64_LD_PREL_LO19 273 /* S + A - P */ +#define R_AARCH64_ADR_PREL_LO21 274 /* S + A - P */ +#define R_AARCH64_ADR_PREL_PG_HI21 275 /* Page(S+A) - Page(P) */ +#define R_AARCH64_ADR_PREL_PG_HI21_NC 276 /* Page(S+A) - Page(P) */ +#define R_AARCH64_ADD_ABS_LO12_NC 277 /* S + A */ +#define R_AARCH64_LDST8_ABS_LO12_NC 278 /* S + A */ +#define R_AARCH64_LDST16_ABS_LO12_NC 284 /* S + A */ +#define R_AARCH64_LDST32_ABS_LO12_NC 285 /* S + A */ +#define R_AARCH64_LDST64_ABS_LO12_NC 286 /* S + A */ +#define R_AARCH64_LDST128_ABS_LO12_NC 299 /* S + A */ + /* Relocations for control-flow instructions - all offsets are a multiple of 4 */ +#define R_AARCH64_TSTBR14 279 /* S+A-P */ +#define R_AARCH64_CONDBR19 280 /* S+A-P */ +#define R_AARCH64_JUMP26 282 /* S+A-P */ +#define R_AARCH64_CALL26 283 /* S+A-P */ + /* Group relocations to create a 16, 32, 48, or 64 bit PC-relative offset inline */ +#define R_AARCH64_MOVW_PREL_G0 287 /* S+A-P */ +#define R_AARCH64_MOVW_PREL_G0_NC 288 /* S+A-P */ +#define R_AARCH64_MOVW_PREL_G1 289 /* S+A-P */ +#define R_AARCH64_MOVW_PREL_G1_NC 290 /* S+A-P */ +#define R_AARCH64_MOVW_PREL_G2 291 /* S+A-P */ +#define R_AARCH64_MOVW_PREL_G2_NC 292 /* S+A-P */ +#define R_AARCH64_MOVW_PREL_G3 293 /* S+A-P */ + /* Group relocations to create a 16, 32, 48, or 64 bit GOT-relative offsets inline */ +#define R_AARCH64_MOVW_GOTOFF_G0 300 /* G(S)-GOT */ +#define R_AARCH64_MOVW_GOTOFF_G0_NC 301 /* G(S)-GOT */ +#define R_AARCH64_MOVW_GOTOFF_G1 302 /* G(S)-GOT */ +#define R_AARCH64_MOVW_GOTOFF_G1_NC 303 /* G(S)-GOT */ +#define R_AARCH64_MOVW_GOTOFF_G2 304 /* G(S)-GOT */ +#define R_AARCH64_MOVW_GOTOFF_G2_NC 305 /* G(S)-GOT */ +#define R_AARCH64_MOVW_GOTOFF_G3 306 /* G(S)-GOT */ + /* GOT-relative data relocations */ +#define R_AARCH64_GOTREL64 307 /* S+A-GOT */ +#define R_AARCH64_GOTREL32 308 /* S+A-GOT */ + /* GOT-relative instruction relocations */ +#define R_AARCH64_GOT_LD_PREL19 309 /* G(S)-P */ +#define R_AARCH64_LD64_GOTOFF_LO15 310 /* G(S)-GOT */ +#define R_AARCH64_ADR_GOT_PAGE 311 /* Page(G(S))-Page(P) */ +#define R_AARCH64_LD64_GOT_LO12_NC 312 /* G(S) */ +#define R_AARCH64_LD64_GOTPAGE_LO15 313 /* G(S)-Page(GOT) */ +/* Relocations for thread-local storage */ + /* General Dynamic TLS relocations */ +#define R_AARCH64_TLSGD_ADR_PREL21 512 /* G(TLSIDX(S+A)) - P */ +#define R_AARCH64_TLSGD_ADR_PAGE21 513 /* Page(G(TLSIDX(S+A))) - Page(P) */ +#define R_AARCH64_TLSGD_ADD_LO12_NC 514 /* G(TLSIDX(S+A)) */ +#define R_AARCH64_TLSGD_MOVW_G1 515 /* G(TLSIDX(S+A)) - GOT */ +#define R_AARCH64_TLSGD_MOVW_G0_NC 516 /* G(TLSIDX(S+A)) - GOT */ + /* Local Dynamic TLS relocations */ +#define R_AARCH64_TLSLD_ADR_PREL21 517 /* G(LDM(S))) - P */ +#define R_AARCH64_TLSLD_ADR_PAGE21 518 /* Page(G(LDM(S)))-Page(P) */ +#define R_AARCH64_TLSLD_ADD_LO12_NC 519 /* G(LDM(S)) */ +#define R_AARCH64_TLSLD_MOVW_G1 520 /* G(LDM(S)) - GOT */ +#define R_AARCH64_TLSLD_MOVW_G0_NC 521 /* G(LDM(S)) - GOT */ +#define R_AARCH64_TLSLD_LD_PREL19 522 /* G(LDM(S)) - P */ +#define R_AARCH64_TLSLD_MOVW_DTPREL_G2 523 /* DTPREL(S+A) */ +#define R_AARCH64_TLSLD_MOVW_DTPREL_G1 524 /* DTPREL(S+A) */ +#define R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC 525 /* DTPREL(S+A) */ +#define R_AARCH64_TLSLD_MOVW_DTPREL_G0 526 /* DTPREL(S+A) */ +#define R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC 527 /* DTPREL(S+A) */ +#define R_AARCH64_TLSLD_ADD_DTPREL_HI12 528 /* DTPREL(S+A) */ +#define R_AARCH64_TLSLD_ADD_DTPREL_LO12 529 /* DTPREL(S+A) */ +#define R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC 530 /* DTPREL(S+A) */ +#define R_AARCH64_TLSLD_LDST8_DTPREL_LO12 531 /* DTPREL(S+A) */ +#define R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC 532 /* DTPREL(S+A) */ +#define R_AARCH64_TLSLD_LDST16_DTPREL_LO12 533 /* DTPREL(S+A) */ +#define R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC 534 /* DTPREL(S+A) */ +#define R_AARCH64_TLSLD_LDST32_DTPREL_LO12 535 /* DTPREL(S+A) */ +#define R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC 536 /* DTPREL(S+A) */ +#define R_AARCH64_TLSLD_LDST64_DTPREL_LO12 537 /* DTPREL(S+A) */ +#define R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC 538 /* DTPREL(S+A) */ + /* Initial Exec TLS relocations */ +#define R_AARCH64_TLSIE_MOVW_GOTTPREL_G1 539 /* G(TPREL(S+A)) - GOT */ +#define R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC 540 /* G(TPREL(S+A)) - GOT */ +#define R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 541 /* Page(G(TPREL(S+A))) - Page(P) */ +#define R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC 542 /* G(TPREL(S+A)) */ +#define R_AARCH64_TLSIE_LD_GOTTPREL_PREL19 543 /* G(TPREL(S+A)) - P */ + /* Local Exec TLS relocations */ +#define R_AARCH64_TLSLE_MOVW_TPREL_G2 544 /* TPREL(S+A) */ +#define R_AARCH64_TLSLE_MOVW_TPREL_G1 545 /* TPREL(S+A) */ +#define R_AARCH64_TLSLE_MOVW_TPREL_G1_NC 546 /* TPREL(S+A) */ +#define R_AARCH64_TLSLE_MOVW_TPREL_G0 547 /* TPREL(S+A) */ +#define R_AARCH64_TLSLE_MOVW_TPREL_G0_NC 548 /* TPREL(S+A) */ +#define R_AARCH64_TLSLE_ADD_TPREL_HI12 549 /* TPREL(S+A) */ +#define R_AARCH64_TLSLE_ADD_TPREL_LO12 550 /* TPREL(S+A) */ +#define R_AARCH64_TLSLE_ADD_TPREL_LO12_NC 551 /* TPREL(S+A) */ +#define R_AARCH64_TLSLE_LDST8_TPREL_LO12 552 /* TPREL(S+A) */ +#define R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC 553 /* TPREL(S+A) */ +#define R_AARCH64_TLSLE_LDST16_TPREL_LO12 554 /* TPREL(S+A) */ +#define R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC 555 /* TPREL(S+A) */ +#define R_AARCH64_TLSLE_LDST32_TPREL_LO12 556 /* TPREL(S+A) */ +#define R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC 557 /* TPREL(S+A) */ +#define R_AARCH64_TLSLE_LDST64_TPREL_LO12 558 /* TPREL(S+A) */ +#define R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC 559 /* TPREL(S+A) */ +/* Dynamic relocations */ + /* Dynamic relocations */ +#define R_AARCH64_COPY 1024 +#define R_AARCH64_GLOB_DAT 1025 /* S + A */ +#define R_AARCH64_JUMP_SLOT 1026 /* S + A */ +#define R_AARCH64_RELATIVE 1027 /* Delta(S) + A , Delta(P) + A */ +#define R_AARCH64_TLS_DTPREL64 1028 /* DTPREL(S+A) */ +#define R_AARCH64_TLS_DTPMOD64 1029 /* LDM(S) */ +#define R_AARCH64_TLS_TPREL64 1030 /* TPREL(S+A) */ +#define R_AARCH64_TLS_DTPREL32 1031 /* DTPREL(S+A) */ +#define R_AARCH64_TLS_DTPMOD32 1032 /* LDM(S) */ +#define R_AARCH64_TLS_TPREL32 1033 /* DTPREL(S+A) */ + +#define R_ALPHA_NONE 0 /* No reloc */ +#define R_ALPHA_REFLONG 1 /* Direct 32 bit */ +#define R_ALPHA_REFQUAD 2 /* Direct 64 bit */ +#define R_ALPHA_GPREL32 3 /* GP relative 32 bit */ +#define R_ALPHA_LITERAL 4 /* GP relative 16 bit w/optimization */ +#define R_ALPHA_LITUSE 5 /* Optimization hint for LITERAL */ +#define R_ALPHA_GPDISP 6 /* Add displacement to GP */ +#define R_ALPHA_BRADDR 7 /* PC+4 relative 23 bit shifted */ +#define R_ALPHA_HINT 8 /* PC+4 relative 16 bit shifted */ +#define R_ALPHA_SREL16 9 /* PC relative 16 bit */ +#define R_ALPHA_SREL32 10 /* PC relative 32 bit */ +#define R_ALPHA_SREL64 11 /* PC relative 64 bit */ +#define R_ALPHA_OP_PUSH 12 /* OP stack push */ +#define R_ALPHA_OP_STORE 13 /* OP stack pop and store */ +#define R_ALPHA_OP_PSUB 14 /* OP stack subtract */ +#define R_ALPHA_OP_PRSHIFT 15 /* OP stack right shift */ +#define R_ALPHA_GPVALUE 16 +#define R_ALPHA_GPRELHIGH 17 +#define R_ALPHA_GPRELLOW 18 +#define R_ALPHA_IMMED_GP_16 19 +#define R_ALPHA_IMMED_GP_HI32 20 +#define R_ALPHA_IMMED_SCN_HI32 21 +#define R_ALPHA_IMMED_BR_HI32 22 +#define R_ALPHA_IMMED_LO32 23 +#define R_ALPHA_COPY 24 /* Copy symbol at runtime */ +#define R_ALPHA_GLOB_DAT 25 /* Create GOT entry */ +#define R_ALPHA_JMP_SLOT 26 /* Create PLT entry */ +#define R_ALPHA_RELATIVE 27 /* Adjust by program base */ + +#define R_ARM_NONE 0 /* No relocation. */ +#define R_ARM_PC24 1 +#define R_ARM_ABS32 2 +#define R_ARM_REL32 3 +#define R_ARM_PC13 4 +#define R_ARM_ABS16 5 +#define R_ARM_ABS12 6 +#define R_ARM_THM_ABS5 7 +#define R_ARM_ABS8 8 +#define R_ARM_SBREL32 9 +#define R_ARM_THM_PC22 10 +#define R_ARM_THM_PC8 11 +#define R_ARM_AMP_VCALL9 12 +#define R_ARM_SWI24 13 +#define R_ARM_THM_SWI8 14 +#define R_ARM_XPC25 15 +#define R_ARM_THM_XPC22 16 +#define R_ARM_COPY 20 /* Copy data from shared object. */ +#define R_ARM_GLOB_DAT 21 /* Set GOT entry to data address. */ +#define R_ARM_JUMP_SLOT 22 /* Set GOT entry to code address. */ +#define R_ARM_RELATIVE 23 /* Add load address of shared object. */ +#define R_ARM_GOTOFF 24 /* Add GOT-relative symbol address. */ +#define R_ARM_GOTPC 25 /* Add PC-relative GOT table address. */ +#define R_ARM_GOT32 26 /* Add PC-relative GOT offset. */ +#define R_ARM_PLT32 27 /* Add PC-relative PLT offset. */ +#define R_ARM_CALL 28 +#define R_ARM_JMP24 29 +#define R_ARM_THM_MOVW_ABS_NC 47 +#define R_ARM_THM_MOVT_ABS 48 + +// Block of PC-relative relocations added to work around gcc putting +// object relocations in static executables. +#define R_ARM_THM_JUMP24 30 +#define R_ARM_PREL31 42 +#define R_ARM_MOVW_PREL_NC 45 +#define R_ARM_MOVT_PREL 46 +#define R_ARM_THM_MOVW_PREL_NC 49 +#define R_ARM_THM_MOVT_PREL 50 +#define R_ARM_THM_JMP6 52 +#define R_ARM_THM_ALU_PREL_11_0 53 +#define R_ARM_THM_PC12 54 +#define R_ARM_REL32_NOI 56 #define R_ARM_ALU_PC_G0_NC 57 #define R_ARM_ALU_PC_G0 58 #define R_ARM_ALU_PC_G1_NC 59 @@ -757,301 +757,301 @@ typedef struct { #define R_ARM_LDRS_PC_G2 66 #define R_ARM_LDC_PC_G0 67 #define R_ARM_LDC_PC_G1 68 -#define R_ARM_LDC_PC_G2 69 -#define R_ARM_GOT_PREL 96 -#define R_ARM_THM_JUMP11 102 -#define R_ARM_THM_JUMP8 103 -#define R_ARM_TLS_GD32 104 -#define R_ARM_TLS_LDM32 105 -#define R_ARM_TLS_IE32 107 - -#define R_ARM_THM_JUMP19 51 -#define R_ARM_GNU_VTENTRY 100 -#define R_ARM_GNU_VTINHERIT 101 -#define R_ARM_RSBREL32 250 -#define R_ARM_THM_RPC22 251 -#define R_ARM_RREL32 252 -#define R_ARM_RABS32 253 -#define R_ARM_RPC24 254 -#define R_ARM_RBASE 255 - - - -/* Name Value Field Calculation */ -#define R_IA_64_NONE 0 /* None */ -#define R_IA_64_IMM14 0x21 /* immediate14 S + A */ -#define R_IA_64_IMM22 0x22 /* immediate22 S + A */ -#define R_IA_64_IMM64 0x23 /* immediate64 S + A */ -#define R_IA_64_DIR32MSB 0x24 /* word32 MSB S + A */ -#define R_IA_64_DIR32LSB 0x25 /* word32 LSB S + A */ -#define R_IA_64_DIR64MSB 0x26 /* word64 MSB S + A */ -#define R_IA_64_DIR64LSB 0x27 /* word64 LSB S + A */ -#define R_IA_64_GPREL22 0x2a /* immediate22 @gprel(S + A) */ -#define R_IA_64_GPREL64I 0x2b /* immediate64 @gprel(S + A) */ -#define R_IA_64_GPREL32MSB 0x2c /* word32 MSB @gprel(S + A) */ -#define R_IA_64_GPREL32LSB 0x2d /* word32 LSB @gprel(S + A) */ -#define R_IA_64_GPREL64MSB 0x2e /* word64 MSB @gprel(S + A) */ -#define R_IA_64_GPREL64LSB 0x2f /* word64 LSB @gprel(S + A) */ -#define R_IA_64_LTOFF22 0x32 /* immediate22 @ltoff(S + A) */ -#define R_IA_64_LTOFF64I 0x33 /* immediate64 @ltoff(S + A) */ -#define R_IA_64_PLTOFF22 0x3a /* immediate22 @pltoff(S + A) */ -#define R_IA_64_PLTOFF64I 0x3b /* immediate64 @pltoff(S + A) */ -#define R_IA_64_PLTOFF64MSB 0x3e /* word64 MSB @pltoff(S + A) */ -#define R_IA_64_PLTOFF64LSB 0x3f /* word64 LSB @pltoff(S + A) */ -#define R_IA_64_FPTR64I 0x43 /* immediate64 @fptr(S + A) */ -#define R_IA_64_FPTR32MSB 0x44 /* word32 MSB @fptr(S + A) */ -#define R_IA_64_FPTR32LSB 0x45 /* word32 LSB @fptr(S + A) */ -#define R_IA_64_FPTR64MSB 0x46 /* word64 MSB @fptr(S + A) */ -#define R_IA_64_FPTR64LSB 0x47 /* word64 LSB @fptr(S + A) */ -#define R_IA_64_PCREL60B 0x48 /* immediate60 form1 S + A - P */ -#define R_IA_64_PCREL21B 0x49 /* immediate21 form1 S + A - P */ -#define R_IA_64_PCREL21M 0x4a /* immediate21 form2 S + A - P */ -#define R_IA_64_PCREL21F 0x4b /* immediate21 form3 S + A - P */ -#define R_IA_64_PCREL32MSB 0x4c /* word32 MSB S + A - P */ -#define R_IA_64_PCREL32LSB 0x4d /* word32 LSB S + A - P */ -#define R_IA_64_PCREL64MSB 0x4e /* word64 MSB S + A - P */ -#define R_IA_64_PCREL64LSB 0x4f /* word64 LSB S + A - P */ -#define R_IA_64_LTOFF_FPTR22 0x52 /* immediate22 @ltoff(@fptr(S + A)) */ -#define R_IA_64_LTOFF_FPTR64I 0x53 /* immediate64 @ltoff(@fptr(S + A)) */ -#define R_IA_64_LTOFF_FPTR32MSB 0x54 /* word32 MSB @ltoff(@fptr(S + A)) */ -#define R_IA_64_LTOFF_FPTR32LSB 0x55 /* word32 LSB @ltoff(@fptr(S + A)) */ -#define R_IA_64_LTOFF_FPTR64MSB 0x56 /* word64 MSB @ltoff(@fptr(S + A)) */ -#define R_IA_64_LTOFF_FPTR64LSB 0x57 /* word64 LSB @ltoff(@fptr(S + A)) */ -#define R_IA_64_SEGREL32MSB 0x5c /* word32 MSB @segrel(S + A) */ -#define R_IA_64_SEGREL32LSB 0x5d /* word32 LSB @segrel(S + A) */ -#define R_IA_64_SEGREL64MSB 0x5e /* word64 MSB @segrel(S + A) */ -#define R_IA_64_SEGREL64LSB 0x5f /* word64 LSB @segrel(S + A) */ -#define R_IA_64_SECREL32MSB 0x64 /* word32 MSB @secrel(S + A) */ -#define R_IA_64_SECREL32LSB 0x65 /* word32 LSB @secrel(S + A) */ -#define R_IA_64_SECREL64MSB 0x66 /* word64 MSB @secrel(S + A) */ -#define R_IA_64_SECREL64LSB 0x67 /* word64 LSB @secrel(S + A) */ -#define R_IA_64_REL32MSB 0x6c /* word32 MSB BD + A */ -#define R_IA_64_REL32LSB 0x6d /* word32 LSB BD + A */ -#define R_IA_64_REL64MSB 0x6e /* word64 MSB BD + A */ -#define R_IA_64_REL64LSB 0x6f /* word64 LSB BD + A */ -#define R_IA_64_LTV32MSB 0x74 /* word32 MSB S + A */ -#define R_IA_64_LTV32LSB 0x75 /* word32 LSB S + A */ -#define R_IA_64_LTV64MSB 0x76 /* word64 MSB S + A */ -#define R_IA_64_LTV64LSB 0x77 /* word64 LSB S + A */ -#define R_IA_64_PCREL21BI 0x79 /* immediate21 form1 S + A - P */ -#define R_IA_64_PCREL22 0x7a /* immediate22 S + A - P */ -#define R_IA_64_PCREL64I 0x7b /* immediate64 S + A - P */ -#define R_IA_64_IPLTMSB 0x80 /* function descriptor MSB special */ -#define R_IA_64_IPLTLSB 0x81 /* function descriptor LSB speciaal */ -#define R_IA_64_SUB 0x85 /* immediate64 A - S */ -#define R_IA_64_LTOFF22X 0x86 /* immediate22 special */ -#define R_IA_64_LDXMOV 0x87 /* immediate22 special */ -#define R_IA_64_TPREL14 0x91 /* imm14 @tprel(S + A) */ -#define R_IA_64_TPREL22 0x92 /* imm22 @tprel(S + A) */ -#define R_IA_64_TPREL64I 0x93 /* imm64 @tprel(S + A) */ -#define R_IA_64_TPREL64MSB 0x96 /* word64 MSB @tprel(S + A) */ -#define R_IA_64_TPREL64LSB 0x97 /* word64 LSB @tprel(S + A) */ -#define R_IA_64_LTOFF_TPREL22 0x9a /* imm22 @ltoff(@tprel(S+A)) */ -#define R_IA_64_DTPMOD64MSB 0xa6 /* word64 MSB @dtpmod(S + A) */ -#define R_IA_64_DTPMOD64LSB 0xa7 /* word64 LSB @dtpmod(S + A) */ -#define R_IA_64_LTOFF_DTPMOD22 0xaa /* imm22 @ltoff(@dtpmod(S+A)) */ -#define R_IA_64_DTPREL14 0xb1 /* imm14 @dtprel(S + A) */ -#define R_IA_64_DTPREL22 0xb2 /* imm22 @dtprel(S + A) */ -#define R_IA_64_DTPREL64I 0xb3 /* imm64 @dtprel(S + A) */ -#define R_IA_64_DTPREL32MSB 0xb4 /* word32 MSB @dtprel(S + A) */ -#define R_IA_64_DTPREL32LSB 0xb5 /* word32 LSB @dtprel(S + A) */ -#define R_IA_64_DTPREL64MSB 0xb6 /* word64 MSB @dtprel(S + A) */ -#define R_IA_64_DTPREL64LSB 0xb7 /* word64 LSB @dtprel(S + A) */ -#define R_IA_64_LTOFF_DTPREL22 0xba /* imm22 @ltoff(@dtprel(S+A)) */ - -#define R_PPC_NONE 0 /* No relocation. */ -#define R_PPC_ADDR32 1 -#define R_PPC_ADDR24 2 -#define R_PPC_ADDR16 3 -#define R_PPC_ADDR16_LO 4 -#define R_PPC_ADDR16_HI 5 -#define R_PPC_ADDR16_HA 6 -#define R_PPC_ADDR14 7 -#define R_PPC_ADDR14_BRTAKEN 8 -#define R_PPC_ADDR14_BRNTAKEN 9 -#define R_PPC_REL24 10 -#define R_PPC_REL14 11 -#define R_PPC_REL14_BRTAKEN 12 -#define R_PPC_REL14_BRNTAKEN 13 -#define R_PPC_GOT16 14 -#define R_PPC_GOT16_LO 15 -#define R_PPC_GOT16_HI 16 -#define R_PPC_GOT16_HA 17 -#define R_PPC_PLTREL24 18 -#define R_PPC_COPY 19 -#define R_PPC_GLOB_DAT 20 -#define R_PPC_JMP_SLOT 21 -#define R_PPC_RELATIVE 22 -#define R_PPC_LOCAL24PC 23 -#define R_PPC_UADDR32 24 -#define R_PPC_UADDR16 25 -#define R_PPC_REL32 26 -#define R_PPC_PLT32 27 -#define R_PPC_PLTREL32 28 -#define R_PPC_PLT16_LO 29 -#define R_PPC_PLT16_HI 30 -#define R_PPC_PLT16_HA 31 -#define R_PPC_SDAREL16 32 -#define R_PPC_SECTOFF 33 -#define R_PPC_SECTOFF_LO 34 -#define R_PPC_SECTOFF_HI 35 -#define R_PPC_SECTOFF_HA 36 - -/* - * TLS relocations - */ -#define R_PPC_TLS 67 -#define R_PPC_DTPMOD32 68 -#define R_PPC_TPREL16 69 -#define R_PPC_TPREL16_LO 70 -#define R_PPC_TPREL16_HI 71 -#define R_PPC_TPREL16_HA 72 -#define R_PPC_TPREL32 73 -#define R_PPC_DTPREL16 74 -#define R_PPC_DTPREL16_LO 75 -#define R_PPC_DTPREL16_HI 76 -#define R_PPC_DTPREL16_HA 77 -#define R_PPC_DTPREL32 78 -#define R_PPC_GOT_TLSGD16 79 -#define R_PPC_GOT_TLSGD16_LO 80 -#define R_PPC_GOT_TLSGD16_HI 81 -#define R_PPC_GOT_TLSGD16_HA 82 -#define R_PPC_GOT_TLSLD16 83 -#define R_PPC_GOT_TLSLD16_LO 84 -#define R_PPC_GOT_TLSLD16_HI 85 -#define R_PPC_GOT_TLSLD16_HA 86 -#define R_PPC_GOT_TPREL16 87 -#define R_PPC_GOT_TPREL16_LO 88 -#define R_PPC_GOT_TPREL16_HI 89 -#define R_PPC_GOT_TPREL16_HA 90 - -/* - * The remaining relocs are from the Embedded ELF ABI, and are not in the - * SVR4 ELF ABI. - */ - -#define R_PPC_EMB_NADDR32 101 -#define R_PPC_EMB_NADDR16 102 -#define R_PPC_EMB_NADDR16_LO 103 -#define R_PPC_EMB_NADDR16_HI 104 -#define R_PPC_EMB_NADDR16_HA 105 -#define R_PPC_EMB_SDAI16 106 -#define R_PPC_EMB_SDA2I16 107 -#define R_PPC_EMB_SDA2REL 108 -#define R_PPC_EMB_SDA21 109 -#define R_PPC_EMB_MRKREF 110 -#define R_PPC_EMB_RELSEC16 111 -#define R_PPC_EMB_RELST_LO 112 -#define R_PPC_EMB_RELST_HI 113 -#define R_PPC_EMB_RELST_HA 114 -#define R_PPC_EMB_BIT_FLD 115 -#define R_PPC_EMB_RELSDA 116 - -#define R_SPARC_NONE 0 -#define R_SPARC_8 1 -#define R_SPARC_16 2 -#define R_SPARC_32 3 -#define R_SPARC_DISP8 4 -#define R_SPARC_DISP16 5 -#define R_SPARC_DISP32 6 -#define R_SPARC_WDISP30 7 -#define R_SPARC_WDISP22 8 -#define R_SPARC_HI22 9 -#define R_SPARC_22 10 -#define R_SPARC_13 11 -#define R_SPARC_LO10 12 -#define R_SPARC_GOT10 13 -#define R_SPARC_GOT13 14 -#define R_SPARC_GOT22 15 -#define R_SPARC_PC10 16 -#define R_SPARC_PC22 17 -#define R_SPARC_WPLT30 18 -#define R_SPARC_COPY 19 -#define R_SPARC_GLOB_DAT 20 -#define R_SPARC_JMP_SLOT 21 -#define R_SPARC_RELATIVE 22 -#define R_SPARC_UA32 23 -#define R_SPARC_PLT32 24 -#define R_SPARC_HIPLT22 25 -#define R_SPARC_LOPLT10 26 -#define R_SPARC_PCPLT32 27 -#define R_SPARC_PCPLT22 28 -#define R_SPARC_PCPLT10 29 -#define R_SPARC_10 30 -#define R_SPARC_11 31 -#define R_SPARC_64 32 -#define R_SPARC_OLO10 33 -#define R_SPARC_HH22 34 -#define R_SPARC_HM10 35 -#define R_SPARC_LM22 36 -#define R_SPARC_PC_HH22 37 -#define R_SPARC_PC_HM10 38 -#define R_SPARC_PC_LM22 39 -#define R_SPARC_WDISP16 40 -#define R_SPARC_WDISP19 41 -#define R_SPARC_GLOB_JMP 42 -#define R_SPARC_7 43 -#define R_SPARC_5 44 -#define R_SPARC_6 45 -#define R_SPARC_DISP64 46 -#define R_SPARC_PLT64 47 -#define R_SPARC_HIX22 48 -#define R_SPARC_LOX10 49 -#define R_SPARC_H44 50 -#define R_SPARC_M44 51 -#define R_SPARC_L44 52 -#define R_SPARC_REGISTER 53 -#define R_SPARC_UA64 54 -#define R_SPARC_UA16 55 -#define R_SPARC_TLS_GD_HI22 56 -#define R_SPARC_TLS_GD_LO10 57 -#define R_SPARC_TLS_GD_ADD 58 -#define R_SPARC_TLS_GD_CALL 59 -#define R_SPARC_TLS_LDM_HI22 60 -#define R_SPARC_TLS_LDM_LO10 61 -#define R_SPARC_TLS_LDM_ADD 62 -#define R_SPARC_TLS_LDM_CALL 63 -#define R_SPARC_TLS_LDO_HIX22 64 -#define R_SPARC_TLS_LDO_LOX10 65 -#define R_SPARC_TLS_LDO_ADD 66 -#define R_SPARC_TLS_IE_HI22 67 -#define R_SPARC_TLS_IE_LO10 68 -#define R_SPARC_TLS_IE_LD 69 -#define R_SPARC_TLS_IE_LDX 70 -#define R_SPARC_TLS_IE_ADD 71 -#define R_SPARC_TLS_LE_HIX22 72 -#define R_SPARC_TLS_LE_LOX10 73 -#define R_SPARC_TLS_DTPMOD32 74 -#define R_SPARC_TLS_DTPMOD64 75 -#define R_SPARC_TLS_DTPOFF32 76 -#define R_SPARC_TLS_DTPOFF64 77 -#define R_SPARC_TLS_TPOFF32 78 -#define R_SPARC_TLS_TPOFF64 79 - -#define R_X86_64_NONE 0 /* No relocation. */ -#define R_X86_64_64 1 /* Add 64 bit symbol value. */ -#define R_X86_64_PC32 2 /* PC-relative 32 bit signed sym value. */ -#define R_X86_64_GOT32 3 /* PC-relative 32 bit GOT offset. */ -#define R_X86_64_PLT32 4 /* PC-relative 32 bit PLT offset. */ -#define R_X86_64_COPY 5 /* Copy data from shared object. */ -#define R_X86_64_GLOB_DAT 6 /* Set GOT entry to data address. */ -#define R_X86_64_JMP_SLOT 7 /* Set GOT entry to code address. */ -#define R_X86_64_RELATIVE 8 /* Add load address of shared object. */ -#define R_X86_64_GOTPCREL 9 /* Add 32 bit signed pcrel offset to GOT. */ -#define R_X86_64_32 10 /* Add 32 bit zero extended symbol value */ -#define R_X86_64_32S 11 /* Add 32 bit sign extended symbol value */ -#define R_X86_64_16 12 /* Add 16 bit zero extended symbol value */ -#define R_X86_64_PC16 13 /* Add 16 bit signed extended pc relative symbol value */ -#define R_X86_64_8 14 /* Add 8 bit zero extended symbol value */ -#define R_X86_64_PC8 15 /* Add 8 bit signed extended pc relative symbol value */ -#define R_X86_64_DTPMOD64 16 /* ID of module containing symbol */ -#define R_X86_64_DTPOFF64 17 /* Offset in TLS block */ -#define R_X86_64_TPOFF64 18 /* Offset in static TLS block */ -#define R_X86_64_TLSGD 19 /* PC relative offset to GD GOT entry */ -#define R_X86_64_TLSLD 20 /* PC relative offset to LD GOT entry */ -#define R_X86_64_DTPOFF32 21 /* Offset in TLS block */ -#define R_X86_64_GOTTPOFF 22 /* PC relative offset to IE GOT entry */ -#define R_X86_64_TPOFF32 23 /* Offset in static TLS block */ - - -#endif /* !_SYS_ELF_COMMON_H_ */ +#define R_ARM_LDC_PC_G2 69 +#define R_ARM_GOT_PREL 96 +#define R_ARM_THM_JUMP11 102 +#define R_ARM_THM_JUMP8 103 +#define R_ARM_TLS_GD32 104 +#define R_ARM_TLS_LDM32 105 +#define R_ARM_TLS_IE32 107 + +#define R_ARM_THM_JUMP19 51 +#define R_ARM_GNU_VTENTRY 100 +#define R_ARM_GNU_VTINHERIT 101 +#define R_ARM_RSBREL32 250 +#define R_ARM_THM_RPC22 251 +#define R_ARM_RREL32 252 +#define R_ARM_RABS32 253 +#define R_ARM_RPC24 254 +#define R_ARM_RBASE 255 + + + +/* Name Value Field Calculation */ +#define R_IA_64_NONE 0 /* None */ +#define R_IA_64_IMM14 0x21 /* immediate14 S + A */ +#define R_IA_64_IMM22 0x22 /* immediate22 S + A */ +#define R_IA_64_IMM64 0x23 /* immediate64 S + A */ +#define R_IA_64_DIR32MSB 0x24 /* word32 MSB S + A */ +#define R_IA_64_DIR32LSB 0x25 /* word32 LSB S + A */ +#define R_IA_64_DIR64MSB 0x26 /* word64 MSB S + A */ +#define R_IA_64_DIR64LSB 0x27 /* word64 LSB S + A */ +#define R_IA_64_GPREL22 0x2a /* immediate22 @gprel(S + A) */ +#define R_IA_64_GPREL64I 0x2b /* immediate64 @gprel(S + A) */ +#define R_IA_64_GPREL32MSB 0x2c /* word32 MSB @gprel(S + A) */ +#define R_IA_64_GPREL32LSB 0x2d /* word32 LSB @gprel(S + A) */ +#define R_IA_64_GPREL64MSB 0x2e /* word64 MSB @gprel(S + A) */ +#define R_IA_64_GPREL64LSB 0x2f /* word64 LSB @gprel(S + A) */ +#define R_IA_64_LTOFF22 0x32 /* immediate22 @ltoff(S + A) */ +#define R_IA_64_LTOFF64I 0x33 /* immediate64 @ltoff(S + A) */ +#define R_IA_64_PLTOFF22 0x3a /* immediate22 @pltoff(S + A) */ +#define R_IA_64_PLTOFF64I 0x3b /* immediate64 @pltoff(S + A) */ +#define R_IA_64_PLTOFF64MSB 0x3e /* word64 MSB @pltoff(S + A) */ +#define R_IA_64_PLTOFF64LSB 0x3f /* word64 LSB @pltoff(S + A) */ +#define R_IA_64_FPTR64I 0x43 /* immediate64 @fptr(S + A) */ +#define R_IA_64_FPTR32MSB 0x44 /* word32 MSB @fptr(S + A) */ +#define R_IA_64_FPTR32LSB 0x45 /* word32 LSB @fptr(S + A) */ +#define R_IA_64_FPTR64MSB 0x46 /* word64 MSB @fptr(S + A) */ +#define R_IA_64_FPTR64LSB 0x47 /* word64 LSB @fptr(S + A) */ +#define R_IA_64_PCREL60B 0x48 /* immediate60 form1 S + A - P */ +#define R_IA_64_PCREL21B 0x49 /* immediate21 form1 S + A - P */ +#define R_IA_64_PCREL21M 0x4a /* immediate21 form2 S + A - P */ +#define R_IA_64_PCREL21F 0x4b /* immediate21 form3 S + A - P */ +#define R_IA_64_PCREL32MSB 0x4c /* word32 MSB S + A - P */ +#define R_IA_64_PCREL32LSB 0x4d /* word32 LSB S + A - P */ +#define R_IA_64_PCREL64MSB 0x4e /* word64 MSB S + A - P */ +#define R_IA_64_PCREL64LSB 0x4f /* word64 LSB S + A - P */ +#define R_IA_64_LTOFF_FPTR22 0x52 /* immediate22 @ltoff(@fptr(S + A)) */ +#define R_IA_64_LTOFF_FPTR64I 0x53 /* immediate64 @ltoff(@fptr(S + A)) */ +#define R_IA_64_LTOFF_FPTR32MSB 0x54 /* word32 MSB @ltoff(@fptr(S + A)) */ +#define R_IA_64_LTOFF_FPTR32LSB 0x55 /* word32 LSB @ltoff(@fptr(S + A)) */ +#define R_IA_64_LTOFF_FPTR64MSB 0x56 /* word64 MSB @ltoff(@fptr(S + A)) */ +#define R_IA_64_LTOFF_FPTR64LSB 0x57 /* word64 LSB @ltoff(@fptr(S + A)) */ +#define R_IA_64_SEGREL32MSB 0x5c /* word32 MSB @segrel(S + A) */ +#define R_IA_64_SEGREL32LSB 0x5d /* word32 LSB @segrel(S + A) */ +#define R_IA_64_SEGREL64MSB 0x5e /* word64 MSB @segrel(S + A) */ +#define R_IA_64_SEGREL64LSB 0x5f /* word64 LSB @segrel(S + A) */ +#define R_IA_64_SECREL32MSB 0x64 /* word32 MSB @secrel(S + A) */ +#define R_IA_64_SECREL32LSB 0x65 /* word32 LSB @secrel(S + A) */ +#define R_IA_64_SECREL64MSB 0x66 /* word64 MSB @secrel(S + A) */ +#define R_IA_64_SECREL64LSB 0x67 /* word64 LSB @secrel(S + A) */ +#define R_IA_64_REL32MSB 0x6c /* word32 MSB BD + A */ +#define R_IA_64_REL32LSB 0x6d /* word32 LSB BD + A */ +#define R_IA_64_REL64MSB 0x6e /* word64 MSB BD + A */ +#define R_IA_64_REL64LSB 0x6f /* word64 LSB BD + A */ +#define R_IA_64_LTV32MSB 0x74 /* word32 MSB S + A */ +#define R_IA_64_LTV32LSB 0x75 /* word32 LSB S + A */ +#define R_IA_64_LTV64MSB 0x76 /* word64 MSB S + A */ +#define R_IA_64_LTV64LSB 0x77 /* word64 LSB S + A */ +#define R_IA_64_PCREL21BI 0x79 /* immediate21 form1 S + A - P */ +#define R_IA_64_PCREL22 0x7a /* immediate22 S + A - P */ +#define R_IA_64_PCREL64I 0x7b /* immediate64 S + A - P */ +#define R_IA_64_IPLTMSB 0x80 /* function descriptor MSB special */ +#define R_IA_64_IPLTLSB 0x81 /* function descriptor LSB speciaal */ +#define R_IA_64_SUB 0x85 /* immediate64 A - S */ +#define R_IA_64_LTOFF22X 0x86 /* immediate22 special */ +#define R_IA_64_LDXMOV 0x87 /* immediate22 special */ +#define R_IA_64_TPREL14 0x91 /* imm14 @tprel(S + A) */ +#define R_IA_64_TPREL22 0x92 /* imm22 @tprel(S + A) */ +#define R_IA_64_TPREL64I 0x93 /* imm64 @tprel(S + A) */ +#define R_IA_64_TPREL64MSB 0x96 /* word64 MSB @tprel(S + A) */ +#define R_IA_64_TPREL64LSB 0x97 /* word64 LSB @tprel(S + A) */ +#define R_IA_64_LTOFF_TPREL22 0x9a /* imm22 @ltoff(@tprel(S+A)) */ +#define R_IA_64_DTPMOD64MSB 0xa6 /* word64 MSB @dtpmod(S + A) */ +#define R_IA_64_DTPMOD64LSB 0xa7 /* word64 LSB @dtpmod(S + A) */ +#define R_IA_64_LTOFF_DTPMOD22 0xaa /* imm22 @ltoff(@dtpmod(S+A)) */ +#define R_IA_64_DTPREL14 0xb1 /* imm14 @dtprel(S + A) */ +#define R_IA_64_DTPREL22 0xb2 /* imm22 @dtprel(S + A) */ +#define R_IA_64_DTPREL64I 0xb3 /* imm64 @dtprel(S + A) */ +#define R_IA_64_DTPREL32MSB 0xb4 /* word32 MSB @dtprel(S + A) */ +#define R_IA_64_DTPREL32LSB 0xb5 /* word32 LSB @dtprel(S + A) */ +#define R_IA_64_DTPREL64MSB 0xb6 /* word64 MSB @dtprel(S + A) */ +#define R_IA_64_DTPREL64LSB 0xb7 /* word64 LSB @dtprel(S + A) */ +#define R_IA_64_LTOFF_DTPREL22 0xba /* imm22 @ltoff(@dtprel(S+A)) */ + +#define R_PPC_NONE 0 /* No relocation. */ +#define R_PPC_ADDR32 1 +#define R_PPC_ADDR24 2 +#define R_PPC_ADDR16 3 +#define R_PPC_ADDR16_LO 4 +#define R_PPC_ADDR16_HI 5 +#define R_PPC_ADDR16_HA 6 +#define R_PPC_ADDR14 7 +#define R_PPC_ADDR14_BRTAKEN 8 +#define R_PPC_ADDR14_BRNTAKEN 9 +#define R_PPC_REL24 10 +#define R_PPC_REL14 11 +#define R_PPC_REL14_BRTAKEN 12 +#define R_PPC_REL14_BRNTAKEN 13 +#define R_PPC_GOT16 14 +#define R_PPC_GOT16_LO 15 +#define R_PPC_GOT16_HI 16 +#define R_PPC_GOT16_HA 17 +#define R_PPC_PLTREL24 18 +#define R_PPC_COPY 19 +#define R_PPC_GLOB_DAT 20 +#define R_PPC_JMP_SLOT 21 +#define R_PPC_RELATIVE 22 +#define R_PPC_LOCAL24PC 23 +#define R_PPC_UADDR32 24 +#define R_PPC_UADDR16 25 +#define R_PPC_REL32 26 +#define R_PPC_PLT32 27 +#define R_PPC_PLTREL32 28 +#define R_PPC_PLT16_LO 29 +#define R_PPC_PLT16_HI 30 +#define R_PPC_PLT16_HA 31 +#define R_PPC_SDAREL16 32 +#define R_PPC_SECTOFF 33 +#define R_PPC_SECTOFF_LO 34 +#define R_PPC_SECTOFF_HI 35 +#define R_PPC_SECTOFF_HA 36 + +/* + * TLS relocations + */ +#define R_PPC_TLS 67 +#define R_PPC_DTPMOD32 68 +#define R_PPC_TPREL16 69 +#define R_PPC_TPREL16_LO 70 +#define R_PPC_TPREL16_HI 71 +#define R_PPC_TPREL16_HA 72 +#define R_PPC_TPREL32 73 +#define R_PPC_DTPREL16 74 +#define R_PPC_DTPREL16_LO 75 +#define R_PPC_DTPREL16_HI 76 +#define R_PPC_DTPREL16_HA 77 +#define R_PPC_DTPREL32 78 +#define R_PPC_GOT_TLSGD16 79 +#define R_PPC_GOT_TLSGD16_LO 80 +#define R_PPC_GOT_TLSGD16_HI 81 +#define R_PPC_GOT_TLSGD16_HA 82 +#define R_PPC_GOT_TLSLD16 83 +#define R_PPC_GOT_TLSLD16_LO 84 +#define R_PPC_GOT_TLSLD16_HI 85 +#define R_PPC_GOT_TLSLD16_HA 86 +#define R_PPC_GOT_TPREL16 87 +#define R_PPC_GOT_TPREL16_LO 88 +#define R_PPC_GOT_TPREL16_HI 89 +#define R_PPC_GOT_TPREL16_HA 90 + +/* + * The remaining relocs are from the Embedded ELF ABI, and are not in the + * SVR4 ELF ABI. + */ + +#define R_PPC_EMB_NADDR32 101 +#define R_PPC_EMB_NADDR16 102 +#define R_PPC_EMB_NADDR16_LO 103 +#define R_PPC_EMB_NADDR16_HI 104 +#define R_PPC_EMB_NADDR16_HA 105 +#define R_PPC_EMB_SDAI16 106 +#define R_PPC_EMB_SDA2I16 107 +#define R_PPC_EMB_SDA2REL 108 +#define R_PPC_EMB_SDA21 109 +#define R_PPC_EMB_MRKREF 110 +#define R_PPC_EMB_RELSEC16 111 +#define R_PPC_EMB_RELST_LO 112 +#define R_PPC_EMB_RELST_HI 113 +#define R_PPC_EMB_RELST_HA 114 +#define R_PPC_EMB_BIT_FLD 115 +#define R_PPC_EMB_RELSDA 116 + +#define R_SPARC_NONE 0 +#define R_SPARC_8 1 +#define R_SPARC_16 2 +#define R_SPARC_32 3 +#define R_SPARC_DISP8 4 +#define R_SPARC_DISP16 5 +#define R_SPARC_DISP32 6 +#define R_SPARC_WDISP30 7 +#define R_SPARC_WDISP22 8 +#define R_SPARC_HI22 9 +#define R_SPARC_22 10 +#define R_SPARC_13 11 +#define R_SPARC_LO10 12 +#define R_SPARC_GOT10 13 +#define R_SPARC_GOT13 14 +#define R_SPARC_GOT22 15 +#define R_SPARC_PC10 16 +#define R_SPARC_PC22 17 +#define R_SPARC_WPLT30 18 +#define R_SPARC_COPY 19 +#define R_SPARC_GLOB_DAT 20 +#define R_SPARC_JMP_SLOT 21 +#define R_SPARC_RELATIVE 22 +#define R_SPARC_UA32 23 +#define R_SPARC_PLT32 24 +#define R_SPARC_HIPLT22 25 +#define R_SPARC_LOPLT10 26 +#define R_SPARC_PCPLT32 27 +#define R_SPARC_PCPLT22 28 +#define R_SPARC_PCPLT10 29 +#define R_SPARC_10 30 +#define R_SPARC_11 31 +#define R_SPARC_64 32 +#define R_SPARC_OLO10 33 +#define R_SPARC_HH22 34 +#define R_SPARC_HM10 35 +#define R_SPARC_LM22 36 +#define R_SPARC_PC_HH22 37 +#define R_SPARC_PC_HM10 38 +#define R_SPARC_PC_LM22 39 +#define R_SPARC_WDISP16 40 +#define R_SPARC_WDISP19 41 +#define R_SPARC_GLOB_JMP 42 +#define R_SPARC_7 43 +#define R_SPARC_5 44 +#define R_SPARC_6 45 +#define R_SPARC_DISP64 46 +#define R_SPARC_PLT64 47 +#define R_SPARC_HIX22 48 +#define R_SPARC_LOX10 49 +#define R_SPARC_H44 50 +#define R_SPARC_M44 51 +#define R_SPARC_L44 52 +#define R_SPARC_REGISTER 53 +#define R_SPARC_UA64 54 +#define R_SPARC_UA16 55 +#define R_SPARC_TLS_GD_HI22 56 +#define R_SPARC_TLS_GD_LO10 57 +#define R_SPARC_TLS_GD_ADD 58 +#define R_SPARC_TLS_GD_CALL 59 +#define R_SPARC_TLS_LDM_HI22 60 +#define R_SPARC_TLS_LDM_LO10 61 +#define R_SPARC_TLS_LDM_ADD 62 +#define R_SPARC_TLS_LDM_CALL 63 +#define R_SPARC_TLS_LDO_HIX22 64 +#define R_SPARC_TLS_LDO_LOX10 65 +#define R_SPARC_TLS_LDO_ADD 66 +#define R_SPARC_TLS_IE_HI22 67 +#define R_SPARC_TLS_IE_LO10 68 +#define R_SPARC_TLS_IE_LD 69 +#define R_SPARC_TLS_IE_LDX 70 +#define R_SPARC_TLS_IE_ADD 71 +#define R_SPARC_TLS_LE_HIX22 72 +#define R_SPARC_TLS_LE_LOX10 73 +#define R_SPARC_TLS_DTPMOD32 74 +#define R_SPARC_TLS_DTPMOD64 75 +#define R_SPARC_TLS_DTPOFF32 76 +#define R_SPARC_TLS_DTPOFF64 77 +#define R_SPARC_TLS_TPOFF32 78 +#define R_SPARC_TLS_TPOFF64 79 + +#define R_X86_64_NONE 0 /* No relocation. */ +#define R_X86_64_64 1 /* Add 64 bit symbol value. */ +#define R_X86_64_PC32 2 /* PC-relative 32 bit signed sym value. */ +#define R_X86_64_GOT32 3 /* PC-relative 32 bit GOT offset. */ +#define R_X86_64_PLT32 4 /* PC-relative 32 bit PLT offset. */ +#define R_X86_64_COPY 5 /* Copy data from shared object. */ +#define R_X86_64_GLOB_DAT 6 /* Set GOT entry to data address. */ +#define R_X86_64_JMP_SLOT 7 /* Set GOT entry to code address. */ +#define R_X86_64_RELATIVE 8 /* Add load address of shared object. */ +#define R_X86_64_GOTPCREL 9 /* Add 32 bit signed pcrel offset to GOT. */ +#define R_X86_64_32 10 /* Add 32 bit zero extended symbol value */ +#define R_X86_64_32S 11 /* Add 32 bit sign extended symbol value */ +#define R_X86_64_16 12 /* Add 16 bit zero extended symbol value */ +#define R_X86_64_PC16 13 /* Add 16 bit signed extended pc relative symbol value */ +#define R_X86_64_8 14 /* Add 8 bit zero extended symbol value */ +#define R_X86_64_PC8 15 /* Add 8 bit signed extended pc relative symbol value */ +#define R_X86_64_DTPMOD64 16 /* ID of module containing symbol */ +#define R_X86_64_DTPOFF64 17 /* Offset in TLS block */ +#define R_X86_64_TPOFF64 18 /* Offset in static TLS block */ +#define R_X86_64_TLSGD 19 /* PC relative offset to GD GOT entry */ +#define R_X86_64_TLSLD 20 /* PC relative offset to LD GOT entry */ +#define R_X86_64_DTPOFF32 21 /* Offset in TLS block */ +#define R_X86_64_GOTTPOFF 22 /* PC relative offset to IE GOT entry */ +#define R_X86_64_TPOFF32 23 /* Offset in static TLS block */ + + +#endif /* !_SYS_ELF_COMMON_H_ */ diff --git a/BaseTools/Source/C/Include/Arm/ProcessorBind.h b/BaseTools/Source/C/Include/Arm/ProcessorBind.h index 1ca26ab6f3..d84f16e7ba 100644 --- a/BaseTools/Source/C/Include/Arm/ProcessorBind.h +++ b/BaseTools/Source/C/Include/Arm/ProcessorBind.h @@ -1,158 +1,158 @@ -/** @file - Processor or Compiler specific defines and types for ARM. - - Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.
- Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef __PROCESSOR_BIND_H__ -#define __PROCESSOR_BIND_H__ - -/// -/// Define the processor type so other code can make processor based choices -/// -#define MDE_CPU_ARM - -// -// Make sure we are using the correct packing rules per EFI specification -// -#ifndef __GNUC__ -#pragma pack() -#endif - -#if _MSC_EXTENSIONS - // - // use Microsoft* C complier dependent integer width types - // - typedef unsigned __int64 UINT64; - typedef __int64 INT64; - typedef unsigned __int32 UINT32; - typedef __int32 INT32; - typedef unsigned short UINT16; - typedef unsigned short CHAR16; - typedef short INT16; - typedef unsigned char BOOLEAN; - typedef unsigned char UINT8; - typedef char CHAR8; - typedef signed char INT8; -#else - // - // Assume standard ARM alignment. - // - typedef unsigned long long UINT64; - typedef long long INT64; - typedef unsigned int UINT32; - typedef int INT32; - typedef unsigned short UINT16; - typedef unsigned short CHAR16; - typedef short INT16; - typedef unsigned char BOOLEAN; - typedef unsigned char UINT8; - typedef char CHAR8; - typedef signed char INT8; - - #define UINT8_MAX 0xff -#endif - -/// -/// Unsigned value of native width. (4 bytes on supported 32-bit processor instructions, -/// 8 bytes on supported 64-bit processor instructions) -/// -typedef UINT32 UINTN; - -/// -/// Signed value of native width. (4 bytes on supported 32-bit processor instructions, -/// 8 bytes on supported 64-bit processor instructions) -/// -typedef INT32 INTN; - -// -// Processor specific defines -// - -/// -/// A value of native width with the highest bit set. -/// -#define MAX_BIT 0x80000000 - -/// -/// A value of native width with the two highest bits set. -/// -#define MAX_2_BITS 0xC0000000 - -/// -/// Maximum legal ARM address -/// -#define MAX_ADDRESS 0xFFFFFFFF - -/// -/// The stack alignment required for ARM -/// -#define CPU_STACK_ALIGNMENT sizeof(UINT64) - -// -// Modifier to ensure that all protocol member functions and EFI intrinsics -// use the correct C calling convention. All protocol member functions and -// EFI intrinsics are required to modify their member functions with EFIAPI. -// -#define EFIAPI - -#if defined(__GNUC__) - /// - /// For GNU assembly code, .global or .globl can declare global symbols. - /// Define this macro to unify the usage. - /// - #define ASM_GLOBAL .globl - - #if !defined(__APPLE__) - /// - /// ARM EABI defines that the linker should not manipulate call relocations - /// (do bl/blx conversion) unless the target symbol has function type. - /// CodeSourcery 2010.09 started requiring the .type to function properly - /// - #define INTERWORK_FUNC(func__) .type ASM_PFX(func__), %function - - #define GCC_ASM_EXPORT(func__) \ - .global _CONCATENATE (__USER_LABEL_PREFIX__, func__) ;\ - .type ASM_PFX(func__), %function - - #define GCC_ASM_IMPORT(func__) \ - .extern _CONCATENATE (__USER_LABEL_PREFIX__, func__) - - #else - // - // .type not supported by Apple Xcode tools - // - #define INTERWORK_FUNC(func__) - - #define GCC_ASM_EXPORT(func__) \ - .globl _CONCATENATE (__USER_LABEL_PREFIX__, func__) \ - - #define GCC_ASM_IMPORT(name) - - #endif -#endif - -/** - Return the pointer to the first instruction of a function given a function pointer. - On ARM CPU architectures, these two pointer values are the same, - so the implementation of this macro is very simple. - - @param FunctionPointer A pointer to a function. - - @return The pointer to the first instruction of a function given a function pointer. - -**/ -#define FUNCTION_ENTRY_POINT(FunctionPointer) (VOID *)(UINTN)(FunctionPointer) - -#endif - - +/** @file + Processor or Compiler specific defines and types for ARM. + + Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.
+ Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef __PROCESSOR_BIND_H__ +#define __PROCESSOR_BIND_H__ + +/// +/// Define the processor type so other code can make processor based choices +/// +#define MDE_CPU_ARM + +// +// Make sure we are using the correct packing rules per EFI specification +// +#ifndef __GNUC__ +#pragma pack() +#endif + +#if _MSC_EXTENSIONS + // + // use Microsoft* C complier dependent integer width types + // + typedef unsigned __int64 UINT64; + typedef __int64 INT64; + typedef unsigned __int32 UINT32; + typedef __int32 INT32; + typedef unsigned short UINT16; + typedef unsigned short CHAR16; + typedef short INT16; + typedef unsigned char BOOLEAN; + typedef unsigned char UINT8; + typedef char CHAR8; + typedef signed char INT8; +#else + // + // Assume standard ARM alignment. + // + typedef unsigned long long UINT64; + typedef long long INT64; + typedef unsigned int UINT32; + typedef int INT32; + typedef unsigned short UINT16; + typedef unsigned short CHAR16; + typedef short INT16; + typedef unsigned char BOOLEAN; + typedef unsigned char UINT8; + typedef char CHAR8; + typedef signed char INT8; + + #define UINT8_MAX 0xff +#endif + +/// +/// Unsigned value of native width. (4 bytes on supported 32-bit processor instructions, +/// 8 bytes on supported 64-bit processor instructions) +/// +typedef UINT32 UINTN; + +/// +/// Signed value of native width. (4 bytes on supported 32-bit processor instructions, +/// 8 bytes on supported 64-bit processor instructions) +/// +typedef INT32 INTN; + +// +// Processor specific defines +// + +/// +/// A value of native width with the highest bit set. +/// +#define MAX_BIT 0x80000000 + +/// +/// A value of native width with the two highest bits set. +/// +#define MAX_2_BITS 0xC0000000 + +/// +/// Maximum legal ARM address +/// +#define MAX_ADDRESS 0xFFFFFFFF + +/// +/// The stack alignment required for ARM +/// +#define CPU_STACK_ALIGNMENT sizeof(UINT64) + +// +// Modifier to ensure that all protocol member functions and EFI intrinsics +// use the correct C calling convention. All protocol member functions and +// EFI intrinsics are required to modify their member functions with EFIAPI. +// +#define EFIAPI + +#if defined(__GNUC__) + /// + /// For GNU assembly code, .global or .globl can declare global symbols. + /// Define this macro to unify the usage. + /// + #define ASM_GLOBAL .globl + + #if !defined(__APPLE__) + /// + /// ARM EABI defines that the linker should not manipulate call relocations + /// (do bl/blx conversion) unless the target symbol has function type. + /// CodeSourcery 2010.09 started requiring the .type to function properly + /// + #define INTERWORK_FUNC(func__) .type ASM_PFX(func__), %function + + #define GCC_ASM_EXPORT(func__) \ + .global _CONCATENATE (__USER_LABEL_PREFIX__, func__) ;\ + .type ASM_PFX(func__), %function + + #define GCC_ASM_IMPORT(func__) \ + .extern _CONCATENATE (__USER_LABEL_PREFIX__, func__) + + #else + // + // .type not supported by Apple Xcode tools + // + #define INTERWORK_FUNC(func__) + + #define GCC_ASM_EXPORT(func__) \ + .globl _CONCATENATE (__USER_LABEL_PREFIX__, func__) \ + + #define GCC_ASM_IMPORT(name) + + #endif +#endif + +/** + Return the pointer to the first instruction of a function given a function pointer. + On ARM CPU architectures, these two pointer values are the same, + so the implementation of this macro is very simple. + + @param FunctionPointer A pointer to a function. + + @return The pointer to the first instruction of a function given a function pointer. + +**/ +#define FUNCTION_ENTRY_POINT(FunctionPointer) (VOID *)(UINTN)(FunctionPointer) + +#endif + + diff --git a/BaseTools/Source/C/Include/Common/BuildVersion.h b/BaseTools/Source/C/Include/Common/BuildVersion.h index dd9852bad3..d3ad7c265b 100644 --- a/BaseTools/Source/C/Include/Common/BuildVersion.h +++ b/BaseTools/Source/C/Include/Common/BuildVersion.h @@ -14,4 +14,4 @@ **/ -#define __BUILD_VERSION "Build 2640" +#define __BUILD_VERSION "Build 2649" diff --git a/BaseTools/Source/C/Makefiles/NmakeSubdirs.bat b/BaseTools/Source/C/Makefiles/NmakeSubdirs.bat index 25b8790ac5..fac89bd9ee 100644 --- a/BaseTools/Source/C/Makefiles/NmakeSubdirs.bat +++ b/BaseTools/Source/C/Makefiles/NmakeSubdirs.bat @@ -7,7 +7,7 @@ @REM # http://opensource.org/licenses/bsd-license.php @REM # @REM # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -@REM # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +@REM # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. @echo off diff --git a/BaseTools/Source/C/Makefiles/app.makefile b/BaseTools/Source/C/Makefiles/app.makefile index ed2e2fba08..19269a13a9 100644 --- a/BaseTools/Source/C/Makefiles/app.makefile +++ b/BaseTools/Source/C/Makefiles/app.makefile @@ -1,27 +1,27 @@ -## @file -# -# Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.
-# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# - -MAKEROOT ?= ../.. - -include $(MAKEROOT)/Makefiles/header.makefile - -APPLICATION = $(MAKEROOT)/bin/$(APPNAME) - -.PHONY:all -all: $(MAKEROOT)/bin $(APPLICATION) - -$(APPLICATION): $(OBJECTS) - $(LINKER) -o $(APPLICATION) $(LFLAGS) $(OBJECTS) -L$(MAKEROOT)/libs $(LIBS) - -$(OBJECTS): ../Include/Common/BuildVersion.h - -include $(MAKEROOT)/Makefiles/footer.makefile +## @file +# +# Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.
+# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# + +MAKEROOT ?= ../.. + +include $(MAKEROOT)/Makefiles/header.makefile + +APPLICATION = $(MAKEROOT)/bin/$(APPNAME) + +.PHONY:all +all: $(MAKEROOT)/bin $(APPLICATION) + +$(APPLICATION): $(OBJECTS) + $(LINKER) -o $(APPLICATION) $(LFLAGS) $(OBJECTS) -L$(MAKEROOT)/libs $(LIBS) + +$(OBJECTS): ../Include/Common/BuildVersion.h + +include $(MAKEROOT)/Makefiles/footer.makefile diff --git a/BaseTools/Source/C/Makefiles/footer.makefile b/BaseTools/Source/C/Makefiles/footer.makefile index de7114257d..c10ad7aab4 100644 --- a/BaseTools/Source/C/Makefiles/footer.makefile +++ b/BaseTools/Source/C/Makefiles/footer.makefile @@ -7,28 +7,28 @@ # http://opensource.org/licenses/bsd-license.php # # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -DEPFILES = $(OBJECTS:%.o=%.d) - -$(MAKEROOT)/libs-$(ARCH): - mkdir -p $(MAKEROOT)/libs-$(ARCH) - -.PHONY: install -install: $(MAKEROOT)/libs-$(ARCH) $(LIBRARY) - cp $(LIBRARY) $(MAKEROOT)/libs-$(ARCH) - -$(LIBRARY): $(OBJECTS) - $(AR) crs $@ $^ - -%.o : %.c - $(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@ - -%.o : %.S - $(AS) -c $(ASFLAGS) $< -o $@ - -.PHONY: clean -clean: - @rm -f $(OBJECTS) $(LIBRARY) $(DEPFILES) - --include $(DEPFILES) +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +DEPFILES = $(OBJECTS:%.o=%.d) + +$(MAKEROOT)/libs-$(ARCH): + mkdir -p $(MAKEROOT)/libs-$(ARCH) + +.PHONY: install +install: $(MAKEROOT)/libs-$(ARCH) $(LIBRARY) + cp $(LIBRARY) $(MAKEROOT)/libs-$(ARCH) + +$(LIBRARY): $(OBJECTS) + $(AR) crs $@ $^ + +%.o : %.c + $(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@ + +%.o : %.S + $(AS) -c $(ASFLAGS) $< -o $@ + +.PHONY: clean +clean: + @rm -f $(OBJECTS) $(LIBRARY) $(DEPFILES) + +-include $(DEPFILES) diff --git a/BaseTools/Source/C/Makefiles/ms.app b/BaseTools/Source/C/Makefiles/ms.app index 7812175e7f..455549c121 100644 --- a/BaseTools/Source/C/Makefiles/ms.app +++ b/BaseTools/Source/C/Makefiles/ms.app @@ -7,28 +7,28 @@ # http://opensource.org/licenses/bsd-license.php # # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -!INCLUDE ..\Makefiles\ms.common - -APPLICATION = $(BIN_PATH)\$(APPNAME).exe - -all: $(APPLICATION) - -$(APPLICATION) : $(OBJECTS) - -@if not exist $(BIN_PATH) mkdir $(BIN_PATH) - $(LD) /nologo /debug /incremental:no /nodefaultlib:libc.lib /out:$@ $(LIBS) $** - +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +!INCLUDE ..\Makefiles\ms.common + +APPLICATION = $(BIN_PATH)\$(APPNAME).exe + +all: $(APPLICATION) + +$(APPLICATION) : $(OBJECTS) + -@if not exist $(BIN_PATH) mkdir $(BIN_PATH) + $(LD) /nologo /debug /incremental:no /nodefaultlib:libc.lib /out:$@ $(LIBS) $** + $(OBJECTS) : ..\Include\Common\BuildVersion.h -.PHONY:clean -.PHONY:cleanall - -clean: - del /f /q $(OBJECTS) *.pdb > nul - -cleanall: - del /f /q $(OBJECTS) $(APPLICATION) *.pdb $(BIN_PATH)\*.pdb > nul - -!INCLUDE ..\Makefiles\ms.rule - +.PHONY:clean +.PHONY:cleanall + +clean: + del /f /q $(OBJECTS) *.pdb > nul + +cleanall: + del /f /q $(OBJECTS) $(APPLICATION) *.pdb $(BIN_PATH)\*.pdb > nul + +!INCLUDE ..\Makefiles\ms.rule + diff --git a/BaseTools/Source/C/Makefiles/ms.common b/BaseTools/Source/C/Makefiles/ms.common index d2fbc453ee..fa9ffba563 100644 --- a/BaseTools/Source/C/Makefiles/ms.common +++ b/BaseTools/Source/C/Makefiles/ms.common @@ -7,54 +7,54 @@ # http://opensource.org/licenses/bsd-license.php # # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -!IFNDEF EDK_TOOLS_PATH -!ERROR "Please set your EDK_TOOLS_PATH!" -!ENDIF - -!IFNDEF BASE_TOOLS_PATH -!ERROR "BASE_TOOLS_PATH is not set! Please run build_tools.bat at first!" -!ENDIF - -!IFNDEF ARCH -ARCH = IA32 -!ENDIF - -MAKE = nmake -nologo - -SOURCE_PATH = $(BASE_TOOLS_PATH)\Source\C -BIN_PATH = $(BASE_TOOLS_PATH)\Bin -LIB_PATH = $(BASE_TOOLS_PATH)\Lib - -SYS_BIN_PATH=$(EDK_TOOLS_PATH)\Bin -SYS_LIB_PATH=$(EDK_TOOLS_PATH)\Lib - -!IF "$(ARCH)"=="IA32" -ARCH_INCLUDE = $(SOURCE_PATH)\Include\Ia32 -BIN_PATH = $(BASE_TOOLS_PATH)\Bin\Win32 -LIB_PATH = $(BASE_TOOLS_PATH)\Lib\Win32 -SYS_BIN_PATH = $(EDK_TOOLS_PATH)\Bin\Win32 -SYS_LIB_PATH = $(EDK_TOOLS_PATH)\Lib\Win32 -!ENDIF - -!IF "$(ARCH)"=="X64" -ARCH_INCLUDE = $(SOURCE_PATH)\Include\X64 -BIN_PATH = $(BASE_TOOLS_PATH)\Bin\Win64 -LIB_PATH = $(BASE_TOOLS_PATH)\Lib\Win64 -SYS_BIN_PATH = $(EDK_TOOLS_PATH)\Bin\Win64 -SYS_LIB_PATH = $(EDK_TOOLS_PATH)\Lib\Win64 -!ENDIF - -CC = cl.exe -CXX = cl.exe -AS = ml.exe -AR = lib.exe -LD = link.exe -LINKER = $(LD) - -INC = -I . -I $(SOURCE_PATH)\Include -I $(ARCH_INCLUDE) -I $(SOURCE_PATH)\Common $(INC) - -CFLAGS = $(CFLAGS) /nologo /c /Zi /Od /RTC1 /D _DEBUG /MTd /W4 /WX /D _CRT_SECURE_NO_DEPRECATE /D _CRT_NONSTDC_NO_DEPRECATE -CPPFLAGS = $(CPPFLAGS) /EHsc /nologo /c /Zi /Od /RTC1 /D _DEBUG /MTd /D _CRT_SECURE_NO_DEPRECATE /D _CRT_NONSTDC_NO_DEPRECATE - +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +!IFNDEF EDK_TOOLS_PATH +!ERROR "Please set your EDK_TOOLS_PATH!" +!ENDIF + +!IFNDEF BASE_TOOLS_PATH +!ERROR "BASE_TOOLS_PATH is not set! Please run build_tools.bat at first!" +!ENDIF + +!IFNDEF ARCH +ARCH = IA32 +!ENDIF + +MAKE = nmake -nologo + +SOURCE_PATH = $(BASE_TOOLS_PATH)\Source\C +BIN_PATH = $(BASE_TOOLS_PATH)\Bin +LIB_PATH = $(BASE_TOOLS_PATH)\Lib + +SYS_BIN_PATH=$(EDK_TOOLS_PATH)\Bin +SYS_LIB_PATH=$(EDK_TOOLS_PATH)\Lib + +!IF "$(ARCH)"=="IA32" +ARCH_INCLUDE = $(SOURCE_PATH)\Include\Ia32 +BIN_PATH = $(BASE_TOOLS_PATH)\Bin\Win32 +LIB_PATH = $(BASE_TOOLS_PATH)\Lib\Win32 +SYS_BIN_PATH = $(EDK_TOOLS_PATH)\Bin\Win32 +SYS_LIB_PATH = $(EDK_TOOLS_PATH)\Lib\Win32 +!ENDIF + +!IF "$(ARCH)"=="X64" +ARCH_INCLUDE = $(SOURCE_PATH)\Include\X64 +BIN_PATH = $(BASE_TOOLS_PATH)\Bin\Win64 +LIB_PATH = $(BASE_TOOLS_PATH)\Lib\Win64 +SYS_BIN_PATH = $(EDK_TOOLS_PATH)\Bin\Win64 +SYS_LIB_PATH = $(EDK_TOOLS_PATH)\Lib\Win64 +!ENDIF + +CC = cl.exe +CXX = cl.exe +AS = ml.exe +AR = lib.exe +LD = link.exe +LINKER = $(LD) + +INC = -I . -I $(SOURCE_PATH)\Include -I $(ARCH_INCLUDE) -I $(SOURCE_PATH)\Common $(INC) + +CFLAGS = $(CFLAGS) /nologo /c /Zi /Od /RTC1 /D _DEBUG /MTd /W4 /WX /D _CRT_SECURE_NO_DEPRECATE /D _CRT_NONSTDC_NO_DEPRECATE +CPPFLAGS = $(CPPFLAGS) /EHsc /nologo /c /Zi /Od /RTC1 /D _DEBUG /MTd /D _CRT_SECURE_NO_DEPRECATE /D _CRT_NONSTDC_NO_DEPRECATE + diff --git a/BaseTools/Source/C/Makefiles/ms.lib b/BaseTools/Source/C/Makefiles/ms.lib index 0e418f3c8f..55f6a23118 100644 --- a/BaseTools/Source/C/Makefiles/ms.lib +++ b/BaseTools/Source/C/Makefiles/ms.lib @@ -7,25 +7,25 @@ # http://opensource.org/licenses/bsd-license.php # # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -!INCLUDE ..\Makefiles\ms.common - -LIBRARY = $(LIB_PATH)\$(LIBNAME).lib - -all: $(LIBRARY) - -$(LIBRARY) : $(OBJECTS) - -@if not exist $(LIB_PATH) mkdir $(LIB_PATH) - $(AR) /nologo /out:$@ $** - -.PHONY:clean -clean: - del /f /q $(OBJECTS) *.pdb > nul - -.PHONY:cleanall -cleanall: - del /f /q $(OBJECTS) $(LIBRARY) *.pdb > nul - -!INCLUDE ..\Makefiles\ms.rule - +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +!INCLUDE ..\Makefiles\ms.common + +LIBRARY = $(LIB_PATH)\$(LIBNAME).lib + +all: $(LIBRARY) + +$(LIBRARY) : $(OBJECTS) + -@if not exist $(LIB_PATH) mkdir $(LIB_PATH) + $(AR) /nologo /out:$@ $** + +.PHONY:clean +clean: + del /f /q $(OBJECTS) *.pdb > nul + +.PHONY:cleanall +cleanall: + del /f /q $(OBJECTS) $(LIBRARY) *.pdb > nul + +!INCLUDE ..\Makefiles\ms.rule + diff --git a/BaseTools/Source/C/Makefiles/ms.rule b/BaseTools/Source/C/Makefiles/ms.rule index afbd5dcc4b..b73e504b29 100644 --- a/BaseTools/Source/C/Makefiles/ms.rule +++ b/BaseTools/Source/C/Makefiles/ms.rule @@ -7,18 +7,18 @@ # http://opensource.org/licenses/bsd-license.php # # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -#DEPFILES = $(OBJECTS:%.o=%.d) - -.c.obj : - $(CC) -c $(CFLAGS) $(INC) $< -Fo$@ - -.S.obj : - $(AS) -c $(ASFLAGS) $< -Fo$@ - -.cpp.obj : - $(CXX) -c $(CPPFLAGS) $(INC) $< -Fo$@ - -#-include $(DEPFILES) - +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +#DEPFILES = $(OBJECTS:%.o=%.d) + +.c.obj : + $(CC) -c $(CFLAGS) $(INC) $< -Fo$@ + +.S.obj : + $(AS) -c $(ASFLAGS) $< -Fo$@ + +.cpp.obj : + $(CXX) -c $(CPPFLAGS) $(INC) $< -Fo$@ + +#-include $(DEPFILES) + diff --git a/BaseTools/Source/C/PyEfiCompressor/Makefile b/BaseTools/Source/C/PyEfiCompressor/Makefile index d52a3454b7..fdd2e391cb 100644 --- a/BaseTools/Source/C/PyEfiCompressor/Makefile +++ b/BaseTools/Source/C/PyEfiCompressor/Makefile @@ -7,17 +7,17 @@ # http://opensource.org/licenses/bsd-license.php # # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -!INCLUDE ..\Makefiles\ms.common - -APPNAME = GenSec - -LIBS = $(LIB_PATH)\Common.lib - -OBJECTS = GenSec.obj - -#CFLAGS = $(CFLAGS) /nodefaultlib:libc.lib - -!INCLUDE ..\Makefiles\ms.app - +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +!INCLUDE ..\Makefiles\ms.common + +APPNAME = GenSec + +LIBS = $(LIB_PATH)\Common.lib + +OBJECTS = GenSec.obj + +#CFLAGS = $(CFLAGS) /nodefaultlib:libc.lib + +!INCLUDE ..\Makefiles\ms.app + diff --git a/BaseTools/Source/C/PyUtility/Makefile b/BaseTools/Source/C/PyUtility/Makefile index 71d4d542bd..0cc9ad7987 100644 --- a/BaseTools/Source/C/PyUtility/Makefile +++ b/BaseTools/Source/C/PyUtility/Makefile @@ -7,17 +7,17 @@ # http://opensource.org/licenses/bsd-license.php # # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -!INCLUDE ..\Makefiles\ms.common - -APPNAME = GenSec - -LIBS = $(LIB_PATH)\Common.lib - -OBJECTS = PyUtility.obj - -#CFLAGS = $(CFLAGS) /nodefaultlib:libc.lib - -!INCLUDE ..\Makefiles\ms.app - +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +!INCLUDE ..\Makefiles\ms.common + +APPNAME = GenSec + +LIBS = $(LIB_PATH)\Common.lib + +OBJECTS = PyUtility.obj + +#CFLAGS = $(CFLAGS) /nodefaultlib:libc.lib + +!INCLUDE ..\Makefiles\ms.app + diff --git a/BaseTools/Source/C/VfrCompile/VfrFormPkg.cpp b/BaseTools/Source/C/VfrCompile/VfrFormPkg.cpp index addff24cf6..6dfc118eea 100644 --- a/BaseTools/Source/C/VfrCompile/VfrFormPkg.cpp +++ b/BaseTools/Source/C/VfrCompile/VfrFormPkg.cpp @@ -82,7 +82,7 @@ SPendingAssign::AssignValue ( IN UINT32 Len ) { - memcpy (mAddr, Addr, (mLen < Len ? mLen : Len)); + memmove (mAddr, Addr, (mLen < Len ? mLen : Len)); mFlag = ASSIGNED; } @@ -685,7 +685,7 @@ CFormPkg::AdjustDynamicInsertOpcode ( // // Override the restore buffer data. // - memcpy (LastFormEndAddr, InsertOpcodeAddr, InsertOpcodeNode->mBufferFree - InsertOpcodeAddr); + memmove (LastFormEndAddr, InsertOpcodeAddr, InsertOpcodeNode->mBufferFree - InsertOpcodeAddr); InsertOpcodeNode->mBufferFree -= NeedRestoreCodeLen; memset (InsertOpcodeNode->mBufferFree, 0, NeedRestoreCodeLen); } else { @@ -733,7 +733,7 @@ CFormPkg::AdjustDynamicInsertOpcode ( // // Override the restore buffer data. // - memcpy (InsertOpcodeNode->mBufferStart, InsertOpcodeAddr, InsertOpcodeNode->mBufferFree - InsertOpcodeAddr); + memmove (InsertOpcodeNode->mBufferStart, InsertOpcodeAddr, InsertOpcodeNode->mBufferFree - InsertOpcodeAddr); InsertOpcodeNode->mBufferFree -= InsertOpcodeAddr - InsertOpcodeNode->mBufferStart; // @@ -1542,7 +1542,7 @@ CIfrObj::_EMIT_PENDING_OBJ ( // ObjBinBuf = gCFormPkg.IfrBinBufferGet (mObjBinLen); if (ObjBinBuf != NULL) { - memcpy (ObjBinBuf, mObjBinBuf, mObjBinLen); + memmove (ObjBinBuf, mObjBinBuf, mObjBinLen); } // diff --git a/BaseTools/Source/C/VfrCompile/VfrFormPkg.h b/BaseTools/Source/C/VfrCompile/VfrFormPkg.h index 25280def9b..c69518af76 100644 --- a/BaseTools/Source/C/VfrCompile/VfrFormPkg.h +++ b/BaseTools/Source/C/VfrCompile/VfrFormPkg.h @@ -368,7 +368,7 @@ public: VOID VARSTORE_INFO (OUT EFI_VARSTORE_INFO *Info) { if (Info != NULL) { Info->mVarStoreId = mHeader->VarStoreId; - memcpy (&Info->mVarStoreId, &mHeader->VarStoreInfo, sizeof (Info->mVarStoreId)); + memmove (&Info->mVarStoreId, &mHeader->VarStoreInfo, sizeof (Info->mVarStoreId)); } } @@ -615,7 +615,7 @@ public: } VOID SetGuid (IN EFI_GUID *Guid) { - memcpy (&mFormSet->Guid, Guid, sizeof (EFI_GUID)); + memmove (&mFormSet->Guid, Guid, sizeof (EFI_GUID)); } VOID SetFormSetTitle (IN EFI_STRING_ID FormSetTitle) { @@ -627,7 +627,7 @@ public: } VOID SetClassGuid (IN EFI_GUID *Guid) { - memcpy (&(mClassGuid[mFormSet->Flags++]), Guid, sizeof (EFI_GUID)); + memmove (&(mClassGuid[mFormSet->Flags++]), Guid, sizeof (EFI_GUID)); } UINT8 GetFlags() { @@ -749,7 +749,7 @@ public: IncLength (sizeof (EFI_IFR_FORM_MAP_METHOD)); mMethodMap->MethodTitle = MethodTitle; - memcpy (&(mMethodMap->MethodIdentifier), MethodGuid, sizeof (EFI_GUID)); + memmove (&(mMethodMap->MethodIdentifier), MethodGuid, sizeof (EFI_GUID)); mMethodMap ++; } } @@ -769,7 +769,7 @@ public: } VOID SetGuid (IN EFI_GUID *Guid) { - memcpy (&mVarStore->Guid, Guid, sizeof (EFI_GUID)); + memmove (&mVarStore->Guid, Guid, sizeof (EFI_GUID)); } VOID SetVarStoreId (IN EFI_VARSTORE_ID VarStoreId) { @@ -809,7 +809,7 @@ public: } VOID SetGuid (IN EFI_GUID *Guid) { - memcpy (&mVarStoreEfi->Guid, Guid, sizeof (EFI_GUID)); + memmove (&mVarStoreEfi->Guid, Guid, sizeof (EFI_GUID)); } VOID SetVarStoreId (IN UINT16 VarStoreId) { @@ -863,7 +863,7 @@ public: } VOID SetGuid (IN EFI_GUID *Guid) { - memcpy (&mVarStoreNameValue->Guid, Guid, sizeof (EFI_GUID)); + memmove (&mVarStoreNameValue->Guid, Guid, sizeof (EFI_GUID)); } VOID SetVarStoreId (IN UINT16 VarStoreId) { @@ -938,7 +938,7 @@ public: CIfrOpHeader (EFI_IFR_DEFAULT_OP, &mDefault->Header, Size) { mDefault->Type = Type; mDefault->DefaultId = DefaultId; - memcpy (&(mDefault->Value), &Value, Size - OFFSET_OF (EFI_IFR_DEFAULT, Value)); + memmove (&(mDefault->Value), &Value, Size - OFFSET_OF (EFI_IFR_DEFAULT, Value)); } VOID SetDefaultId (IN UINT16 DefaultId) { @@ -950,7 +950,7 @@ public: } VOID SetValue (IN EFI_IFR_TYPE_VALUE Value) { - memcpy (&mDefault->Value, &Value, mDefault->Header.Length - OFFSET_OF (EFI_IFR_DEFAULT, Value)); + memmove (&mDefault->Value, &Value, mDefault->Header.Length - OFFSET_OF (EFI_IFR_DEFAULT, Value)); } }; @@ -1673,7 +1673,7 @@ public: } VOID SetRefreshEventGroutId (IN EFI_GUID *RefreshEventGroupId) { - memcpy (&mRefreshId->RefreshEventGroupId, RefreshEventGroupId, sizeof (EFI_GUID)); + memmove (&mRefreshId->RefreshEventGroupId, RefreshEventGroupId, sizeof (EFI_GUID)); } }; @@ -1755,7 +1755,7 @@ public: } VOID SetValue (IN EFI_IFR_TYPE_VALUE Value) { - memcpy (&mOneOfOption->Value, &Value, mOneOfOption->Header.Length - OFFSET_OF (EFI_IFR_ONE_OF_OPTION, Value)); + memmove (&mOneOfOption->Value, &Value, mOneOfOption->Header.Length - OFFSET_OF (EFI_IFR_ONE_OF_OPTION, Value)); } UINT8 GetFlags (VOID) { @@ -1904,11 +1904,11 @@ public: } VOID SetGuid (IN EFI_GUID *Guid) { - memcpy (&mGuid->Guid, Guid, sizeof (EFI_GUID)); + memmove (&mGuid->Guid, Guid, sizeof (EFI_GUID)); } VOID SetData (IN UINT8* DataBuff, IN UINT8 Size) { - memcpy ((UINT8 *)mGuid + sizeof (EFI_IFR_GUID), DataBuff, Size); + memmove ((UINT8 *)mGuid + sizeof (EFI_IFR_GUID), DataBuff, Size); } }; @@ -2214,7 +2214,7 @@ public: } VOID SetPermissions (IN EFI_GUID *Permissions) { - memcpy (&mSecurity->Permissions, Permissions, sizeof (EFI_GUID)); + memmove (&mSecurity->Permissions, Permissions, sizeof (EFI_GUID)); } }; diff --git a/BaseTools/Source/C/VolInfo/VolInfo.c b/BaseTools/Source/C/VolInfo/VolInfo.c index 7d127e1691..0f54c2a429 100644 --- a/BaseTools/Source/C/VolInfo/VolInfo.c +++ b/BaseTools/Source/C/VolInfo/VolInfo.c @@ -1,1826 +1,1826 @@ -/** @file - -Copyright (c) 1999 - 2011, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - VolInfo.c - -Abstract: - - The tool dumps the contents of a firmware volume - -**/ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "Compress.h" -#include "Decompress.h" -#include "VolInfo.h" -#include "CommonLib.h" -#include "EfiUtilityMsgs.h" -#include "FirmwareVolumeBufferLib.h" -#include "OsPath.h" -#include "ParseGuidedSectionTools.h" -#include "StringFuncs.h" - -// -// Utility global variables -// - -EFI_GUID gEfiCrc32GuidedSectionExtractionProtocolGuid = EFI_CRC32_GUIDED_SECTION_EXTRACTION_PROTOCOL_GUID; - -#define UTILITY_MAJOR_VERSION 0 -#define UTILITY_MINOR_VERSION 82 - -#define UTILITY_NAME "VolInfo" - -#define EFI_SECTION_ERROR EFIERR (100) - -#define MAX_BASENAME_LEN 60 // not good to hardcode, but let's be reasonable - -// -// Structure to keep a list of guid-to-basenames -// -typedef struct _GUID_TO_BASENAME { - struct _GUID_TO_BASENAME *Next; - INT8 Guid[PRINTED_GUID_BUFFER_SIZE]; - INT8 BaseName[MAX_BASENAME_LEN]; -} GUID_TO_BASENAME; - -static GUID_TO_BASENAME *mGuidBaseNameList = NULL; - -// -// Store GUIDed Section guid->tool mapping -// -EFI_HANDLE mParsedGuidedSectionTools = NULL; - -CHAR8* mUtilityFilename = NULL; - -EFI_STATUS -ParseGuidBaseNameFile ( - CHAR8 *FileName - ); - -EFI_STATUS -FreeGuidBaseNameList ( - VOID - ); - -EFI_STATUS -PrintGuidName ( - IN UINT8 *GuidStr - ); - -EFI_STATUS -ParseSection ( - IN UINT8 *SectionBuffer, - IN UINT32 BufferLength - ); - -EFI_STATUS -DumpDepexSection ( - IN UINT8 *Ptr, - IN UINT32 SectionLength - ); - -STATIC -EFI_STATUS -ReadHeader ( - IN FILE *InputFile, - OUT UINT32 *FvSize, - OUT BOOLEAN *ErasePolarity - ); - -STATIC -EFI_STATUS -PrintFileInfo ( - EFI_FIRMWARE_VOLUME_HEADER *FvImage, - EFI_FFS_FILE_HEADER *FileHeader, - BOOLEAN ErasePolarity - ); - -static -EFI_STATUS -PrintFvInfo ( - IN VOID *Fv, - IN BOOLEAN IsChildFv - ); - -static -VOID -LoadGuidedSectionToolsTxt ( - IN CHAR8* FirmwareVolumeFilename - ); - -void -Usage ( - VOID - ); - -int -main ( - int argc, - char *argv[] - ) -/*++ - -Routine Description: - - GC_TODO: Add function description - -Arguments: - - argc - GC_TODO: add argument description - ] - GC_TODO: add argument description - -Returns: - - GC_TODO: add return values - ---*/ -{ - FILE *InputFile; - int BytesRead; - EFI_FIRMWARE_VOLUME_HEADER *FvImage; - UINT32 FvSize; - EFI_STATUS Status; - int Offset; - BOOLEAN ErasePolarity; - - SetUtilityName (UTILITY_NAME); - // - // Print utility header - // - printf ("%s Tiano Firmware Volume FFS image info. Version %d.%d %s, %s\n", - UTILITY_NAME, - UTILITY_MAJOR_VERSION, - UTILITY_MINOR_VERSION, - __BUILD_VERSION, - __DATE__ - ); - - // - // Save, and then skip filename arg - // - mUtilityFilename = argv[0]; - argc--; - argv++; - - Offset = 0; - - // - // If they specified -x xref guid/basename cross-reference files, process it. - // This will print the basename beside each file guid. To use it, specify - // -x xref_filename to processdsc, then use xref_filename as a parameter - // here. - // - while (argc > 2) { - if ((strcmp(argv[0], "-x") == 0) || (strcmp(argv[0], "--xref") == 0)) { - ParseGuidBaseNameFile (argv[1]); - printf("ParseGuidBaseNameFile: %s\n", argv[1]); - argc -= 2; - argv += 2; - } else if (strcmp(argv[0], "--offset") == 0) { - // - // Hex or decimal? - // - if ((argv[1][0] == '0') && (tolower ((int)argv[1][1]) == 'x')) { - if (sscanf (argv[1], "%x", &Offset) != 1) { - Error (NULL, 0, 1003, "Invalid option value", "Offset = %s", argv[1]); - return GetUtilityStatus (); - } - } else { - if (sscanf (argv[1], "%d", &Offset) != 1) { - Error (NULL, 0, 1003, "Invalid option value", "Offset = %s", argv[1]); - return GetUtilityStatus (); - } - // - // See if they said something like "64K" - // - if (tolower ((int)argv[1][strlen (argv[1]) - 1]) == 'k') { - Offset *= 1024; - } - } - - argc -= 2; - argv += 2; - } else { - Usage (); - return -1; - } - } - // - // Check for proper number of arguments - // - if (argc != 1) { - Usage (); - return -1; - } - // - // Look for help options - // - if ((strcmp(argv[0], "-h") == 0) || (strcmp(argv[0], "--help") == 0) || - (strcmp(argv[0], "-?") == 0) || (strcmp(argv[0], "/?") == 0)) { - Usage(); - return STATUS_ERROR; - } - - // - // Open the file containing the FV - // - InputFile = fopen (argv[0], "rb"); - if (InputFile == NULL) { - Error (NULL, 0, 0001, "Error opening the input file", argv[0]); - return GetUtilityStatus (); - } - // - // Skip over pad bytes if specified. This is used if they prepend 0xff - // data to the FV image binary. - // - if (Offset != 0) { - fseek (InputFile, Offset, SEEK_SET); - } - // - // Determine size of FV - // - Status = ReadHeader (InputFile, &FvSize, &ErasePolarity); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 0003, "error parsing FV image", "%s Header is invalid", argv[0]); - fclose (InputFile); - return GetUtilityStatus (); - } - // - // Allocate a buffer for the FV image - // - FvImage = malloc (FvSize); - if (FvImage == NULL) { - Error (NULL, 0, 4001, "Resource: Memory can't be allocated", NULL); - fclose (InputFile); - return GetUtilityStatus (); - } - // - // Seek to the start of the image, then read the entire FV to the buffer - // - fseek (InputFile, Offset, SEEK_SET); - BytesRead = fread (FvImage, 1, FvSize, InputFile); - fclose (InputFile); - if ((unsigned int) BytesRead != FvSize) { - Error (NULL, 0, 0004, "error reading FvImage from", argv[0]); - free (FvImage); - return GetUtilityStatus (); - } - - LoadGuidedSectionToolsTxt (argv[0]); - - PrintFvInfo (FvImage, FALSE); - - // - // Clean up - // - free (FvImage); - FreeGuidBaseNameList (); - return GetUtilityStatus (); -} - - -static -EFI_STATUS -PrintFvInfo ( - IN VOID *Fv, - IN BOOLEAN IsChildFv - ) -/*++ - -Routine Description: - - GC_TODO: Add function description - -Arguments: - - Fv - Firmware Volume to print information about - IsChildFv - Flag specifies whether the input FV is a child FV. - -Returns: - - EFI_STATUS - ---*/ -{ - EFI_STATUS Status; - UINTN NumberOfFiles; - BOOLEAN ErasePolarity; - UINTN FvSize; - EFI_FFS_FILE_HEADER *CurrentFile; - UINTN Key; - - Status = FvBufGetSize (Fv, &FvSize); - - NumberOfFiles = 0; - ErasePolarity = - (((EFI_FIRMWARE_VOLUME_HEADER*)Fv)->Attributes & EFI_FVB2_ERASE_POLARITY) ? - TRUE : FALSE; - - // - // Get the first file - // - Key = 0; - Status = FvBufFindNextFile (Fv, &Key, (VOID **) &CurrentFile); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 0003, "error parsing FV image", "cannot find the first file in the FV image"); - return GetUtilityStatus (); - } - // - // Display information about files found - // - while (CurrentFile != NULL) { - // - // Increment the number of files counter - // - NumberOfFiles++; - - // - // Display info about this file - // - Status = PrintFileInfo (Fv, CurrentFile, ErasePolarity); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 0003, "error parsing FV image", "failed to parse a file in the FV"); - return GetUtilityStatus (); - } - // - // Get the next file - // - Status = FvBufFindNextFile (Fv, &Key, (VOID **) &CurrentFile); - if (Status == EFI_NOT_FOUND) { - CurrentFile = NULL; - } else if (EFI_ERROR (Status)) { - Error (NULL, 0, 0003, "error parsing FV image", "cannot find the next file in the FV image"); - return GetUtilityStatus (); - } - } - - if (IsChildFv) { - printf ("There are a total of %d files in the child FV\n", (int) NumberOfFiles); - } else { - printf ("There are a total of %d files in this FV\n", (int) NumberOfFiles); - } - - return EFI_SUCCESS; -} - -UINT32 -GetOccupiedSize ( - IN UINT32 ActualSize, - IN UINT32 Alignment - ) -/*++ - -Routine Description: - - This function returns the next larger size that meets the alignment - requirement specified. - -Arguments: - - ActualSize The size. - Alignment The desired alignment. - -Returns: - - EFI_SUCCESS Function completed successfully. - EFI_ABORTED The function encountered an error. - ---*/ -{ - UINT32 OccupiedSize; - - OccupiedSize = ActualSize; - while ((OccupiedSize & (Alignment - 1)) != 0) { - OccupiedSize++; - } - - return OccupiedSize; -} - -static -CHAR8 * -SectionNameToStr ( - IN EFI_SECTION_TYPE Type - ) -/*++ - -Routine Description: - - Converts EFI Section names to Strings - -Arguments: - - Type - The EFI Section type - -Returns: - - CHAR8* - Pointer to the String containing the section name. - ---*/ -{ - CHAR8 *SectionStr; - CHAR8 *SectionTypeStringTable[] = { - // - // 0X00 - // - "EFI_SECTION_ALL", - // - // 0x01 - // - "EFI_SECTION_COMPRESSION", - // - // 0x02 - // - "EFI_SECTION_GUID_DEFINED", - // - // 0x03 - // - "Unknown section type - Reserved 0x03", - // - // 0x04 - // - "Unknown section type - Reserved 0x04", - // - // 0x05 - // - "Unknown section type - Reserved 0x05", - // - // 0x06 - // - "Unknown section type - Reserved 0x06", - // - // 0x07 - // - "Unknown section type - Reserved 0x07", - // - // 0x08 - // - "Unknown section type - Reserved 0x08", - // - // 0x09 - // - "Unknown section type - Reserved 0x09", - // - // 0x0A - // - "Unknown section type - Reserved 0x0A", - // - // 0x0B - // - "Unknown section type - Reserved 0x0B", - // - // 0x0C - // - "Unknown section type - Reserved 0x0C", - // - // 0x0D - // - "Unknown section type - Reserved 0x0D", - // - // 0x0E - // - "Unknown section type - Reserved 0x0E", - // - // 0x0F - // - "Unknown section type - Reserved 0x0E", - // - // 0x10 - // - "EFI_SECTION_PE32", - // - // 0x11 - // - "EFI_SECTION_PIC", - // - // 0x12 - // - "EFI_SECTION_TE", - // - // 0x13 - // - "EFI_SECTION_DXE_DEPEX", - // - // 0x14 - // - "EFI_SECTION_VERSION", - // - // 0x15 - // - "EFI_SECTION_USER_INTERFACE", - // - // 0x16 - // - "EFI_SECTION_COMPATIBILITY16", - // - // 0x17 - // - "EFI_SECTION_FIRMWARE_VOLUME_IMAGE ", - // - // 0x18 - // - "EFI_SECTION_FREEFORM_SUBTYPE_GUID ", - // - // 0x19 - // - "EFI_SECTION_RAW", - // - // 0x1A - // - "Unknown section type - 0x1A", - // - // 0x1B - // - "EFI_SECTION_PEI_DEPEX", - // - // 0x1C - // - "EFI_SECTION_SMM_DEPEX", - // - // 0x1C+ - // - "Unknown section type - Reserved - beyond last defined section" - }; - - if (Type > EFI_SECTION_LAST_SECTION_TYPE) { - Type = EFI_SECTION_LAST_SECTION_TYPE + 1; - } - - SectionStr = malloc (100); - if (SectionStr == NULL) { - printf ("Error: Out of memory resources.\n"); - return SectionStr; - } - strcpy (SectionStr, SectionTypeStringTable[Type]); - return SectionStr; -} - -STATIC -EFI_STATUS -ReadHeader ( - IN FILE *InputFile, - OUT UINT32 *FvSize, - OUT BOOLEAN *ErasePolarity - ) -/*++ - -Routine Description: - - This function determines the size of the FV and the erase polarity. The - erase polarity is the FALSE value for file state. - -Arguments: - - InputFile The file that contains the FV image. - FvSize The size of the FV. - ErasePolarity The FV erase polarity. - -Returns: - - EFI_SUCCESS Function completed successfully. - EFI_INVALID_PARAMETER A required parameter was NULL or is out of range. - EFI_ABORTED The function encountered an error. - ---*/ -{ - EFI_FIRMWARE_VOLUME_HEADER VolumeHeader; - EFI_FV_BLOCK_MAP_ENTRY BlockMap; - UINTN Signature[2]; - UINTN BytesRead; - UINT32 Size; - - BytesRead = 0; - Size = 0; - // - // Check input parameters - // - if (InputFile == NULL || FvSize == NULL || ErasePolarity == NULL) { - Error (__FILE__, __LINE__, 0, "application error", "invalid parameter to function"); - return EFI_INVALID_PARAMETER; - } - // - // Read the header - // - fread (&VolumeHeader, sizeof (EFI_FIRMWARE_VOLUME_HEADER) - sizeof (EFI_FV_BLOCK_MAP_ENTRY), 1, InputFile); - BytesRead = sizeof (EFI_FIRMWARE_VOLUME_HEADER) - sizeof (EFI_FV_BLOCK_MAP_ENTRY); - Signature[0] = VolumeHeader.Signature; - Signature[1] = 0; - - // - // Print FV header information - // - printf ("Signature: %s (%X)\n", (char *) Signature, (unsigned) VolumeHeader.Signature); - printf ("Attributes: %X\n", (unsigned) VolumeHeader.Attributes); - - if (VolumeHeader.Attributes & EFI_FVB2_READ_DISABLED_CAP) { - printf (" EFI_FVB2_READ_DISABLED_CAP\n"); - } - - if (VolumeHeader.Attributes & EFI_FVB2_READ_ENABLED_CAP) { - printf (" EFI_FVB2_READ_ENABLED_CAP\n"); - } - - if (VolumeHeader.Attributes & EFI_FVB2_READ_STATUS) { - printf (" EFI_FVB2_READ_STATUS\n"); - } - - if (VolumeHeader.Attributes & EFI_FVB2_WRITE_DISABLED_CAP) { - printf (" EFI_FVB2_WRITE_DISABLED_CAP\n"); - } - - if (VolumeHeader.Attributes & EFI_FVB2_WRITE_ENABLED_CAP) { - printf (" EFI_FVB2_WRITE_ENABLED_CAP\n"); - } - - if (VolumeHeader.Attributes & EFI_FVB2_WRITE_STATUS) { - printf (" EFI_FVB2_WRITE_STATUS\n"); - } - - if (VolumeHeader.Attributes & EFI_FVB2_LOCK_CAP) { - printf (" EFI_FVB2_LOCK_CAP\n"); - } - - if (VolumeHeader.Attributes & EFI_FVB2_LOCK_STATUS) { - printf (" EFI_FVB2_LOCK_STATUS\n"); - } - - if (VolumeHeader.Attributes & EFI_FVB2_STICKY_WRITE) { - printf (" EFI_FVB2_STICKY_WRITE\n"); - } - - if (VolumeHeader.Attributes & EFI_FVB2_MEMORY_MAPPED) { - printf (" EFI_FVB2_MEMORY_MAPPED\n"); - } - - if (VolumeHeader.Attributes & EFI_FVB2_ERASE_POLARITY) { - printf (" EFI_FVB2_ERASE_POLARITY\n"); - *ErasePolarity = TRUE; - } - -#if (PI_SPECIFICATION_VERSION < 0x00010000) - if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT) { - printf (" EFI_FVB2_ALIGNMENT\n"); - } - - if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_2) { - printf (" EFI_FVB2_ALIGNMENT_2\n"); - } - - if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_4) { - printf (" EFI_FVB2_ALIGNMENT_4\n"); - } - - if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_8) { - printf (" EFI_FVB2_ALIGNMENT_8\n"); - } - - if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_16) { - printf (" EFI_FVB2_ALIGNMENT_16\n"); - } - - if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_32) { - printf (" EFI_FVB2_ALIGNMENT_32\n"); - } - - if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_64) { - printf (" EFI_FVB2_ALIGNMENT_64\n"); - } - - if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_128) { - printf (" EFI_FVB2_ALIGNMENT_128\n"); - } - - if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_256) { - printf (" EFI_FVB2_ALIGNMENT_256\n"); - } - - if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_512) { - printf (" EFI_FVB2_ALIGNMENT_512\n"); - } - - if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_1K) { - printf (" EFI_FVB2_ALIGNMENT_1K\n"); - } - - if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_2K) { - printf (" EFI_FVB2_ALIGNMENT_2K\n"); - } - - if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_4K) { - printf (" EFI_FVB2_ALIGNMENT_4K\n"); - } - - if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_8K) { - printf (" EFI_FVB2_ALIGNMENT_8K\n"); - } - - if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_16K) { - printf (" EFI_FVB2_ALIGNMENT_16K\n"); - } - - if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_32K) { - printf (" EFI_FVB2_ALIGNMENT_32K\n"); - } - - if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_64K) { - printf (" EFI_FVB2_ALIGNMENT_64K\n"); - } - -#else - - if (VolumeHeader.Attributes & EFI_FVB2_READ_LOCK_CAP) { - printf (" EFI_FVB2_READ_LOCK_CAP\n"); - } - - if (VolumeHeader.Attributes & EFI_FVB2_READ_LOCK_STATUS) { - printf (" EFI_FVB2_READ_LOCK_STATUS\n"); - } - - if (VolumeHeader.Attributes & EFI_FVB2_WRITE_LOCK_CAP) { - printf (" EFI_FVB2_WRITE_LOCK_CAP\n"); - } - - if (VolumeHeader.Attributes & EFI_FVB2_WRITE_LOCK_STATUS) { - printf (" EFI_FVB2_WRITE_LOCK_STATUS\n"); - } - - if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_1) { - printf (" EFI_FVB2_ALIGNMENT_1\n"); - } - - if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_2) { - printf (" EFI_FVB2_ALIGNMENT_2\n"); - } - - if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_4) { - printf (" EFI_FVB2_ALIGNMENT_4\n"); - } - - if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_8) { - printf (" EFI_FVB2_ALIGNMENT_8\n"); - } - - if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_16) { - printf (" EFI_FVB2_ALIGNMENT_16\n"); - } - - if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_32) { - printf (" EFI_FVB2_ALIGNMENT_32\n"); - } - - if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_64) { - printf (" EFI_FVB2_ALIGNMENT_64\n"); - } - - if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_128) { - printf (" EFI_FVB2_ALIGNMENT_128\n"); - } - - if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_256) { - printf (" EFI_FVB2_ALIGNMENT_256\n"); - } - - if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_512) { - printf (" EFI_FVB2_ALIGNMENT_512\n"); - } - - if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_1K) { - printf (" EFI_FVB2_ALIGNMENT_1K\n"); - } - - if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_2K) { - printf (" EFI_FVB2_ALIGNMENT_2K\n"); - } - - if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_4K) { - printf (" EFI_FVB2_ALIGNMENT_4K\n"); - } - - if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_8K) { - printf (" EFI_FVB2_ALIGNMENT_8K\n"); - } - - if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_16K) { - printf (" EFI_FVB2_ALIGNMENT_16K\n"); - } - - if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_32K) { - printf (" EFI_FVB2_ALIGNMENT_32K\n"); - } - - if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_64K) { - printf (" EFI_FVB2_ALIGNMENT_64K\n"); - } - - if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_128K) { - printf (" EFI_FVB2_ALIGNMENT_128K\n"); - } - - if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_256K) { - printf (" EFI_FVB2_ALIGNMENT_256K\n"); - } - - if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_512K) { - printf (" EFI_FVB2_ALIGNMENT_512K\n"); - } - - if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_1M) { - printf (" EFI_FVB2_ALIGNMENT_1M\n"); - } - - if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_2M) { - printf (" EFI_FVB2_ALIGNMENT_2M\n"); - } - - if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_4M) { - printf (" EFI_FVB2_ALIGNMENT_4M\n"); - } - - if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_8M) { - printf (" EFI_FVB2_ALIGNMENT_8M\n"); - } - - if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_16M) { - printf (" EFI_FVB2_ALIGNMENT_16M\n"); - } - - if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_32M) { - printf (" EFI_FVB2_ALIGNMENT_32M\n"); - } - - if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_64M) { - printf (" EFI_FVB2_ALIGNMENT_64M\n"); - } - - if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_128M) { - printf (" EFI_FVB2_ALIGNMENT_128M\n"); - } - - if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_64M) { - printf (" EFI_FVB2_ALIGNMENT_64M\n"); - } - - if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_128M) { - printf (" EFI_FVB2_ALIGNMENT_128M\n"); - } - - if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_256M) { - printf (" EFI_FVB2_ALIGNMENT_256M\n"); - } - - if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_512M) { - printf (" EFI_FVB2_ALIGNMENT_512M\n"); - } - - if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_1G) { - printf (" EFI_FVB2_ALIGNMENT_1G\n"); - } - - if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_2G) { - printf (" EFI_FVB2_ALIGNMENT_2G\n"); - } - -#endif - printf ("Header Length: 0x%08X\n", VolumeHeader.HeaderLength); - printf ("File System ID: "); - PrintGuid (&VolumeHeader.FileSystemGuid); - // - // printf ("\n"); - // - printf ("Revision: 0x%04X\n", VolumeHeader.Revision); - - do { - fread (&BlockMap, sizeof (EFI_FV_BLOCK_MAP_ENTRY), 1, InputFile); - BytesRead += sizeof (EFI_FV_BLOCK_MAP_ENTRY); - - if (BlockMap.NumBlocks != 0) { - printf ("Number of Blocks: 0x%08X\n", (unsigned) BlockMap.NumBlocks); - printf ("Block Length: 0x%08X\n", (unsigned) BlockMap.Length); - Size += BlockMap.NumBlocks * BlockMap.Length; - } - - } while (!(BlockMap.NumBlocks == 0 && BlockMap.Length == 0)); - - if (BytesRead != VolumeHeader.HeaderLength) { - printf ("ERROR: Header length not consistent with Block Maps!\n"); - return EFI_ABORTED; - } - - if (VolumeHeader.FvLength != Size) { - printf ("ERROR: Volume Size not consistant with Block Maps!\n"); - return EFI_ABORTED; - } - - printf ("Total Volume Size: 0x%08X\n", (unsigned) Size); - - *FvSize = Size; - - // - // rewind (InputFile); - // - return EFI_SUCCESS; -} - -STATIC -EFI_STATUS -PrintFileInfo ( - EFI_FIRMWARE_VOLUME_HEADER *FvImage, - EFI_FFS_FILE_HEADER *FileHeader, - BOOLEAN ErasePolarity - ) -/*++ - -Routine Description: - - GC_TODO: Add function description - -Arguments: - - FvImage - GC_TODO: add argument description - FileHeader - GC_TODO: add argument description - ErasePolarity - GC_TODO: add argument description - -Returns: - - EFI_SUCCESS - GC_TODO: Add description for return value - EFI_ABORTED - GC_TODO: Add description for return value - ---*/ -{ - UINT32 FileLength; - UINT8 FileState; - UINT8 Checksum; - EFI_FFS_FILE_HEADER BlankHeader; - EFI_STATUS Status; - UINT8 GuidBuffer[PRINTED_GUID_BUFFER_SIZE]; -#if (PI_SPECIFICATION_VERSION < 0x00010000) - UINT16 *Tail; -#endif - // - // Check if we have free space - // - if (ErasePolarity) { - memset (&BlankHeader, -1, sizeof (EFI_FFS_FILE_HEADER)); - } else { - memset (&BlankHeader, 0, sizeof (EFI_FFS_FILE_HEADER)); - } - - if (memcmp (&BlankHeader, FileHeader, sizeof (EFI_FFS_FILE_HEADER)) == 0) { - return EFI_SUCCESS; - } - // - // Print file information. - // - printf ("============================================================\n"); - - printf ("File Name: "); - PrintGuidToBuffer (&FileHeader->Name, GuidBuffer, sizeof (GuidBuffer), TRUE); - printf ("%s ", GuidBuffer); - PrintGuidName (GuidBuffer); - printf ("\n"); - - // - // PrintGuid (&FileHeader->Name); - // printf ("\n"); - // - FileLength = GetLength (FileHeader->Size); - printf ("File Offset: 0x%08X\n", (unsigned) ((UINTN) FileHeader - (UINTN) FvImage)); - printf ("File Length: 0x%08X\n", (unsigned) FileLength); - printf ("File Attributes: 0x%02X\n", FileHeader->Attributes); - printf ("File State: 0x%02X\n", FileHeader->State); - - // - // Print file state - // - FileState = GetFileState (ErasePolarity, FileHeader); - - switch (FileState) { - - case EFI_FILE_HEADER_CONSTRUCTION: - printf (" EFI_FILE_HEADER_CONSTRUCTION\n"); - return EFI_SUCCESS; - - case EFI_FILE_HEADER_INVALID: - printf (" EFI_FILE_HEADER_INVALID\n"); - return EFI_SUCCESS; - - case EFI_FILE_HEADER_VALID: - printf (" EFI_FILE_HEADER_VALID\n"); - Checksum = CalculateSum8 ((UINT8 *) FileHeader, sizeof (EFI_FFS_FILE_HEADER)); - Checksum = (UINT8) (Checksum - FileHeader->IntegrityCheck.Checksum.File); - Checksum = (UINT8) (Checksum - FileHeader->State); - if (Checksum != 0) { - printf ("ERROR: Header checksum invalid.\n"); - return EFI_ABORTED; - } - - return EFI_SUCCESS; - - case EFI_FILE_DELETED: - printf (" EFI_FILE_DELETED\n"); - - case EFI_FILE_MARKED_FOR_UPDATE: - printf (" EFI_FILE_MARKED_FOR_UPDATE\n"); - - case EFI_FILE_DATA_VALID: - printf (" EFI_FILE_DATA_VALID\n"); - - // - // Calculate header checksum - // - Checksum = CalculateSum8 ((UINT8 *) FileHeader, sizeof (EFI_FFS_FILE_HEADER)); - Checksum = (UINT8) (Checksum - FileHeader->IntegrityCheck.Checksum.File); - Checksum = (UINT8) (Checksum - FileHeader->State); - if (Checksum != 0) { - Error (NULL, 0, 0003, "error parsing FFS file", "FFS file with Guid %s has invalid header checksum", GuidBuffer); - return EFI_ABORTED; - } - - FileLength = GetLength (FileHeader->Size); - - if (FileHeader->Attributes & FFS_ATTRIB_CHECKSUM) { - // - // Calculate file checksum - // - Checksum = CalculateSum8 ((UINT8 *) (FileHeader + 1), FileLength - sizeof (EFI_FFS_FILE_HEADER)); - Checksum = Checksum + FileHeader->IntegrityCheck.Checksum.File; - if (Checksum != 0) { - Error (NULL, 0, 0003, "error parsing FFS file", "FFS file with Guid %s has invalid file checksum", GuidBuffer); - return EFI_ABORTED; - } - } else { - if (FileHeader->IntegrityCheck.Checksum.File != FFS_FIXED_CHECKSUM) { - Error (NULL, 0, 0003, "error parsing FFS file", "FFS file with Guid %s has invalid header checksum -- not set to fixed value of 0xAA", GuidBuffer); - return EFI_ABORTED; - } - } -#if (PI_SPECIFICATION_VERSION < 0x00010000) - // - // Verify tail if present - // - if (FileHeader->Attributes & FFS_ATTRIB_TAIL_PRESENT) { - // - // Verify tail is complement of integrity check field in the header. - // - Tail = (UINT16 *) ((UINTN) FileHeader + GetLength (FileHeader->Size) - sizeof (EFI_FFS_INTEGRITY_CHECK)); - if (FileHeader->IntegrityCheck.TailReference != (UINT16)~(*Tail)) { - Error (NULL, 0, 0003, "error parsing FFS file", \ - "FFS file with Guid %s failed in the integrity check, tail is not the complement of the header field", GuidBuffer); - return EFI_ABORTED; - } - } - #endif - break; - - default: - Error (NULL, 0, 0003, "error parsing FFS file", "FFS file with Guid %s has the invalid/unrecognized file state bits", GuidBuffer); - return EFI_ABORTED; - } - - printf ("File Type: 0x%02X ", FileHeader->Type); - - switch (FileHeader->Type) { - - case EFI_FV_FILETYPE_RAW: - printf ("EFI_FV_FILETYPE_RAW\n"); - break; - - case EFI_FV_FILETYPE_FREEFORM: - printf ("EFI_FV_FILETYPE_FREEFORM\n"); - break; - - case EFI_FV_FILETYPE_SECURITY_CORE: - printf ("EFI_FV_FILETYPE_SECURITY_CORE\n"); - break; - - case EFI_FV_FILETYPE_PEI_CORE: - printf ("EFI_FV_FILETYPE_PEI_CORE\n"); - break; - - case EFI_FV_FILETYPE_DXE_CORE: - printf ("EFI_FV_FILETYPE_DXE_CORE\n"); - break; - - case EFI_FV_FILETYPE_PEIM: - printf ("EFI_FV_FILETYPE_PEIM\n"); - break; - - case EFI_FV_FILETYPE_DRIVER: - printf ("EFI_FV_FILETYPE_DRIVER\n"); - break; - - case EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER: - printf ("EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER\n"); - break; - - case EFI_FV_FILETYPE_APPLICATION: - printf ("EFI_FV_FILETYPE_APPLICATION\n"); - break; - - case EFI_FV_FILETYPE_SMM: - printf ("EFI_FV_FILETYPE_SMM\n"); - break; - - case EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE: - printf ("EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE\n"); - break; - - case EFI_FV_FILETYPE_COMBINED_SMM_DXE: - printf ("EFI_FV_FILETYPE_COMBINED_SMM_DXE\n"); - break; - - case EFI_FV_FILETYPE_SMM_CORE: - printf ("EFI_FV_FILETYPE_SMM_CORE\n"); - break; - - case EFI_FV_FILETYPE_FFS_PAD: - printf ("EFI_FV_FILETYPE_FFS_PAD\n"); - break; - - default: - printf ("\nERROR: Unrecognized file type %X.\n", FileHeader->Type); - return EFI_ABORTED; - break; - } - - switch (FileHeader->Type) { - - case EFI_FV_FILETYPE_ALL: - case EFI_FV_FILETYPE_RAW: - case EFI_FV_FILETYPE_FFS_PAD: - break; - - default: - // - // All other files have sections - // - Status = ParseSection ( - (UINT8 *) ((UINTN) FileHeader + sizeof (EFI_FFS_FILE_HEADER)), - GetLength (FileHeader->Size) - sizeof (EFI_FFS_FILE_HEADER) - ); - if (EFI_ERROR (Status)) { - // - // printf ("ERROR: Parsing the FFS file.\n"); - // - return EFI_ABORTED; - } - break; - } - - return EFI_SUCCESS; -} - -EFI_STATUS -ParseSection ( - IN UINT8 *SectionBuffer, - IN UINT32 BufferLength - ) -/*++ - -Routine Description: - - Parses EFI Sections - -Arguments: - - SectionBuffer - Buffer containing the section to parse. - BufferLength - Length of SectionBuffer - -Returns: - - EFI_SECTION_ERROR - Problem with section parsing. - (a) compression errors - (b) unrecognized section - EFI_UNSUPPORTED - Do not know how to parse the section. - EFI_SUCCESS - Section successfully parsed. - EFI_OUT_OF_RESOURCES - Memory allocation failed. - ---*/ -{ - EFI_SECTION_TYPE Type; - UINT8 *Ptr; - UINT32 SectionLength; - CHAR8 *SectionName; - EFI_STATUS Status; - UINT32 ParsedLength; - UINT8 *CompressedBuffer; - UINT32 CompressedLength; - UINT8 *UncompressedBuffer; - UINT32 UncompressedLength; - UINT8 *ToolOutputBuffer; - UINT32 ToolOutputLength; - UINT8 CompressionType; - UINT32 DstSize; - UINT32 ScratchSize; - UINT8 *ScratchBuffer; - DECOMPRESS_FUNCTION DecompressFunction; - GETINFO_FUNCTION GetInfoFunction; - // CHAR16 *name; - CHAR8 *ExtractionTool; - CHAR8 *ToolInputFile; - CHAR8 *ToolOutputFile; - CHAR8 *SystemCommandFormatString; - CHAR8 *SystemCommand; - - ParsedLength = 0; - while (ParsedLength < BufferLength) { - Ptr = SectionBuffer + ParsedLength; - - SectionLength = GetLength (((EFI_COMMON_SECTION_HEADER *) Ptr)->Size); - Type = ((EFI_COMMON_SECTION_HEADER *) Ptr)->Type; - - // - // This is sort of an odd check, but is necessary because FFS files are - // padded to a QWORD boundary, meaning there is potentially a whole section - // header worth of 0xFF bytes. - // - if (SectionLength == 0xffffff && Type == 0xff) { - ParsedLength += 4; - continue; - } - - SectionName = SectionNameToStr (Type); - printf ("------------------------------------------------------------\n"); - printf (" Type: %s\n Size: 0x%08X\n", SectionName, (unsigned) SectionLength); - free (SectionName); - - switch (Type) { - case EFI_SECTION_RAW: - case EFI_SECTION_PE32: - case EFI_SECTION_PIC: - case EFI_SECTION_TE: - // default is no more information - break; - - case EFI_SECTION_USER_INTERFACE: - // name = &((EFI_USER_INTERFACE_SECTION *) Ptr)->FileNameString; - // printf (" String: %s\n", &name); - break; - - case EFI_SECTION_FIRMWARE_VOLUME_IMAGE: - Status = PrintFvInfo (((EFI_FIRMWARE_VOLUME_IMAGE_SECTION*)Ptr) + 1, TRUE); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 0003, "printing of FV section contents failed", NULL); - return EFI_SECTION_ERROR; - } - break; - - case EFI_SECTION_COMPATIBILITY16: - case EFI_SECTION_FREEFORM_SUBTYPE_GUID: - // - // Section does not contain any further header information. - // - break; - - case EFI_SECTION_PEI_DEPEX: - case EFI_SECTION_DXE_DEPEX: - case EFI_SECTION_SMM_DEPEX: - DumpDepexSection (Ptr, SectionLength); - break; - - case EFI_SECTION_VERSION: - printf (" Build Number: 0x%02X\n", ((EFI_VERSION_SECTION *) Ptr)->BuildNumber); - printf (" Version Strg: %s\n", (char*) ((EFI_VERSION_SECTION *) Ptr)->VersionString); - break; - - case EFI_SECTION_COMPRESSION: - UncompressedBuffer = NULL; - CompressedLength = SectionLength - sizeof (EFI_COMPRESSION_SECTION); - UncompressedLength = ((EFI_COMPRESSION_SECTION *) Ptr)->UncompressedLength; - CompressionType = ((EFI_COMPRESSION_SECTION *) Ptr)->CompressionType; - printf (" Uncompressed Length: 0x%08X\n", (unsigned) UncompressedLength); - - if (CompressionType == EFI_NOT_COMPRESSED) { - printf (" Compression Type: EFI_NOT_COMPRESSED\n"); - if (CompressedLength != UncompressedLength) { - Error ( - NULL, - 0, - 0, - "file is not compressed, but the compressed length does not match the uncompressed length", - NULL - ); - return EFI_SECTION_ERROR; - } - - UncompressedBuffer = Ptr + sizeof (EFI_COMPRESSION_SECTION); - } else if (CompressionType == EFI_STANDARD_COMPRESSION) { - GetInfoFunction = EfiGetInfo; - DecompressFunction = EfiDecompress; - printf (" Compression Type: EFI_STANDARD_COMPRESSION\n"); - - CompressedBuffer = Ptr + sizeof (EFI_COMPRESSION_SECTION); - - Status = GetInfoFunction (CompressedBuffer, CompressedLength, &DstSize, &ScratchSize); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 0003, "error getting compression info from compression section", NULL); - return EFI_SECTION_ERROR; - } - - if (DstSize != UncompressedLength) { - Error (NULL, 0, 0003, "compression error in the compression section", NULL); - return EFI_SECTION_ERROR; - } - - ScratchBuffer = malloc (ScratchSize); - UncompressedBuffer = malloc (UncompressedLength); - if ((ScratchBuffer == NULL) || (UncompressedBuffer == NULL)) { - return EFI_OUT_OF_RESOURCES; - } - Status = DecompressFunction ( - CompressedBuffer, - CompressedLength, - UncompressedBuffer, - UncompressedLength, - ScratchBuffer, - ScratchSize - ); - free (ScratchBuffer); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 0003, "decompress failed", NULL); - free (UncompressedBuffer); - return EFI_SECTION_ERROR; - } - } else { - Error (NULL, 0, 0003, "unrecognized compression type", "type 0x%X", CompressionType); - return EFI_SECTION_ERROR; - } - - Status = ParseSection (UncompressedBuffer, UncompressedLength); - - if (CompressionType == EFI_STANDARD_COMPRESSION) { - // - // We need to deallocate Buffer - // - free (UncompressedBuffer); - } - - if (EFI_ERROR (Status)) { - Error (NULL, 0, 0003, "failed to parse section", NULL); - return EFI_SECTION_ERROR; - } - break; - - case EFI_SECTION_GUID_DEFINED: - printf (" SectionDefinitionGuid: "); - PrintGuid (&((EFI_GUID_DEFINED_SECTION *) Ptr)->SectionDefinitionGuid); - printf ("\n"); - printf (" DataOffset: 0x%04X\n", (unsigned) ((EFI_GUID_DEFINED_SECTION *) Ptr)->DataOffset); - printf (" Attributes: 0x%04X\n", (unsigned) ((EFI_GUID_DEFINED_SECTION *) Ptr)->Attributes); - - ExtractionTool = - LookupGuidedSectionToolPath ( - mParsedGuidedSectionTools, - &((EFI_GUID_DEFINED_SECTION *) Ptr)->SectionDefinitionGuid - ); - - if (ExtractionTool != NULL) { - - ToolInputFile = CloneString (tmpnam (NULL)); - ToolOutputFile = CloneString (tmpnam (NULL)); - - // - // Construction 'system' command string - // - SystemCommandFormatString = "%s -d -o %s %s"; - SystemCommand = malloc ( - strlen (SystemCommandFormatString) + - strlen (ExtractionTool) + - strlen (ToolInputFile) + - strlen (ToolOutputFile) + - 1 - ); - sprintf ( - SystemCommand, - SystemCommandFormatString, - ExtractionTool, - ToolOutputFile, - ToolInputFile - ); - free (ExtractionTool); - - Status = - PutFileImage ( - ToolInputFile, - (CHAR8*) SectionBuffer + ((EFI_GUID_DEFINED_SECTION *) Ptr)->DataOffset, - BufferLength - ((EFI_GUID_DEFINED_SECTION *) Ptr)->DataOffset - ); - - system (SystemCommand); - remove (ToolInputFile); - free (ToolInputFile); - - Status = - GetFileImage ( - ToolOutputFile, - (CHAR8 **)&ToolOutputBuffer, - &ToolOutputLength - ); - remove (ToolOutputFile); - free (ToolOutputFile); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 0004, "unable to read decoded GUIDED section", NULL); - return EFI_SECTION_ERROR; - } - - Status = ParseSection ( - ToolOutputBuffer, - ToolOutputLength - ); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 0003, "parse of decoded GUIDED section failed", NULL); - return EFI_SECTION_ERROR; - } - - // - // Check for CRC32 sections which we can handle internally if needed. - // - } else if (!CompareGuid ( - &((EFI_GUID_DEFINED_SECTION *) Ptr)->SectionDefinitionGuid, - &gEfiCrc32GuidedSectionExtractionProtocolGuid - ) - ) { - // - // CRC32 guided section - // - Status = ParseSection ( - SectionBuffer + ((EFI_GUID_DEFINED_SECTION *) Ptr)->DataOffset, - BufferLength - ((EFI_GUID_DEFINED_SECTION *) Ptr)->DataOffset - ); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 0003, "parse of CRC32 GUIDED section failed", NULL); - return EFI_SECTION_ERROR; - } - } else { - // - // We don't know how to parse it now. - // - Error (NULL, 0, 0003, "Error parsing section", \ - "EFI_SECTION_GUID_DEFINED cannot be parsed at this time. Tool to decode this section should have been defined in GuidedSectionTools.txt (built in the FV directory)."); - return EFI_UNSUPPORTED; - } - break; - - default: - // - // Unknown section, return error - // - Error (NULL, 0, 0003, "unrecognized section type found", "section type = 0x%X", Type); - return EFI_SECTION_ERROR; - } - - ParsedLength += SectionLength; - // - // We make then next section begin on a 4-byte boundary - // - ParsedLength = GetOccupiedSize (ParsedLength, 4); - } - - if (ParsedLength < BufferLength) { - Error (NULL, 0, 0003, "sections do not completely fill the sectioned buffer being parsed", NULL); - return EFI_SECTION_ERROR; - } - - return EFI_SUCCESS; -} - -EFI_STATUS -DumpDepexSection ( - IN UINT8 *Ptr, - IN UINT32 SectionLength - ) -/*++ - -Routine Description: - - GC_TODO: Add function description - -Arguments: - - Ptr - GC_TODO: add argument description - SectionLength - GC_TODO: add argument description - -Returns: - - EFI_SUCCESS - GC_TODO: Add description for return value - ---*/ -{ - UINT8 GuidBuffer[PRINTED_GUID_BUFFER_SIZE]; - - // - // Need at least a section header + data - // - if (SectionLength <= sizeof (EFI_COMMON_SECTION_HEADER)) { - return EFI_SUCCESS; - } - - Ptr += sizeof (EFI_COMMON_SECTION_HEADER); - SectionLength -= sizeof (EFI_COMMON_SECTION_HEADER); - while (SectionLength > 0) { - printf (" "); - switch (*Ptr) { - case EFI_DEP_BEFORE: - printf ("BEFORE\n"); - Ptr++; - SectionLength--; - break; - - case EFI_DEP_AFTER: - printf ("AFTER\n"); - Ptr++; - SectionLength--; - break; - - case EFI_DEP_PUSH: - printf ("PUSH\n "); - PrintGuidToBuffer ((EFI_GUID *) (Ptr + 1), GuidBuffer, sizeof (GuidBuffer), TRUE); - printf ("%s ", GuidBuffer); - PrintGuidName (GuidBuffer); - printf ("\n"); - // - // PrintGuid ((EFI_GUID *)(Ptr + 1)); - // - Ptr += 17; - SectionLength -= 17; - break; - - case EFI_DEP_AND: - printf ("AND\n"); - Ptr++; - SectionLength--; - break; - - case EFI_DEP_OR: - printf ("OR\n"); - Ptr++; - SectionLength--; - break; - - case EFI_DEP_NOT: - printf ("NOT\n"); - Ptr++; - SectionLength--; - break; - - case EFI_DEP_TRUE: - printf ("TRUE\n"); - Ptr++; - SectionLength--; - break; - - case EFI_DEP_FALSE: - printf ("FALSE\n"); - Ptr++; - SectionLength--; - break; - - case EFI_DEP_END: - printf ("END DEPEX\n"); - Ptr++; - SectionLength--; - break; - - case EFI_DEP_SOR: - printf ("SOR\n"); - Ptr++; - SectionLength--; - break; - - default: - printf ("Unrecognized byte in depex: 0x%X\n", *Ptr); - return EFI_SUCCESS; - } - } - - return EFI_SUCCESS; -} - -EFI_STATUS -PrintGuidName ( - IN UINT8 *GuidStr - ) -/*++ - -Routine Description: - - GC_TODO: Add function description - -Arguments: - - GuidStr - GC_TODO: add argument description - -Returns: - - EFI_SUCCESS - GC_TODO: Add description for return value - EFI_INVALID_PARAMETER - GC_TODO: Add description for return value - ---*/ -{ - GUID_TO_BASENAME *GPtr; - // - // If we have a list of guid-to-basenames, then go through the list to - // look for a guid string match. If found, print the basename to stdout, - // otherwise return a failure. - // - GPtr = mGuidBaseNameList; - while (GPtr != NULL) { - if (_stricmp ((CHAR8*) GuidStr, (CHAR8*) GPtr->Guid) == 0) { - printf ("%s", GPtr->BaseName); - return EFI_SUCCESS; - } - - GPtr = GPtr->Next; - } - - return EFI_INVALID_PARAMETER; -} - -EFI_STATUS -ParseGuidBaseNameFile ( - CHAR8 *FileName - ) -/*++ - -Routine Description: - - GC_TODO: Add function description - -Arguments: - - FileName - GC_TODO: add argument description - -Returns: - - EFI_DEVICE_ERROR - GC_TODO: Add description for return value - EFI_OUT_OF_RESOURCES - GC_TODO: Add description for return value - EFI_SUCCESS - GC_TODO: Add description for return value - ---*/ -{ - FILE *Fptr; - CHAR8 Line[MAX_LINE_LEN]; - GUID_TO_BASENAME *GPtr; - - if ((Fptr = fopen (FileName, "r")) == NULL) { - printf ("ERROR: Failed to open input cross-reference file '%s'\n", FileName); - return EFI_DEVICE_ERROR; - } - - while (fgets (Line, sizeof (Line), Fptr) != NULL) { - // - // Allocate space for another guid/basename element - // - GPtr = malloc (sizeof (GUID_TO_BASENAME)); - if (GPtr == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - memset ((char *) GPtr, 0, sizeof (GUID_TO_BASENAME)); - if (sscanf (Line, "%s %s", GPtr->Guid, GPtr->BaseName) == 2) { - GPtr->Next = mGuidBaseNameList; - mGuidBaseNameList = GPtr; - } else { - // - // Some sort of error. Just continue. - // - free (GPtr); - } - } - - fclose (Fptr); - return EFI_SUCCESS; -} - -EFI_STATUS -FreeGuidBaseNameList ( - VOID - ) -/*++ - -Routine Description: - - GC_TODO: Add function description - -Arguments: - - None - -Returns: - - EFI_SUCCESS - GC_TODO: Add description for return value - ---*/ -{ - GUID_TO_BASENAME *Next; - - while (mGuidBaseNameList != NULL) { - Next = mGuidBaseNameList->Next; - free (mGuidBaseNameList); - mGuidBaseNameList = Next; - } - - return EFI_SUCCESS; -} - - -static -VOID -LoadGuidedSectionToolsTxt ( - IN CHAR8* FirmwareVolumeFilename - ) -{ - CHAR8* PeerFilename; - CHAR8* Places[] = { - NULL, - //NULL, - }; - UINTN Index; - - Places[0] = FirmwareVolumeFilename; - //Places[1] = mUtilityFilename; - - mParsedGuidedSectionTools = NULL; - - for (Index = 0; Index < (sizeof(Places)/sizeof(Places[0])); Index++) { - PeerFilename = OsPathPeerFilePath (Places[Index], "GuidedSectionTools.txt"); - //printf("Loading %s...\n", PeerFilename); - if (OsPathExists (PeerFilename)) { - mParsedGuidedSectionTools = ParseGuidedSectionToolsFile (PeerFilename); - } - free (PeerFilename); - if (mParsedGuidedSectionTools != NULL) { - return; - } - } -} - - -void -Usage ( - VOID - ) -/*++ - -Routine Description: - - GC_TODO: Add function description - -Arguments: - - None - -Returns: - - GC_TODO: add return values - ---*/ -{ - // - // Summary usage - // - fprintf (stdout, "Usage: %s [options] \n\n", UTILITY_NAME); - - // - // Copyright declaration - // - fprintf (stdout, "Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.\n\n"); - - // - // Details Option - // - fprintf (stdout, "Options:\n"); - fprintf (stdout, " -x xref, --xref xref\n\ - Parse basename to file-guid cross reference file(s).\n"); - fprintf (stdout, " --offset offset\n\ - Offset of file to start processing FV at.\n"); - fprintf (stdout, " -h, --help\n\ - Show this help message and exit.\n"); - -} - +/** @file + +Copyright (c) 1999 - 2011, Intel Corporation. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + VolInfo.c + +Abstract: + + The tool dumps the contents of a firmware volume + +**/ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "Compress.h" +#include "Decompress.h" +#include "VolInfo.h" +#include "CommonLib.h" +#include "EfiUtilityMsgs.h" +#include "FirmwareVolumeBufferLib.h" +#include "OsPath.h" +#include "ParseGuidedSectionTools.h" +#include "StringFuncs.h" + +// +// Utility global variables +// + +EFI_GUID gEfiCrc32GuidedSectionExtractionProtocolGuid = EFI_CRC32_GUIDED_SECTION_EXTRACTION_PROTOCOL_GUID; + +#define UTILITY_MAJOR_VERSION 0 +#define UTILITY_MINOR_VERSION 82 + +#define UTILITY_NAME "VolInfo" + +#define EFI_SECTION_ERROR EFIERR (100) + +#define MAX_BASENAME_LEN 60 // not good to hardcode, but let's be reasonable + +// +// Structure to keep a list of guid-to-basenames +// +typedef struct _GUID_TO_BASENAME { + struct _GUID_TO_BASENAME *Next; + INT8 Guid[PRINTED_GUID_BUFFER_SIZE]; + INT8 BaseName[MAX_BASENAME_LEN]; +} GUID_TO_BASENAME; + +static GUID_TO_BASENAME *mGuidBaseNameList = NULL; + +// +// Store GUIDed Section guid->tool mapping +// +EFI_HANDLE mParsedGuidedSectionTools = NULL; + +CHAR8* mUtilityFilename = NULL; + +EFI_STATUS +ParseGuidBaseNameFile ( + CHAR8 *FileName + ); + +EFI_STATUS +FreeGuidBaseNameList ( + VOID + ); + +EFI_STATUS +PrintGuidName ( + IN UINT8 *GuidStr + ); + +EFI_STATUS +ParseSection ( + IN UINT8 *SectionBuffer, + IN UINT32 BufferLength + ); + +EFI_STATUS +DumpDepexSection ( + IN UINT8 *Ptr, + IN UINT32 SectionLength + ); + +STATIC +EFI_STATUS +ReadHeader ( + IN FILE *InputFile, + OUT UINT32 *FvSize, + OUT BOOLEAN *ErasePolarity + ); + +STATIC +EFI_STATUS +PrintFileInfo ( + EFI_FIRMWARE_VOLUME_HEADER *FvImage, + EFI_FFS_FILE_HEADER *FileHeader, + BOOLEAN ErasePolarity + ); + +static +EFI_STATUS +PrintFvInfo ( + IN VOID *Fv, + IN BOOLEAN IsChildFv + ); + +static +VOID +LoadGuidedSectionToolsTxt ( + IN CHAR8* FirmwareVolumeFilename + ); + +void +Usage ( + VOID + ); + +int +main ( + int argc, + char *argv[] + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + argc - GC_TODO: add argument description + ] - GC_TODO: add argument description + +Returns: + + GC_TODO: add return values + +--*/ +{ + FILE *InputFile; + int BytesRead; + EFI_FIRMWARE_VOLUME_HEADER *FvImage; + UINT32 FvSize; + EFI_STATUS Status; + int Offset; + BOOLEAN ErasePolarity; + + SetUtilityName (UTILITY_NAME); + // + // Print utility header + // + printf ("%s Tiano Firmware Volume FFS image info. Version %d.%d %s, %s\n", + UTILITY_NAME, + UTILITY_MAJOR_VERSION, + UTILITY_MINOR_VERSION, + __BUILD_VERSION, + __DATE__ + ); + + // + // Save, and then skip filename arg + // + mUtilityFilename = argv[0]; + argc--; + argv++; + + Offset = 0; + + // + // If they specified -x xref guid/basename cross-reference files, process it. + // This will print the basename beside each file guid. To use it, specify + // -x xref_filename to processdsc, then use xref_filename as a parameter + // here. + // + while (argc > 2) { + if ((strcmp(argv[0], "-x") == 0) || (strcmp(argv[0], "--xref") == 0)) { + ParseGuidBaseNameFile (argv[1]); + printf("ParseGuidBaseNameFile: %s\n", argv[1]); + argc -= 2; + argv += 2; + } else if (strcmp(argv[0], "--offset") == 0) { + // + // Hex or decimal? + // + if ((argv[1][0] == '0') && (tolower ((int)argv[1][1]) == 'x')) { + if (sscanf (argv[1], "%x", &Offset) != 1) { + Error (NULL, 0, 1003, "Invalid option value", "Offset = %s", argv[1]); + return GetUtilityStatus (); + } + } else { + if (sscanf (argv[1], "%d", &Offset) != 1) { + Error (NULL, 0, 1003, "Invalid option value", "Offset = %s", argv[1]); + return GetUtilityStatus (); + } + // + // See if they said something like "64K" + // + if (tolower ((int)argv[1][strlen (argv[1]) - 1]) == 'k') { + Offset *= 1024; + } + } + + argc -= 2; + argv += 2; + } else { + Usage (); + return -1; + } + } + // + // Check for proper number of arguments + // + if (argc != 1) { + Usage (); + return -1; + } + // + // Look for help options + // + if ((strcmp(argv[0], "-h") == 0) || (strcmp(argv[0], "--help") == 0) || + (strcmp(argv[0], "-?") == 0) || (strcmp(argv[0], "/?") == 0)) { + Usage(); + return STATUS_ERROR; + } + + // + // Open the file containing the FV + // + InputFile = fopen (argv[0], "rb"); + if (InputFile == NULL) { + Error (NULL, 0, 0001, "Error opening the input file", argv[0]); + return GetUtilityStatus (); + } + // + // Skip over pad bytes if specified. This is used if they prepend 0xff + // data to the FV image binary. + // + if (Offset != 0) { + fseek (InputFile, Offset, SEEK_SET); + } + // + // Determine size of FV + // + Status = ReadHeader (InputFile, &FvSize, &ErasePolarity); + if (EFI_ERROR (Status)) { + Error (NULL, 0, 0003, "error parsing FV image", "%s Header is invalid", argv[0]); + fclose (InputFile); + return GetUtilityStatus (); + } + // + // Allocate a buffer for the FV image + // + FvImage = malloc (FvSize); + if (FvImage == NULL) { + Error (NULL, 0, 4001, "Resource: Memory can't be allocated", NULL); + fclose (InputFile); + return GetUtilityStatus (); + } + // + // Seek to the start of the image, then read the entire FV to the buffer + // + fseek (InputFile, Offset, SEEK_SET); + BytesRead = fread (FvImage, 1, FvSize, InputFile); + fclose (InputFile); + if ((unsigned int) BytesRead != FvSize) { + Error (NULL, 0, 0004, "error reading FvImage from", argv[0]); + free (FvImage); + return GetUtilityStatus (); + } + + LoadGuidedSectionToolsTxt (argv[0]); + + PrintFvInfo (FvImage, FALSE); + + // + // Clean up + // + free (FvImage); + FreeGuidBaseNameList (); + return GetUtilityStatus (); +} + + +static +EFI_STATUS +PrintFvInfo ( + IN VOID *Fv, + IN BOOLEAN IsChildFv + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + Fv - Firmware Volume to print information about + IsChildFv - Flag specifies whether the input FV is a child FV. + +Returns: + + EFI_STATUS + +--*/ +{ + EFI_STATUS Status; + UINTN NumberOfFiles; + BOOLEAN ErasePolarity; + UINTN FvSize; + EFI_FFS_FILE_HEADER *CurrentFile; + UINTN Key; + + Status = FvBufGetSize (Fv, &FvSize); + + NumberOfFiles = 0; + ErasePolarity = + (((EFI_FIRMWARE_VOLUME_HEADER*)Fv)->Attributes & EFI_FVB2_ERASE_POLARITY) ? + TRUE : FALSE; + + // + // Get the first file + // + Key = 0; + Status = FvBufFindNextFile (Fv, &Key, (VOID **) &CurrentFile); + if (EFI_ERROR (Status)) { + Error (NULL, 0, 0003, "error parsing FV image", "cannot find the first file in the FV image"); + return GetUtilityStatus (); + } + // + // Display information about files found + // + while (CurrentFile != NULL) { + // + // Increment the number of files counter + // + NumberOfFiles++; + + // + // Display info about this file + // + Status = PrintFileInfo (Fv, CurrentFile, ErasePolarity); + if (EFI_ERROR (Status)) { + Error (NULL, 0, 0003, "error parsing FV image", "failed to parse a file in the FV"); + return GetUtilityStatus (); + } + // + // Get the next file + // + Status = FvBufFindNextFile (Fv, &Key, (VOID **) &CurrentFile); + if (Status == EFI_NOT_FOUND) { + CurrentFile = NULL; + } else if (EFI_ERROR (Status)) { + Error (NULL, 0, 0003, "error parsing FV image", "cannot find the next file in the FV image"); + return GetUtilityStatus (); + } + } + + if (IsChildFv) { + printf ("There are a total of %d files in the child FV\n", (int) NumberOfFiles); + } else { + printf ("There are a total of %d files in this FV\n", (int) NumberOfFiles); + } + + return EFI_SUCCESS; +} + +UINT32 +GetOccupiedSize ( + IN UINT32 ActualSize, + IN UINT32 Alignment + ) +/*++ + +Routine Description: + + This function returns the next larger size that meets the alignment + requirement specified. + +Arguments: + + ActualSize The size. + Alignment The desired alignment. + +Returns: + + EFI_SUCCESS Function completed successfully. + EFI_ABORTED The function encountered an error. + +--*/ +{ + UINT32 OccupiedSize; + + OccupiedSize = ActualSize; + while ((OccupiedSize & (Alignment - 1)) != 0) { + OccupiedSize++; + } + + return OccupiedSize; +} + +static +CHAR8 * +SectionNameToStr ( + IN EFI_SECTION_TYPE Type + ) +/*++ + +Routine Description: + + Converts EFI Section names to Strings + +Arguments: + + Type - The EFI Section type + +Returns: + + CHAR8* - Pointer to the String containing the section name. + +--*/ +{ + CHAR8 *SectionStr; + CHAR8 *SectionTypeStringTable[] = { + // + // 0X00 + // + "EFI_SECTION_ALL", + // + // 0x01 + // + "EFI_SECTION_COMPRESSION", + // + // 0x02 + // + "EFI_SECTION_GUID_DEFINED", + // + // 0x03 + // + "Unknown section type - Reserved 0x03", + // + // 0x04 + // + "Unknown section type - Reserved 0x04", + // + // 0x05 + // + "Unknown section type - Reserved 0x05", + // + // 0x06 + // + "Unknown section type - Reserved 0x06", + // + // 0x07 + // + "Unknown section type - Reserved 0x07", + // + // 0x08 + // + "Unknown section type - Reserved 0x08", + // + // 0x09 + // + "Unknown section type - Reserved 0x09", + // + // 0x0A + // + "Unknown section type - Reserved 0x0A", + // + // 0x0B + // + "Unknown section type - Reserved 0x0B", + // + // 0x0C + // + "Unknown section type - Reserved 0x0C", + // + // 0x0D + // + "Unknown section type - Reserved 0x0D", + // + // 0x0E + // + "Unknown section type - Reserved 0x0E", + // + // 0x0F + // + "Unknown section type - Reserved 0x0E", + // + // 0x10 + // + "EFI_SECTION_PE32", + // + // 0x11 + // + "EFI_SECTION_PIC", + // + // 0x12 + // + "EFI_SECTION_TE", + // + // 0x13 + // + "EFI_SECTION_DXE_DEPEX", + // + // 0x14 + // + "EFI_SECTION_VERSION", + // + // 0x15 + // + "EFI_SECTION_USER_INTERFACE", + // + // 0x16 + // + "EFI_SECTION_COMPATIBILITY16", + // + // 0x17 + // + "EFI_SECTION_FIRMWARE_VOLUME_IMAGE ", + // + // 0x18 + // + "EFI_SECTION_FREEFORM_SUBTYPE_GUID ", + // + // 0x19 + // + "EFI_SECTION_RAW", + // + // 0x1A + // + "Unknown section type - 0x1A", + // + // 0x1B + // + "EFI_SECTION_PEI_DEPEX", + // + // 0x1C + // + "EFI_SECTION_SMM_DEPEX", + // + // 0x1C+ + // + "Unknown section type - Reserved - beyond last defined section" + }; + + if (Type > EFI_SECTION_LAST_SECTION_TYPE) { + Type = EFI_SECTION_LAST_SECTION_TYPE + 1; + } + + SectionStr = malloc (100); + if (SectionStr == NULL) { + printf ("Error: Out of memory resources.\n"); + return SectionStr; + } + strcpy (SectionStr, SectionTypeStringTable[Type]); + return SectionStr; +} + +STATIC +EFI_STATUS +ReadHeader ( + IN FILE *InputFile, + OUT UINT32 *FvSize, + OUT BOOLEAN *ErasePolarity + ) +/*++ + +Routine Description: + + This function determines the size of the FV and the erase polarity. The + erase polarity is the FALSE value for file state. + +Arguments: + + InputFile The file that contains the FV image. + FvSize The size of the FV. + ErasePolarity The FV erase polarity. + +Returns: + + EFI_SUCCESS Function completed successfully. + EFI_INVALID_PARAMETER A required parameter was NULL or is out of range. + EFI_ABORTED The function encountered an error. + +--*/ +{ + EFI_FIRMWARE_VOLUME_HEADER VolumeHeader; + EFI_FV_BLOCK_MAP_ENTRY BlockMap; + UINTN Signature[2]; + UINTN BytesRead; + UINT32 Size; + + BytesRead = 0; + Size = 0; + // + // Check input parameters + // + if (InputFile == NULL || FvSize == NULL || ErasePolarity == NULL) { + Error (__FILE__, __LINE__, 0, "application error", "invalid parameter to function"); + return EFI_INVALID_PARAMETER; + } + // + // Read the header + // + fread (&VolumeHeader, sizeof (EFI_FIRMWARE_VOLUME_HEADER) - sizeof (EFI_FV_BLOCK_MAP_ENTRY), 1, InputFile); + BytesRead = sizeof (EFI_FIRMWARE_VOLUME_HEADER) - sizeof (EFI_FV_BLOCK_MAP_ENTRY); + Signature[0] = VolumeHeader.Signature; + Signature[1] = 0; + + // + // Print FV header information + // + printf ("Signature: %s (%X)\n", (char *) Signature, (unsigned) VolumeHeader.Signature); + printf ("Attributes: %X\n", (unsigned) VolumeHeader.Attributes); + + if (VolumeHeader.Attributes & EFI_FVB2_READ_DISABLED_CAP) { + printf (" EFI_FVB2_READ_DISABLED_CAP\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_READ_ENABLED_CAP) { + printf (" EFI_FVB2_READ_ENABLED_CAP\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_READ_STATUS) { + printf (" EFI_FVB2_READ_STATUS\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_WRITE_DISABLED_CAP) { + printf (" EFI_FVB2_WRITE_DISABLED_CAP\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_WRITE_ENABLED_CAP) { + printf (" EFI_FVB2_WRITE_ENABLED_CAP\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_WRITE_STATUS) { + printf (" EFI_FVB2_WRITE_STATUS\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_LOCK_CAP) { + printf (" EFI_FVB2_LOCK_CAP\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_LOCK_STATUS) { + printf (" EFI_FVB2_LOCK_STATUS\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_STICKY_WRITE) { + printf (" EFI_FVB2_STICKY_WRITE\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_MEMORY_MAPPED) { + printf (" EFI_FVB2_MEMORY_MAPPED\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_ERASE_POLARITY) { + printf (" EFI_FVB2_ERASE_POLARITY\n"); + *ErasePolarity = TRUE; + } + +#if (PI_SPECIFICATION_VERSION < 0x00010000) + if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT) { + printf (" EFI_FVB2_ALIGNMENT\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_2) { + printf (" EFI_FVB2_ALIGNMENT_2\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_4) { + printf (" EFI_FVB2_ALIGNMENT_4\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_8) { + printf (" EFI_FVB2_ALIGNMENT_8\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_16) { + printf (" EFI_FVB2_ALIGNMENT_16\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_32) { + printf (" EFI_FVB2_ALIGNMENT_32\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_64) { + printf (" EFI_FVB2_ALIGNMENT_64\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_128) { + printf (" EFI_FVB2_ALIGNMENT_128\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_256) { + printf (" EFI_FVB2_ALIGNMENT_256\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_512) { + printf (" EFI_FVB2_ALIGNMENT_512\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_1K) { + printf (" EFI_FVB2_ALIGNMENT_1K\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_2K) { + printf (" EFI_FVB2_ALIGNMENT_2K\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_4K) { + printf (" EFI_FVB2_ALIGNMENT_4K\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_8K) { + printf (" EFI_FVB2_ALIGNMENT_8K\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_16K) { + printf (" EFI_FVB2_ALIGNMENT_16K\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_32K) { + printf (" EFI_FVB2_ALIGNMENT_32K\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_64K) { + printf (" EFI_FVB2_ALIGNMENT_64K\n"); + } + +#else + + if (VolumeHeader.Attributes & EFI_FVB2_READ_LOCK_CAP) { + printf (" EFI_FVB2_READ_LOCK_CAP\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_READ_LOCK_STATUS) { + printf (" EFI_FVB2_READ_LOCK_STATUS\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_WRITE_LOCK_CAP) { + printf (" EFI_FVB2_WRITE_LOCK_CAP\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_WRITE_LOCK_STATUS) { + printf (" EFI_FVB2_WRITE_LOCK_STATUS\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_1) { + printf (" EFI_FVB2_ALIGNMENT_1\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_2) { + printf (" EFI_FVB2_ALIGNMENT_2\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_4) { + printf (" EFI_FVB2_ALIGNMENT_4\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_8) { + printf (" EFI_FVB2_ALIGNMENT_8\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_16) { + printf (" EFI_FVB2_ALIGNMENT_16\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_32) { + printf (" EFI_FVB2_ALIGNMENT_32\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_64) { + printf (" EFI_FVB2_ALIGNMENT_64\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_128) { + printf (" EFI_FVB2_ALIGNMENT_128\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_256) { + printf (" EFI_FVB2_ALIGNMENT_256\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_512) { + printf (" EFI_FVB2_ALIGNMENT_512\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_1K) { + printf (" EFI_FVB2_ALIGNMENT_1K\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_2K) { + printf (" EFI_FVB2_ALIGNMENT_2K\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_4K) { + printf (" EFI_FVB2_ALIGNMENT_4K\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_8K) { + printf (" EFI_FVB2_ALIGNMENT_8K\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_16K) { + printf (" EFI_FVB2_ALIGNMENT_16K\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_32K) { + printf (" EFI_FVB2_ALIGNMENT_32K\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_64K) { + printf (" EFI_FVB2_ALIGNMENT_64K\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_128K) { + printf (" EFI_FVB2_ALIGNMENT_128K\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_256K) { + printf (" EFI_FVB2_ALIGNMENT_256K\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_512K) { + printf (" EFI_FVB2_ALIGNMENT_512K\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_1M) { + printf (" EFI_FVB2_ALIGNMENT_1M\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_2M) { + printf (" EFI_FVB2_ALIGNMENT_2M\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_4M) { + printf (" EFI_FVB2_ALIGNMENT_4M\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_8M) { + printf (" EFI_FVB2_ALIGNMENT_8M\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_16M) { + printf (" EFI_FVB2_ALIGNMENT_16M\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_32M) { + printf (" EFI_FVB2_ALIGNMENT_32M\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_64M) { + printf (" EFI_FVB2_ALIGNMENT_64M\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_128M) { + printf (" EFI_FVB2_ALIGNMENT_128M\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_64M) { + printf (" EFI_FVB2_ALIGNMENT_64M\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_128M) { + printf (" EFI_FVB2_ALIGNMENT_128M\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_256M) { + printf (" EFI_FVB2_ALIGNMENT_256M\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_512M) { + printf (" EFI_FVB2_ALIGNMENT_512M\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_1G) { + printf (" EFI_FVB2_ALIGNMENT_1G\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_2G) { + printf (" EFI_FVB2_ALIGNMENT_2G\n"); + } + +#endif + printf ("Header Length: 0x%08X\n", VolumeHeader.HeaderLength); + printf ("File System ID: "); + PrintGuid (&VolumeHeader.FileSystemGuid); + // + // printf ("\n"); + // + printf ("Revision: 0x%04X\n", VolumeHeader.Revision); + + do { + fread (&BlockMap, sizeof (EFI_FV_BLOCK_MAP_ENTRY), 1, InputFile); + BytesRead += sizeof (EFI_FV_BLOCK_MAP_ENTRY); + + if (BlockMap.NumBlocks != 0) { + printf ("Number of Blocks: 0x%08X\n", (unsigned) BlockMap.NumBlocks); + printf ("Block Length: 0x%08X\n", (unsigned) BlockMap.Length); + Size += BlockMap.NumBlocks * BlockMap.Length; + } + + } while (!(BlockMap.NumBlocks == 0 && BlockMap.Length == 0)); + + if (BytesRead != VolumeHeader.HeaderLength) { + printf ("ERROR: Header length not consistent with Block Maps!\n"); + return EFI_ABORTED; + } + + if (VolumeHeader.FvLength != Size) { + printf ("ERROR: Volume Size not consistant with Block Maps!\n"); + return EFI_ABORTED; + } + + printf ("Total Volume Size: 0x%08X\n", (unsigned) Size); + + *FvSize = Size; + + // + // rewind (InputFile); + // + return EFI_SUCCESS; +} + +STATIC +EFI_STATUS +PrintFileInfo ( + EFI_FIRMWARE_VOLUME_HEADER *FvImage, + EFI_FFS_FILE_HEADER *FileHeader, + BOOLEAN ErasePolarity + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + FvImage - GC_TODO: add argument description + FileHeader - GC_TODO: add argument description + ErasePolarity - GC_TODO: add argument description + +Returns: + + EFI_SUCCESS - GC_TODO: Add description for return value + EFI_ABORTED - GC_TODO: Add description for return value + +--*/ +{ + UINT32 FileLength; + UINT8 FileState; + UINT8 Checksum; + EFI_FFS_FILE_HEADER BlankHeader; + EFI_STATUS Status; + UINT8 GuidBuffer[PRINTED_GUID_BUFFER_SIZE]; +#if (PI_SPECIFICATION_VERSION < 0x00010000) + UINT16 *Tail; +#endif + // + // Check if we have free space + // + if (ErasePolarity) { + memset (&BlankHeader, -1, sizeof (EFI_FFS_FILE_HEADER)); + } else { + memset (&BlankHeader, 0, sizeof (EFI_FFS_FILE_HEADER)); + } + + if (memcmp (&BlankHeader, FileHeader, sizeof (EFI_FFS_FILE_HEADER)) == 0) { + return EFI_SUCCESS; + } + // + // Print file information. + // + printf ("============================================================\n"); + + printf ("File Name: "); + PrintGuidToBuffer (&FileHeader->Name, GuidBuffer, sizeof (GuidBuffer), TRUE); + printf ("%s ", GuidBuffer); + PrintGuidName (GuidBuffer); + printf ("\n"); + + // + // PrintGuid (&FileHeader->Name); + // printf ("\n"); + // + FileLength = GetLength (FileHeader->Size); + printf ("File Offset: 0x%08X\n", (unsigned) ((UINTN) FileHeader - (UINTN) FvImage)); + printf ("File Length: 0x%08X\n", (unsigned) FileLength); + printf ("File Attributes: 0x%02X\n", FileHeader->Attributes); + printf ("File State: 0x%02X\n", FileHeader->State); + + // + // Print file state + // + FileState = GetFileState (ErasePolarity, FileHeader); + + switch (FileState) { + + case EFI_FILE_HEADER_CONSTRUCTION: + printf (" EFI_FILE_HEADER_CONSTRUCTION\n"); + return EFI_SUCCESS; + + case EFI_FILE_HEADER_INVALID: + printf (" EFI_FILE_HEADER_INVALID\n"); + return EFI_SUCCESS; + + case EFI_FILE_HEADER_VALID: + printf (" EFI_FILE_HEADER_VALID\n"); + Checksum = CalculateSum8 ((UINT8 *) FileHeader, sizeof (EFI_FFS_FILE_HEADER)); + Checksum = (UINT8) (Checksum - FileHeader->IntegrityCheck.Checksum.File); + Checksum = (UINT8) (Checksum - FileHeader->State); + if (Checksum != 0) { + printf ("ERROR: Header checksum invalid.\n"); + return EFI_ABORTED; + } + + return EFI_SUCCESS; + + case EFI_FILE_DELETED: + printf (" EFI_FILE_DELETED\n"); + + case EFI_FILE_MARKED_FOR_UPDATE: + printf (" EFI_FILE_MARKED_FOR_UPDATE\n"); + + case EFI_FILE_DATA_VALID: + printf (" EFI_FILE_DATA_VALID\n"); + + // + // Calculate header checksum + // + Checksum = CalculateSum8 ((UINT8 *) FileHeader, sizeof (EFI_FFS_FILE_HEADER)); + Checksum = (UINT8) (Checksum - FileHeader->IntegrityCheck.Checksum.File); + Checksum = (UINT8) (Checksum - FileHeader->State); + if (Checksum != 0) { + Error (NULL, 0, 0003, "error parsing FFS file", "FFS file with Guid %s has invalid header checksum", GuidBuffer); + return EFI_ABORTED; + } + + FileLength = GetLength (FileHeader->Size); + + if (FileHeader->Attributes & FFS_ATTRIB_CHECKSUM) { + // + // Calculate file checksum + // + Checksum = CalculateSum8 ((UINT8 *) (FileHeader + 1), FileLength - sizeof (EFI_FFS_FILE_HEADER)); + Checksum = Checksum + FileHeader->IntegrityCheck.Checksum.File; + if (Checksum != 0) { + Error (NULL, 0, 0003, "error parsing FFS file", "FFS file with Guid %s has invalid file checksum", GuidBuffer); + return EFI_ABORTED; + } + } else { + if (FileHeader->IntegrityCheck.Checksum.File != FFS_FIXED_CHECKSUM) { + Error (NULL, 0, 0003, "error parsing FFS file", "FFS file with Guid %s has invalid header checksum -- not set to fixed value of 0xAA", GuidBuffer); + return EFI_ABORTED; + } + } +#if (PI_SPECIFICATION_VERSION < 0x00010000) + // + // Verify tail if present + // + if (FileHeader->Attributes & FFS_ATTRIB_TAIL_PRESENT) { + // + // Verify tail is complement of integrity check field in the header. + // + Tail = (UINT16 *) ((UINTN) FileHeader + GetLength (FileHeader->Size) - sizeof (EFI_FFS_INTEGRITY_CHECK)); + if (FileHeader->IntegrityCheck.TailReference != (UINT16)~(*Tail)) { + Error (NULL, 0, 0003, "error parsing FFS file", \ + "FFS file with Guid %s failed in the integrity check, tail is not the complement of the header field", GuidBuffer); + return EFI_ABORTED; + } + } + #endif + break; + + default: + Error (NULL, 0, 0003, "error parsing FFS file", "FFS file with Guid %s has the invalid/unrecognized file state bits", GuidBuffer); + return EFI_ABORTED; + } + + printf ("File Type: 0x%02X ", FileHeader->Type); + + switch (FileHeader->Type) { + + case EFI_FV_FILETYPE_RAW: + printf ("EFI_FV_FILETYPE_RAW\n"); + break; + + case EFI_FV_FILETYPE_FREEFORM: + printf ("EFI_FV_FILETYPE_FREEFORM\n"); + break; + + case EFI_FV_FILETYPE_SECURITY_CORE: + printf ("EFI_FV_FILETYPE_SECURITY_CORE\n"); + break; + + case EFI_FV_FILETYPE_PEI_CORE: + printf ("EFI_FV_FILETYPE_PEI_CORE\n"); + break; + + case EFI_FV_FILETYPE_DXE_CORE: + printf ("EFI_FV_FILETYPE_DXE_CORE\n"); + break; + + case EFI_FV_FILETYPE_PEIM: + printf ("EFI_FV_FILETYPE_PEIM\n"); + break; + + case EFI_FV_FILETYPE_DRIVER: + printf ("EFI_FV_FILETYPE_DRIVER\n"); + break; + + case EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER: + printf ("EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER\n"); + break; + + case EFI_FV_FILETYPE_APPLICATION: + printf ("EFI_FV_FILETYPE_APPLICATION\n"); + break; + + case EFI_FV_FILETYPE_SMM: + printf ("EFI_FV_FILETYPE_SMM\n"); + break; + + case EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE: + printf ("EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE\n"); + break; + + case EFI_FV_FILETYPE_COMBINED_SMM_DXE: + printf ("EFI_FV_FILETYPE_COMBINED_SMM_DXE\n"); + break; + + case EFI_FV_FILETYPE_SMM_CORE: + printf ("EFI_FV_FILETYPE_SMM_CORE\n"); + break; + + case EFI_FV_FILETYPE_FFS_PAD: + printf ("EFI_FV_FILETYPE_FFS_PAD\n"); + break; + + default: + printf ("\nERROR: Unrecognized file type %X.\n", FileHeader->Type); + return EFI_ABORTED; + break; + } + + switch (FileHeader->Type) { + + case EFI_FV_FILETYPE_ALL: + case EFI_FV_FILETYPE_RAW: + case EFI_FV_FILETYPE_FFS_PAD: + break; + + default: + // + // All other files have sections + // + Status = ParseSection ( + (UINT8 *) ((UINTN) FileHeader + sizeof (EFI_FFS_FILE_HEADER)), + GetLength (FileHeader->Size) - sizeof (EFI_FFS_FILE_HEADER) + ); + if (EFI_ERROR (Status)) { + // + // printf ("ERROR: Parsing the FFS file.\n"); + // + return EFI_ABORTED; + } + break; + } + + return EFI_SUCCESS; +} + +EFI_STATUS +ParseSection ( + IN UINT8 *SectionBuffer, + IN UINT32 BufferLength + ) +/*++ + +Routine Description: + + Parses EFI Sections + +Arguments: + + SectionBuffer - Buffer containing the section to parse. + BufferLength - Length of SectionBuffer + +Returns: + + EFI_SECTION_ERROR - Problem with section parsing. + (a) compression errors + (b) unrecognized section + EFI_UNSUPPORTED - Do not know how to parse the section. + EFI_SUCCESS - Section successfully parsed. + EFI_OUT_OF_RESOURCES - Memory allocation failed. + +--*/ +{ + EFI_SECTION_TYPE Type; + UINT8 *Ptr; + UINT32 SectionLength; + CHAR8 *SectionName; + EFI_STATUS Status; + UINT32 ParsedLength; + UINT8 *CompressedBuffer; + UINT32 CompressedLength; + UINT8 *UncompressedBuffer; + UINT32 UncompressedLength; + UINT8 *ToolOutputBuffer; + UINT32 ToolOutputLength; + UINT8 CompressionType; + UINT32 DstSize; + UINT32 ScratchSize; + UINT8 *ScratchBuffer; + DECOMPRESS_FUNCTION DecompressFunction; + GETINFO_FUNCTION GetInfoFunction; + // CHAR16 *name; + CHAR8 *ExtractionTool; + CHAR8 *ToolInputFile; + CHAR8 *ToolOutputFile; + CHAR8 *SystemCommandFormatString; + CHAR8 *SystemCommand; + + ParsedLength = 0; + while (ParsedLength < BufferLength) { + Ptr = SectionBuffer + ParsedLength; + + SectionLength = GetLength (((EFI_COMMON_SECTION_HEADER *) Ptr)->Size); + Type = ((EFI_COMMON_SECTION_HEADER *) Ptr)->Type; + + // + // This is sort of an odd check, but is necessary because FFS files are + // padded to a QWORD boundary, meaning there is potentially a whole section + // header worth of 0xFF bytes. + // + if (SectionLength == 0xffffff && Type == 0xff) { + ParsedLength += 4; + continue; + } + + SectionName = SectionNameToStr (Type); + printf ("------------------------------------------------------------\n"); + printf (" Type: %s\n Size: 0x%08X\n", SectionName, (unsigned) SectionLength); + free (SectionName); + + switch (Type) { + case EFI_SECTION_RAW: + case EFI_SECTION_PE32: + case EFI_SECTION_PIC: + case EFI_SECTION_TE: + // default is no more information + break; + + case EFI_SECTION_USER_INTERFACE: + // name = &((EFI_USER_INTERFACE_SECTION *) Ptr)->FileNameString; + // printf (" String: %s\n", &name); + break; + + case EFI_SECTION_FIRMWARE_VOLUME_IMAGE: + Status = PrintFvInfo (((EFI_FIRMWARE_VOLUME_IMAGE_SECTION*)Ptr) + 1, TRUE); + if (EFI_ERROR (Status)) { + Error (NULL, 0, 0003, "printing of FV section contents failed", NULL); + return EFI_SECTION_ERROR; + } + break; + + case EFI_SECTION_COMPATIBILITY16: + case EFI_SECTION_FREEFORM_SUBTYPE_GUID: + // + // Section does not contain any further header information. + // + break; + + case EFI_SECTION_PEI_DEPEX: + case EFI_SECTION_DXE_DEPEX: + case EFI_SECTION_SMM_DEPEX: + DumpDepexSection (Ptr, SectionLength); + break; + + case EFI_SECTION_VERSION: + printf (" Build Number: 0x%02X\n", ((EFI_VERSION_SECTION *) Ptr)->BuildNumber); + printf (" Version Strg: %s\n", (char*) ((EFI_VERSION_SECTION *) Ptr)->VersionString); + break; + + case EFI_SECTION_COMPRESSION: + UncompressedBuffer = NULL; + CompressedLength = SectionLength - sizeof (EFI_COMPRESSION_SECTION); + UncompressedLength = ((EFI_COMPRESSION_SECTION *) Ptr)->UncompressedLength; + CompressionType = ((EFI_COMPRESSION_SECTION *) Ptr)->CompressionType; + printf (" Uncompressed Length: 0x%08X\n", (unsigned) UncompressedLength); + + if (CompressionType == EFI_NOT_COMPRESSED) { + printf (" Compression Type: EFI_NOT_COMPRESSED\n"); + if (CompressedLength != UncompressedLength) { + Error ( + NULL, + 0, + 0, + "file is not compressed, but the compressed length does not match the uncompressed length", + NULL + ); + return EFI_SECTION_ERROR; + } + + UncompressedBuffer = Ptr + sizeof (EFI_COMPRESSION_SECTION); + } else if (CompressionType == EFI_STANDARD_COMPRESSION) { + GetInfoFunction = EfiGetInfo; + DecompressFunction = EfiDecompress; + printf (" Compression Type: EFI_STANDARD_COMPRESSION\n"); + + CompressedBuffer = Ptr + sizeof (EFI_COMPRESSION_SECTION); + + Status = GetInfoFunction (CompressedBuffer, CompressedLength, &DstSize, &ScratchSize); + if (EFI_ERROR (Status)) { + Error (NULL, 0, 0003, "error getting compression info from compression section", NULL); + return EFI_SECTION_ERROR; + } + + if (DstSize != UncompressedLength) { + Error (NULL, 0, 0003, "compression error in the compression section", NULL); + return EFI_SECTION_ERROR; + } + + ScratchBuffer = malloc (ScratchSize); + UncompressedBuffer = malloc (UncompressedLength); + if ((ScratchBuffer == NULL) || (UncompressedBuffer == NULL)) { + return EFI_OUT_OF_RESOURCES; + } + Status = DecompressFunction ( + CompressedBuffer, + CompressedLength, + UncompressedBuffer, + UncompressedLength, + ScratchBuffer, + ScratchSize + ); + free (ScratchBuffer); + if (EFI_ERROR (Status)) { + Error (NULL, 0, 0003, "decompress failed", NULL); + free (UncompressedBuffer); + return EFI_SECTION_ERROR; + } + } else { + Error (NULL, 0, 0003, "unrecognized compression type", "type 0x%X", CompressionType); + return EFI_SECTION_ERROR; + } + + Status = ParseSection (UncompressedBuffer, UncompressedLength); + + if (CompressionType == EFI_STANDARD_COMPRESSION) { + // + // We need to deallocate Buffer + // + free (UncompressedBuffer); + } + + if (EFI_ERROR (Status)) { + Error (NULL, 0, 0003, "failed to parse section", NULL); + return EFI_SECTION_ERROR; + } + break; + + case EFI_SECTION_GUID_DEFINED: + printf (" SectionDefinitionGuid: "); + PrintGuid (&((EFI_GUID_DEFINED_SECTION *) Ptr)->SectionDefinitionGuid); + printf ("\n"); + printf (" DataOffset: 0x%04X\n", (unsigned) ((EFI_GUID_DEFINED_SECTION *) Ptr)->DataOffset); + printf (" Attributes: 0x%04X\n", (unsigned) ((EFI_GUID_DEFINED_SECTION *) Ptr)->Attributes); + + ExtractionTool = + LookupGuidedSectionToolPath ( + mParsedGuidedSectionTools, + &((EFI_GUID_DEFINED_SECTION *) Ptr)->SectionDefinitionGuid + ); + + if (ExtractionTool != NULL) { + + ToolInputFile = CloneString (tmpnam (NULL)); + ToolOutputFile = CloneString (tmpnam (NULL)); + + // + // Construction 'system' command string + // + SystemCommandFormatString = "%s -d -o %s %s"; + SystemCommand = malloc ( + strlen (SystemCommandFormatString) + + strlen (ExtractionTool) + + strlen (ToolInputFile) + + strlen (ToolOutputFile) + + 1 + ); + sprintf ( + SystemCommand, + SystemCommandFormatString, + ExtractionTool, + ToolOutputFile, + ToolInputFile + ); + free (ExtractionTool); + + Status = + PutFileImage ( + ToolInputFile, + (CHAR8*) SectionBuffer + ((EFI_GUID_DEFINED_SECTION *) Ptr)->DataOffset, + BufferLength - ((EFI_GUID_DEFINED_SECTION *) Ptr)->DataOffset + ); + + system (SystemCommand); + remove (ToolInputFile); + free (ToolInputFile); + + Status = + GetFileImage ( + ToolOutputFile, + (CHAR8 **)&ToolOutputBuffer, + &ToolOutputLength + ); + remove (ToolOutputFile); + free (ToolOutputFile); + if (EFI_ERROR (Status)) { + Error (NULL, 0, 0004, "unable to read decoded GUIDED section", NULL); + return EFI_SECTION_ERROR; + } + + Status = ParseSection ( + ToolOutputBuffer, + ToolOutputLength + ); + if (EFI_ERROR (Status)) { + Error (NULL, 0, 0003, "parse of decoded GUIDED section failed", NULL); + return EFI_SECTION_ERROR; + } + + // + // Check for CRC32 sections which we can handle internally if needed. + // + } else if (!CompareGuid ( + &((EFI_GUID_DEFINED_SECTION *) Ptr)->SectionDefinitionGuid, + &gEfiCrc32GuidedSectionExtractionProtocolGuid + ) + ) { + // + // CRC32 guided section + // + Status = ParseSection ( + SectionBuffer + ((EFI_GUID_DEFINED_SECTION *) Ptr)->DataOffset, + BufferLength - ((EFI_GUID_DEFINED_SECTION *) Ptr)->DataOffset + ); + if (EFI_ERROR (Status)) { + Error (NULL, 0, 0003, "parse of CRC32 GUIDED section failed", NULL); + return EFI_SECTION_ERROR; + } + } else { + // + // We don't know how to parse it now. + // + Error (NULL, 0, 0003, "Error parsing section", \ + "EFI_SECTION_GUID_DEFINED cannot be parsed at this time. Tool to decode this section should have been defined in GuidedSectionTools.txt (built in the FV directory)."); + return EFI_UNSUPPORTED; + } + break; + + default: + // + // Unknown section, return error + // + Error (NULL, 0, 0003, "unrecognized section type found", "section type = 0x%X", Type); + return EFI_SECTION_ERROR; + } + + ParsedLength += SectionLength; + // + // We make then next section begin on a 4-byte boundary + // + ParsedLength = GetOccupiedSize (ParsedLength, 4); + } + + if (ParsedLength < BufferLength) { + Error (NULL, 0, 0003, "sections do not completely fill the sectioned buffer being parsed", NULL); + return EFI_SECTION_ERROR; + } + + return EFI_SUCCESS; +} + +EFI_STATUS +DumpDepexSection ( + IN UINT8 *Ptr, + IN UINT32 SectionLength + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + Ptr - GC_TODO: add argument description + SectionLength - GC_TODO: add argument description + +Returns: + + EFI_SUCCESS - GC_TODO: Add description for return value + +--*/ +{ + UINT8 GuidBuffer[PRINTED_GUID_BUFFER_SIZE]; + + // + // Need at least a section header + data + // + if (SectionLength <= sizeof (EFI_COMMON_SECTION_HEADER)) { + return EFI_SUCCESS; + } + + Ptr += sizeof (EFI_COMMON_SECTION_HEADER); + SectionLength -= sizeof (EFI_COMMON_SECTION_HEADER); + while (SectionLength > 0) { + printf (" "); + switch (*Ptr) { + case EFI_DEP_BEFORE: + printf ("BEFORE\n"); + Ptr++; + SectionLength--; + break; + + case EFI_DEP_AFTER: + printf ("AFTER\n"); + Ptr++; + SectionLength--; + break; + + case EFI_DEP_PUSH: + printf ("PUSH\n "); + PrintGuidToBuffer ((EFI_GUID *) (Ptr + 1), GuidBuffer, sizeof (GuidBuffer), TRUE); + printf ("%s ", GuidBuffer); + PrintGuidName (GuidBuffer); + printf ("\n"); + // + // PrintGuid ((EFI_GUID *)(Ptr + 1)); + // + Ptr += 17; + SectionLength -= 17; + break; + + case EFI_DEP_AND: + printf ("AND\n"); + Ptr++; + SectionLength--; + break; + + case EFI_DEP_OR: + printf ("OR\n"); + Ptr++; + SectionLength--; + break; + + case EFI_DEP_NOT: + printf ("NOT\n"); + Ptr++; + SectionLength--; + break; + + case EFI_DEP_TRUE: + printf ("TRUE\n"); + Ptr++; + SectionLength--; + break; + + case EFI_DEP_FALSE: + printf ("FALSE\n"); + Ptr++; + SectionLength--; + break; + + case EFI_DEP_END: + printf ("END DEPEX\n"); + Ptr++; + SectionLength--; + break; + + case EFI_DEP_SOR: + printf ("SOR\n"); + Ptr++; + SectionLength--; + break; + + default: + printf ("Unrecognized byte in depex: 0x%X\n", *Ptr); + return EFI_SUCCESS; + } + } + + return EFI_SUCCESS; +} + +EFI_STATUS +PrintGuidName ( + IN UINT8 *GuidStr + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + GuidStr - GC_TODO: add argument description + +Returns: + + EFI_SUCCESS - GC_TODO: Add description for return value + EFI_INVALID_PARAMETER - GC_TODO: Add description for return value + +--*/ +{ + GUID_TO_BASENAME *GPtr; + // + // If we have a list of guid-to-basenames, then go through the list to + // look for a guid string match. If found, print the basename to stdout, + // otherwise return a failure. + // + GPtr = mGuidBaseNameList; + while (GPtr != NULL) { + if (_stricmp ((CHAR8*) GuidStr, (CHAR8*) GPtr->Guid) == 0) { + printf ("%s", GPtr->BaseName); + return EFI_SUCCESS; + } + + GPtr = GPtr->Next; + } + + return EFI_INVALID_PARAMETER; +} + +EFI_STATUS +ParseGuidBaseNameFile ( + CHAR8 *FileName + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + FileName - GC_TODO: add argument description + +Returns: + + EFI_DEVICE_ERROR - GC_TODO: Add description for return value + EFI_OUT_OF_RESOURCES - GC_TODO: Add description for return value + EFI_SUCCESS - GC_TODO: Add description for return value + +--*/ +{ + FILE *Fptr; + CHAR8 Line[MAX_LINE_LEN]; + GUID_TO_BASENAME *GPtr; + + if ((Fptr = fopen (FileName, "r")) == NULL) { + printf ("ERROR: Failed to open input cross-reference file '%s'\n", FileName); + return EFI_DEVICE_ERROR; + } + + while (fgets (Line, sizeof (Line), Fptr) != NULL) { + // + // Allocate space for another guid/basename element + // + GPtr = malloc (sizeof (GUID_TO_BASENAME)); + if (GPtr == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + memset ((char *) GPtr, 0, sizeof (GUID_TO_BASENAME)); + if (sscanf (Line, "%s %s", GPtr->Guid, GPtr->BaseName) == 2) { + GPtr->Next = mGuidBaseNameList; + mGuidBaseNameList = GPtr; + } else { + // + // Some sort of error. Just continue. + // + free (GPtr); + } + } + + fclose (Fptr); + return EFI_SUCCESS; +} + +EFI_STATUS +FreeGuidBaseNameList ( + VOID + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + None + +Returns: + + EFI_SUCCESS - GC_TODO: Add description for return value + +--*/ +{ + GUID_TO_BASENAME *Next; + + while (mGuidBaseNameList != NULL) { + Next = mGuidBaseNameList->Next; + free (mGuidBaseNameList); + mGuidBaseNameList = Next; + } + + return EFI_SUCCESS; +} + + +static +VOID +LoadGuidedSectionToolsTxt ( + IN CHAR8* FirmwareVolumeFilename + ) +{ + CHAR8* PeerFilename; + CHAR8* Places[] = { + NULL, + //NULL, + }; + UINTN Index; + + Places[0] = FirmwareVolumeFilename; + //Places[1] = mUtilityFilename; + + mParsedGuidedSectionTools = NULL; + + for (Index = 0; Index < (sizeof(Places)/sizeof(Places[0])); Index++) { + PeerFilename = OsPathPeerFilePath (Places[Index], "GuidedSectionTools.txt"); + //printf("Loading %s...\n", PeerFilename); + if (OsPathExists (PeerFilename)) { + mParsedGuidedSectionTools = ParseGuidedSectionToolsFile (PeerFilename); + } + free (PeerFilename); + if (mParsedGuidedSectionTools != NULL) { + return; + } + } +} + + +void +Usage ( + VOID + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + None + +Returns: + + GC_TODO: add return values + +--*/ +{ + // + // Summary usage + // + fprintf (stdout, "Usage: %s [options] \n\n", UTILITY_NAME); + + // + // Copyright declaration + // + fprintf (stdout, "Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.\n\n"); + + // + // Details Option + // + fprintf (stdout, "Options:\n"); + fprintf (stdout, " -x xref, --xref xref\n\ + Parse basename to file-guid cross reference file(s).\n"); + fprintf (stdout, " --offset offset\n\ + Offset of file to start processing FV at.\n"); + fprintf (stdout, " -h, --help\n\ + Show this help message and exit.\n"); + +} + diff --git a/BaseTools/Source/C/VolInfo/VolInfo.h b/BaseTools/Source/C/VolInfo/VolInfo.h index c2831293ba..0e2d181911 100644 --- a/BaseTools/Source/C/VolInfo/VolInfo.h +++ b/BaseTools/Source/C/VolInfo/VolInfo.h @@ -1,41 +1,41 @@ -/** @file - -Copyright (c) 1999 - 2008, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - VolInfo.c - -Abstract: - - Local Definitions for the VolInfo utility - -**/ - -#ifndef _VOLINFO_H_ -#define _VOLINFO_H_ 1 - -#define PI_SPECIFICATION_VERSION 0x00010000 - -#define EFI_DEP_BEFORE 0x00 -#define EFI_DEP_AFTER 0x01 -#define EFI_DEP_PUSH 0x02 -#define EFI_DEP_AND 0x03 -#define EFI_DEP_OR 0x04 -#define EFI_DEP_NOT 0x05 -#define EFI_DEP_TRUE 0x06 -#define EFI_DEP_FALSE 0x07 -#define EFI_DEP_END 0x08 -#define EFI_DEP_SOR 0x09 - -#define EFI_SECTION_LAST_LEAF_SECTION_TYPE 0x1B -#define EFI_SECTION_LAST_SECTION_TYPE 0x1B - -#endif +/** @file + +Copyright (c) 1999 - 2008, Intel Corporation. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + VolInfo.c + +Abstract: + + Local Definitions for the VolInfo utility + +**/ + +#ifndef _VOLINFO_H_ +#define _VOLINFO_H_ 1 + +#define PI_SPECIFICATION_VERSION 0x00010000 + +#define EFI_DEP_BEFORE 0x00 +#define EFI_DEP_AFTER 0x01 +#define EFI_DEP_PUSH 0x02 +#define EFI_DEP_AND 0x03 +#define EFI_DEP_OR 0x04 +#define EFI_DEP_NOT 0x05 +#define EFI_DEP_TRUE 0x06 +#define EFI_DEP_FALSE 0x07 +#define EFI_DEP_END 0x08 +#define EFI_DEP_SOR 0x09 + +#define EFI_SECTION_LAST_LEAF_SECTION_TYPE 0x1B +#define EFI_SECTION_LAST_SECTION_TYPE 0x1B + +#endif -- cgit v1.2.3