Index: ELF/Target.cpp =================================================================== --- ELF/Target.cpp +++ ELF/Target.cpp @@ -329,6 +329,7 @@ return R_TLSLD; case R_386_PLT32: return R_PLT_PC; + case R_386_PC16: case R_386_PC32: return R_PC; case R_386_GOTPC: @@ -437,6 +438,8 @@ switch (Type) { default: return 0; + case R_386_16: + case R_386_PC16: case R_386_32: case R_386_GOT32: case R_386_GOT32X: @@ -451,6 +454,12 @@ void X86TargetInfo::relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const { + // R_386_PC16 and R_386_16 are not part of the current i386 psABI. They are + // used by 16-bit x86 objects, like boot loaders. + if (Type == R_386_16 || Type == R_386_PC16) { + write16le(Loc, Val); + return; + } checkInt<32>(Loc, Val, Type); write32le(Loc, Val); } Index: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -180,14 +180,20 @@ if (Config->Relocatable) { assignFileOffsets(); } else { - Phdrs = Script::X->hasPhdrsCommands() ? Script::X->createPhdrs() - : createPhdrs(); - addPtArmExid(Phdrs); - fixHeaders(); + // Binary output does not have PHDRS. + if (!Config->OFormatBinary) { + Phdrs = Script::X->hasPhdrsCommands() + ? Script::X->createPhdrs() + : createPhdrs(); + addPtArmExid(Phdrs); + fixHeaders(); + } + if (ScriptConfig->HasSections) { Script::X->assignAddresses(Phdrs); } else { - fixSectionAlignments(); + if (!Config->OMagic) + fixSectionAlignments(); assignAddresses(); } Index: test/ELF/oformat-binary-ttext.s =================================================================== --- test/ELF/oformat-binary-ttext.s +++ test/ELF/oformat-binary-ttext.s @@ -0,0 +1,18 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t + +# RUN: ld.lld -N -Ttext 0x100 -o %t.out %t --oformat binary +# RUN: od -t x1 -v %t.out | FileCheck %s --check-prefix=BIN + +# BIN: 0000000 90 00 00 00 00 00 00 00 +# BIN-NEXT: 0000010 +# BIN-NOT: 0000020 + +## The same but without OMAGIC. +# RUN: ld.lld -Ttext 0x100 -o %t.out %t --oformat binary +# RUN: od -t x1 -v %t.out | FileCheck %s --check-prefix=BIN + +.text +.globl _start +_start: + nop