diff options
author | Saleem Abdulrasool <compnerd@compnerd.org> | 2014-04-27 03:48:22 +0000 |
---|---|---|
committer | Saleem Abdulrasool <compnerd@compnerd.org> | 2014-04-27 03:48:22 +0000 |
commit | 84b952b6777a22bb27e6ef7fb01a03f8e2c978a8 (patch) | |
tree | 70413c88387aaf8e8fe47f925eabf31a0dccc182 /llvm/lib/MC | |
parent | a8b1f7204b7c01616ebb444b719a6411e9648442 (diff) | |
download | bcm5719-llvm-84b952b6777a22bb27e6ef7fb01a03f8e2c978a8.tar.gz bcm5719-llvm-84b952b6777a22bb27e6ef7fb01a03f8e2c978a8.zip |
Add WoA object file emission support
Introduce support for WoA PE/COFF object file emission from LLVM. Add the new
target specific PE/COFF Streamer (ARMWinCOFFStreamer) that handles the ARM
specific behaviour of PE/COFF object emission. ARM exception information is not
yet emitted and is a TODO item.
The ARM specific object writer (ARMWinCOFFObjectWriter) handles the ARM specific
relocation handling in conjunction with the WinCOFFObjectWriter in the MC layer.
The MC layer needs to be updated to deal with the relocation adjustments.
Branch relocations are adjusted by 4 bytes (unlikely their ELF counterparts).
Minor tweaks to switch multiple conditional checks into equivalent switch
statements. The ObjectFileInfo is updated to relax the object file setup for
Windows COFF. Move the architecture checks into an assertion. Windows COFF is
currently only supported on x86, x86_64, and ARM (thumb). Rather than
defaulting to ELF, we will refuse to generate an object file. This is better
though as you do not get an (arbitrary) object file which is different from the
request.
llvm-svn: 207345
Diffstat (limited to 'llvm/lib/MC')
-rw-r--r-- | llvm/lib/MC/MCObjectFileInfo.cpp | 6 | ||||
-rw-r--r-- | llvm/lib/MC/WinCOFFObjectWriter.cpp | 38 |
2 files changed, 42 insertions, 2 deletions
diff --git a/llvm/lib/MC/MCObjectFileInfo.cpp b/llvm/lib/MC/MCObjectFileInfo.cpp index 26d2b61d589..efdf677fbb8 100644 --- a/llvm/lib/MC/MCObjectFileInfo.cpp +++ b/llvm/lib/MC/MCObjectFileInfo.cpp @@ -780,8 +780,10 @@ void MCObjectFileInfo::InitMCObjectFileInfo(StringRef TT, Reloc::Model relocm, (T.isOSDarwin() || T.isOSBinFormatMachO())) { Env = IsMachO; InitMachOMCObjectFileInfo(T); - } else if ((Arch == Triple::x86 || Arch == Triple::x86_64) && - T.getObjectFormat() != Triple::ELF && T.isOSWindows()) { + } else if (T.isOSWindows() && T.getObjectFormat() == Triple::COFF) { + assert((Arch == Triple::x86 || Arch == Triple::x86_64 || + Arch == Triple::arm || Arch == Triple::thumb) && + "unsupported Windows COFF architecture"); Env = IsCOFF; InitCOFFMCObjectFileInfo(T); } else { diff --git a/llvm/lib/MC/WinCOFFObjectWriter.cpp b/llvm/lib/MC/WinCOFFObjectWriter.cpp index 60e046ec4fe..5a562ae0efa 100644 --- a/llvm/lib/MC/WinCOFFObjectWriter.cpp +++ b/llvm/lib/MC/WinCOFFObjectWriter.cpp @@ -761,6 +761,44 @@ void WinCOFFObjectWriter::RecordRelocation(const MCAssembler &Asm, Reloc.Data.Type == COFF::IMAGE_REL_I386_REL32)) FixedValue += 4; + if (Header.Machine == COFF::IMAGE_FILE_MACHINE_ARMNT) { + switch (Reloc.Data.Type) { + case COFF::IMAGE_REL_ARM_ABSOLUTE: + case COFF::IMAGE_REL_ARM_ADDR32: + case COFF::IMAGE_REL_ARM_ADDR32NB: + case COFF::IMAGE_REL_ARM_TOKEN: + case COFF::IMAGE_REL_ARM_SECTION: + case COFF::IMAGE_REL_ARM_SECREL: + break; + case COFF::IMAGE_REL_ARM_BRANCH11: + case COFF::IMAGE_REL_ARM_BLX11: + // IMAGE_REL_ARM_BRANCH11 and IMAGE_REL_ARM_BLX11 are only used for + // pre-ARMv7, which implicitly rules it out of ARMNT (it would be valid + // for Windows CE). + case COFF::IMAGE_REL_ARM_BRANCH24: + case COFF::IMAGE_REL_ARM_BLX24: + case COFF::IMAGE_REL_ARM_MOV32A: + // IMAGE_REL_ARM_BRANCH24, IMAGE_REL_ARM_BLX24, IMAGE_REL_ARM_MOV32A are + // only used for ARM mode code, which is documented as being unsupported + // by Windows on ARM. Emperical proof indicates that masm is able to + // generate the relocations however the rest of the MSVC toolchain is + // unable to handle it. + llvm_unreachable("unsupported relocation"); + break; + case COFF::IMAGE_REL_ARM_MOV32T: + break; + case COFF::IMAGE_REL_ARM_BRANCH20T: + case COFF::IMAGE_REL_ARM_BRANCH24T: + case COFF::IMAGE_REL_ARM_BLX23T: + // IMAGE_REL_BRANCH20T, IMAGE_REL_ARM_BRANCH24T, IMAGE_REL_ARM_BLX23T all + // perform a 4 byte adjustment to the relocation. Relative branches are + // offset by 4 on ARM, however, because there is no RELA relocations, all + // branches are offset by 4. + FixedValue = FixedValue + 4; + break; + } + } + coff_section->Relocations.push_back(Reloc); } |