| # 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 |