Index: llvm/lib/ObjectYAML/ELFEmitter.cpp
===================================================================
--- llvm/lib/ObjectYAML/ELFEmitter.cpp
+++ llvm/lib/ObjectYAML/ELFEmitter.cpp
@@ -754,18 +754,21 @@
     Elf_Phdr &PHeader = PHeaders[PhdrIdx++];
     std::vector<Fragment> Fragments = getPhdrFragments(YamlPhdr, SHeaders);
 
-    if (YamlPhdr.Offset) {
-      PHeader.p_offset = *YamlPhdr.Offset;
-    } else {
-      if (YamlPhdr.Sections.size())
-        PHeader.p_offset = UINT32_MAX;
-      else
-        PHeader.p_offset = 0;
+    uint64_t PhdrFileOffset = Fragments.empty() ? 0 : UINT64_MAX;
+    // Find the minimum section file offset.
+    for (const Fragment &F : Fragments)
+      PhdrFileOffset = std::min(PhdrFileOffset, F.Offset);
 
-      // Find the minimum offset for the program header.
-      for (const Fragment &F : Fragments)
-        PHeader.p_offset = std::min((uint64_t)PHeader.p_offset, F.Offset);
+    if (YamlPhdr.Offset) {
+      if (!Fragments.empty() && *YamlPhdr.Offset > PhdrFileOffset)
+        reportError("the 'Offset' specified for the segment with index " +
+                    Twine(PhdrIdx) +
+                    " must be less or equal than the minimal file offset of a "
+                    "section included into it (0x" +
+                    Twine::utohexstr(PhdrFileOffset) + ")");
+      PhdrFileOffset = *YamlPhdr.Offset;
     }
+    PHeader.p_offset = PhdrFileOffset;
 
     // Find the maximum offset of the end of a section in order to set p_filesz
     // and p_memsz. When setting p_filesz, trailing SHT_NOBITS sections are not
Index: llvm/test/Object/invalid.test
===================================================================
--- llvm/test/Object/invalid.test
+++ llvm/test/Object/invalid.test
@@ -485,17 +485,9 @@
   Data:    ELFDATA2LSB
   Type:    ET_EXEC
   Machine: EM_X86_64
-Sections:
-  - Name: .dynamic
-    Type: SHT_DYNAMIC
-    Entries:
-      - Tag:   DT_NULL
-        Value: 0
 ProgramHeaders:
   - Type:   PT_DYNAMIC
     Offset: 0xffff0000
-    Sections:
-      - Section: .dynamic
 
 ## PT_DYNAMIC's p_filesz field is so large that p_offset + p_filesz is larger
 ## than the object size. Check llvm-readobj reports it.
Index: llvm/test/tools/llvm-objcopy/ELF/invalid-p_filesz-p_offset.test
===================================================================
--- llvm/test/tools/llvm-objcopy/ELF/invalid-p_filesz-p_offset.test
+++ llvm/test/tools/llvm-objcopy/ELF/invalid-p_filesz-p_offset.test
@@ -33,13 +33,7 @@
   Data:    ELFDATA2LSB
   Type:    ET_EXEC
   Machine: EM_X86_64
-Sections:
-  - Name: .foo
-    Type: SHT_PROGBITS
-    Size: 1
 ProgramHeaders:
-  - Type:        PT_LOAD
-    Offset:      0x100000
-    FileSize:    1
-    Sections:
-      - Section: .foo
+  - Type:     PT_LOAD
+    Offset:   0x100000
+    FileSize: 1
Index: llvm/test/tools/llvm-readobj/ELF/gnu-notes.test
===================================================================
--- llvm/test/tools/llvm-readobj/ELF/gnu-notes.test
+++ llvm/test/tools/llvm-readobj/ELF/gnu-notes.test
@@ -165,15 +165,9 @@
   Data:    ELFDATA2LSB
   Type:    ET_CORE
   Machine: EM_X86_64
-Sections:
-  - Name:  .note
-    Type:  SHT_NOTE
-    Notes: []
 ProgramHeaders:
-  - Type: PT_NOTE
+  - Type:   PT_NOTE
     Offset: 0xffff0000
-    Sections:
-      - Section: .note
 
 ## Test tools report an error if a note program header has an invalid size that
 ## goes past the end of file.
Index: llvm/test/tools/yaml2obj/ELF/program-header-size-offset.yaml
===================================================================
--- llvm/test/tools/yaml2obj/ELF/program-header-size-offset.yaml
+++ llvm/test/tools/yaml2obj/ELF/program-header-size-offset.yaml
@@ -1,8 +1,8 @@
 ## Show that yaml2obj properly emits program headers with explicit file size,
 ## memory size and offset parameters.
 
-# RUN: yaml2obj %s -o %t
-# RUN: llvm-readobj %t --program-headers | FileCheck %s
+# RUN: yaml2obj --docnum=1 %s -o %t1
+# RUN: llvm-readobj %t1 --program-headers | FileCheck %s
 
 # CHECK: ProgramHeaders [
 # CHECK:    Offset: 0x1234
@@ -34,7 +34,7 @@
 # CHECK:    MemSize: 6
 # CHECK: ]
 
-!ELF
+--- !ELF
 FileHeader:
   Class:           ELFCLASS64
   Data:            ELFDATA2LSB
@@ -97,8 +97,6 @@
     Offset:   0x3000
     FileSize: 3
     MemSize:  2
-    Sections:
-      - Section: .data
   # Program header with 2 SHT_NOBITS sections.
   - Type:     0x6abcdef0
     Offset:   0x2004
@@ -106,3 +104,79 @@
       - Section: .data
       - Section: .nobits1
       - Section: .nobits2
+
+## Test the "Offset" property.
+
+## Check that by default the p_offset field of a segment is set to the
+## offset of the section with the minimal section offset.
+# RUN: yaml2obj --docnum=2 %s -o %t2
+# RUN: llvm-readelf %t2 --sections --program-headers | \
+# RUN:   FileCheck %s --check-prefixes=DEFAULT-OFFSET
+
+# DEFAULT-OFFSET:      [Nr] Name Type     Address          Off
+# DEFAULT-OFFSET:      [ 1] .foo PROGBITS 0000000000001000 0000b0
+# DEFAULT-OFFSET-NEXT: [ 2] .bar PROGBITS 0000000000001001 0000b1
+
+# DEFAULT-OFFSET:       Type Offset
+# DEFAULT-OFFSET-NEXT:  LOAD 0x0000b0
+# DEFAULT-OFFSET-NEXT:  LOAD 0x0000b1
+
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_EXEC
+  Machine: EM_X86_64
+Sections:
+  - Name:    .foo
+    Type:    SHT_PROGBITS
+    Flags:   [ SHF_ALLOC ]
+    Size:    0x1
+    Address: 0x1000
+  - Name:    .bar
+    Type:    SHT_PROGBITS
+    Flags:   [ SHF_ALLOC ]
+    Size:    0x1
+ProgramHeaders:
+  - Type:    PT_LOAD
+    Sections:
+      - Section: .foo
+      - Section: .bar
+  - Type:    PT_LOAD
+    Sections:
+      - Section: .bar
+
+## Check we can set the "Offset" value explicitly when it is less or equal to
+## the offset of a section in the segment.
+# RUN: yaml2obj --docnum=3 -DOFFSET=0x78 %s -o %t3
+# RUN: llvm-readelf %t3 --sections --program-headers | \
+# RUN:   FileCheck %s --check-prefixes=VALID-OFFSET
+
+# VALID-OFFSET: [Nr] Name Type     Address          Off
+# VALID-OFFSET: [ 1] .foo PROGBITS 0000000000000000 000078
+
+# VALID-OFFSET: Type Offset
+# VALID-OFFSET: LOAD 0x000078
+
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_EXEC
+  Machine: EM_X86_64
+Sections:
+  - Name:  .foo
+    Type:  SHT_PROGBITS
+    Flags: [ SHF_ALLOC ]
+    Size:  0x1
+ProgramHeaders:
+  - Type: PT_LOAD
+    Offset: [[OFFSET]]
+    Sections:
+      - Section: .foo
+
+## Check we report an error when the "Offset" value is larger than the offset of a section in the segment.
+# RUN: not yaml2obj --docnum=3 -DOFFSET=0x79 %s -o /dev/null 2>&1 | \
+# RUN:  FileCheck %s --check-prefix=INVALID-OFFSET
+
+# INVALID-OFFSET: yaml2obj: error: the 'Offset' specified for the segment with index 1 must be less or equal than the minimal file offset of a section included into it (0x78)