# REQUIRES: x86-registered-target
# RUN: yaml2obj %s -o %t
# RUN: echo -n 11112222 > %t.same
# RUN: echo -n 00000000 > %t.zeros
# RUN: echo -n 11 > %t.short
# RUN: echo -n 11113333 > %t.updated
# RUN: echo -n 111122223 > %t.larger
## Update the segment section with a regular chunk of data the same size as the section.
# RUN: llvm-objcopy --update-section=.in_segment=%t.same %t %t.same.o
# RUN: llvm-readobj --section-headers --section-data --program-headers %t.same.o | \
# RUN: FileCheck %s --check-prefix=NORMAL
## Show that if we overwrite a given section (.in_segment) with new data, then rewrite it
## back (from the second `--update-section`), then it should be the exact same as the
## original file.
# RUN: llvm-objcopy %t %t.copy.o
# RUN: llvm-objcopy --update-section=.in_segment=%t.same --update-section=.in_segment=%t.zeros %t %t.original.o
# RUN: cmp %t.copy.o %t.original.o
## Update segment section with a smaller chunk of data. This will also update the
## section size to the length of the new data written. This does not affect the offset
## of any subsequent sections in the same segment as this.
# RUN: llvm-objcopy --update-section=.in_segment=%t.short %t %t.short.o
# RUN: llvm-readobj --section-headers --section-data --program-headers %t.short.o | \
# RUN: FileCheck %s --check-prefix=SHORT
## Ensure the data that was in a shortened section within a segment is still retained.
## For cases where there are gaps in segments not covered by sections, the existing
## contents are preserved.
# RUN: od -t x1 -j 0x78 -N 16 %t.short.o | FileCheck %s --check-prefix=PRESERVED
## Add a new section via --add-section, then update it.
# RUN: llvm-objcopy --add-section=.added=%t.zeros --update-section=.added=%t.updated \
# RUN: %t %t.updated.o
# RUN: llvm-readobj --section-headers --section-data --program-headers %t.updated.o | \
# RUN: FileCheck %s --check-prefix=ADD-UPDATE
## Adding should always be first regardless of flag order.
# RUN: llvm-objcopy --update-section=.added=%t.updated --add-section=.added=%t.updated \
# RUN: %t %t.updated.o
# RUN: llvm-readobj --section-headers --section-data --program-headers %t.updated.o | \
# RUN: FileCheck %s --check-prefix=ADD-UPDATE
## We can't update sections which don't exist.
# RUN: not llvm-objcopy --update-section=.nosection=%t.same %t %t-err1 2>&1 | \
# RUN: FileCheck %s --check-prefix=ERR-NO-SECTION
## We can't update certain types of sections.
# RUN: not llvm-objcopy --update-section=.nobits_type=%t.same %t %t-err2 2>&1 | \
# RUN: FileCheck %s --check-prefix=ERR-NOBITS-TYPE
# RUN: not llvm-objcopy --update-section=.null_type=%t.same %t %t-err2 2>&1 | \
# RUN: FileCheck %s --check-prefix=ERR-NULL-TYPE
## Fail on trying to insert data larger than the existing section.
# RUN: not llvm-objcopy --update-section=.in_segment=%t.larger %t %t-err3 2>&1 | \
# RUN: FileCheck %s --check-prefix=ERR-LARGER
## But we can insert larger data if the section is NOT part of a segment.
# RUN: llvm-objcopy --update-section=.not_in_segment=%t.larger %t %t.larger.o
# RUN: llvm-readobj --section-headers --section-data --program-headers %t.larger.o | \
# RUN: FileCheck %s --check-prefix=LONG
## We should still fail on inserting larger data, even if it is superceded by a
## valid --update-section flag.
# RUN: not llvm-objcopy --update-section=.in_segment=%t.larger --update-section=.in_segment=%t.same %t %t-err3 2>&1 | \
# RUN: FileCheck %s --check-prefix=ERR-LARGER
## Test option parsing failures.
# RUN: not llvm-objcopy --update-section %t %t.out 2>&1 | FileCheck %s --check-prefix=MISSING-EQ
# RUN: not llvm-objcopy --update-section=.in_segment= %t %t.out 2>&1 | FileCheck %s --check-prefix=MISSING-FILE
!ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_EXEC
Machine: EM_X86_64
Sections:
- Name: .in_segment
Type: SHT_PROGBITS
Content: "3030303030303030"
- Name: .unmodified_in_segment
Type: SHT_PROGBITS
Content: "3130303030303030"
- Name: .nobits_type
Type: SHT_NOBITS
- Name: .not_in_segment
Type: SHT_PROGBITS
- Name: .null_type
Type: SHT_NULL
ProgramHeaders:
- Type: PT_LOAD
VAddr: 0x1000
FirstSec: .in_segment
## The unmodified section is for ensuring that it remains untouched (ie. its
## offset is the same) even when the section before it is shrunk.
LastSec: .unmodified_in_segment
# NORMAL: Name: .in_segment
# NORMAL: Offset:
# NORMAL-SAME: {{ }}0x78{{$}}
# NORMAL: Size:
# NORMAL-SAME: {{ }}8{{$}}
# NORMAL: SectionData (
# NORMAL-NEXT: |11112222|
# NORMAL-NEXT: )
# NORMAL: Name: .unmodified_in_segment
# NORMAL: Offset:
# NORMAL-SAME: {{ }}0x80{{$}}
# NORMAL: Size:
# NORMAL-SAME: {{ }}8{{$}}
# NORMAL: SectionData (
# NORMAL-NEXT: |10000000|
# NORMAL-NEXT: )
# NORMAL: ProgramHeaders [
# NORMAL-NEXT: ProgramHeader {
# NORMAL-NEXT: Type: PT_LOAD (0x1)
# NORMAL: FileSize:
# NORMAL-SAME: {{ }}16{{$}}
# NORMAL: MemSize:
# NORMAL-SAME: {{ }}16{{$}}
# NORMAL: }
# NORMAL-NEXT: ]
# SHORT: Name: .in_segment
# SHORT: Offset:
# SHORT-SAME: {{ }}0x78{{$}}
# SHORT: Size:
# SHORT-SAME: {{ }}2{{$}}
# SHORT: SectionData (
# SHORT-NEXT: |11|
# SHORT-NEXT: )
# SHORT: Name: .unmodified_in_segment
# SHORT: Offset:
# SHORT-SAME: {{ }}0x80{{$}}
# SHORT: Size:
# SHORT-SAME: {{ }}8{{$}}
# SHORT: SectionData (
# SHORT-NEXT: |10000000|
# SHORT-NEXT: )
# SHORT: ProgramHeaders [
# SHORT-NEXT: ProgramHeader {
# SHORT-NEXT: Type: PT_LOAD (0x1)
# SHORT: FileSize:
# SHORT-SAME: {{ }}16{{$}}
# SHORT: MemSize:
# SHORT-SAME: {{ }}16{{$}}
# SHORT: }
# SHORT-NEXT: ]
## The first 8 bytes are the modified section. The last 8 bytes are the
## unmodified section.
# PRESERVED: 31 31 30 30 30 30 30 30 31 30 30 30 30 30 30 30
# LONG: Name: .not_in_segment
# LONG: Size:
# LONG-SAME: {{ }}9{{$}}
# LONG: SectionData (
# LONG-NEXT: |111122223|
# LONT-NEXT: )
# ADD-UPDATE: Name: .added
# ADD-UPDATE: Size:
# ADD-UPDATE-SAME: {{ }}8{{$}}
# ADD-UPDATE: SectionData (
# ADD-UPDATE-NEXT: |11113333|
# ADD-UPDATE: )
# ERR-NO-SECTION: error: {{.*}}section '.nosection' not found
# ERR-NOBITS-TYPE: error: {{.*}}section '.nobits_type' cannot be updated because it does not have contents
# ERR-NULL-TYPE: error: {{.*}}section '.null_type' cannot be updated because it does not have contents
# ERR-LARGER: error: {{.*}}cannot fit data of size 9 into section '.in_segment' with size 8 that is part of a segment
# MISSING-EQ: error: bad format for --update-section: missing '='
# MISSING-FILE: error: bad format for --update-section: missing file name