/** @file
-Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials are licensed and made available
under the terms and conditions of the BSD License which accompanies this
EFI_IMAGE_DOS_HEADER *DosHdr;
EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr;
UINT32 CoffEntry;
+ UINT32 SectionCount;
CoffEntry = 0;
mCoffOffset = 0;
//
mCoffOffset = CoffAlign(mCoffOffset);
mTextOffset = mCoffOffset;
+ SectionCount = 0;
for (i = 0; i < mEhdr->e_shnum; i++) {
Elf_Shdr *shdr = GetShdrByIndex(i);
if (IsTextShdr(shdr)) {
}
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 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)) {
}
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.
//
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_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;
return TRUE;
}
+UINTN gMovwOffset = 0;
+
STATIC
VOID
WriteRelocations32 (
UINT8 *Targ;
Elf32_Phdr *DynamicSegment;
Elf32_Phdr *TargetSegment;
- Elf_Sym *Sym;
- Elf_Shdr *SymtabShdr;
- UINT8 *Symtab;
-
for (Index = 0, FoundRelocations = FALSE; Index < mEhdr->e_shnum; Index++) {
Elf_Shdr *RelShdr = GetShdrByIndex(Index);
if (IsTextShdr(SecShdr) || IsDataShdr(SecShdr)) {
UINT32 RelIdx;
- SymtabShdr = GetShdrByIndex (RelShdr->sh_link);
- Symtab = (UINT8*)mEhdr + SymtabShdr->sh_offset;
FoundRelocations = TRUE;
for (RelIdx = 0; RelIdx < RelShdr->sh_size; RelIdx += RelShdr->sh_entsize) {
Elf_Rel *Rel = (Elf_Rel *)((UINT8*)mEhdr + RelShdr->sh_offset + RelIdx);
- Elf_Shdr *SymShdr;
- Sym = (Elf_Sym *)(Symtab + ELF_R_SYM(Rel->r_info) * SymtabShdr->sh_entsize);
- SymShdr = GetShdrByIndex (Sym->st_shndx);
-
if (mEhdr->e_machine == EM_386) {
switch (ELF_R_TYPE(Rel->r_info)) {
case R_386_NONE:
}
} else if (mEhdr->e_machine == EM_ARM) {
switch (ELF32_R_TYPE(Rel->r_info)) {
- case R_ARM_RBASE:
+ 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;
CoffAddFixup (
mCoffSectionsOffset[RelShdr->sh_info]
+ (Rel->r_offset - SecShdr->sh_addr),
- EFI_IMAGE_REL_BASED_ARM_THUMB_MOVW
+ 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:
- CoffAddFixup (
- mCoffSectionsOffset[RelShdr->sh_info]
- + (Rel->r_offset - SecShdr->sh_addr),
- EFI_IMAGE_REL_BASED_ARM_THUMB_MOVT
- );
-
- // The relocation entry needs to contain the lower 16-bits so we can do math
- CoffAddFixupEntry ((UINT16)(Sym->st_value - SymShdr->sh_addr + mCoffSectionsOffset[Sym->st_shndx]));
+ 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: