-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[llvm-readobj, ELF] Support reading binary with more than PN_XNUM segments. #165278
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| # RUN: yaml2obj --docnum=1 %s -o %t.o | ||
|
|
||
| # RUN: llvm-readobj --headers %t.o 2>&1 | FileCheck %s --check-prefix=CASE-INVALID | ||
|
|
||
| # CASE-INVALID: SectionHeaderOffset: 0 | ||
| # CASE-INVALID: ProgramHeaderCount: 65535 (corrupt) | ||
| # CASE-INVALID: unable to dump program headers: program headers are longer than binary of size 336: e_phoff = 0x40, e_phnum = 65535, e_phentsize = 56 | ||
|
|
||
| --- !ELF | ||
| FileHeader: | ||
| Class: ELFCLASS64 | ||
| Data: ELFDATA2LSB | ||
| Type: ET_EXEC | ||
| Machine: EM_X86_64 | ||
| EPhNum: 65535 | ||
| EShOff: 0 | ||
| ProgramHeaders: | ||
| - Type: PT_LOAD | ||
|
|
||
| # RUN: yaml2obj --docnum=2 %s -o %t2.o | ||
|
|
||
| # RUN: llvm-readobj --headers %t2.o 2>&1 | FileCheck %s --check-prefix=CASE-VALID | ||
|
|
||
| # CASE-VALID: SectionHeaderOffset: 0 | ||
| # CASE-VALID: ProgramHeaderCount: 65535 (65536) | ||
| # CASE-VALID: unable to dump program headers: program headers are longer than binary of size 336: e_phoff = 0x40, e_phnum = 65536, e_phentsize = 56 | ||
|
|
||
| --- !ELF | ||
| FileHeader: | ||
| Class: ELFCLASS64 | ||
| Data: ELFDATA2LSB | ||
| Type: ET_EXEC | ||
| Machine: EM_X86_64 | ||
| EPhNum: 65535 | ||
| Sections: | ||
| - Type: SHT_NULL | ||
| Info: 65536 | ||
| ProgramHeaders: | ||
| - Type: PT_LOAD | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,79 @@ | ||
| ## Show that llvm-readelf can handle an input file with many segments. | ||
|
|
||
| RUN: %python %p/../../llvm-objcopy/Inputs/ungzip.py %p/Inputs/many-segments.o.gz > %t | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's not rely on a large file to test this behaviour when we don't have to. As noted in a previous comment somewhere, you can use yaml2obj to craft an object with e_phnum set to PN_XNUM and then a low number in the SHT_NULL section header.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A question is that it seems not a valid ELF under your suggestions since gABI would require you have more than or equal to PN_XNUM sections when using sectionc 0. It causes the following problem. That means we are not able to ouput 65535(4) in readelf without checking the getHeader().e_phnum == PN_XNUM since getPhNum always returns the true number. As a result, we might not able to test 65535 (N) case without actually creating more than 65535 segments.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
As I believed both @MaskRay and I have explained in different places, although the gABI requires an object to have >= PN_XNUM program headers for this functionality to be active, there is no reason to enforce that in our code, so we can use a smaller number without issue.
I may not have been clear in my other comments, but it is acceptable to check whether |
||
| RUN: llvm-readobj --file-headers --sections --segments %t | FileCheck %s | ||
| RUN: llvm-readelf --segments %t | FileCheck --check-prefix=SYMS %s | ||
|
|
||
| ## The ELF header should have e_phnum == PN_XNUM | ||
| # CHECK: ProgramHeaderCount: 65535 (66549) | ||
| ## The first section header should store the real program header count in its fields. | ||
| # CHECK: Section { | ||
| # CHECK-NEXT: Index: 0 | ||
| # CHECK-NEXT: Name: | ||
| # CHECK-NEXT: Type: SHT_NULL | ||
| # CHECK-NEXT: Flags [ | ||
| # CHECK-NEXT: ] | ||
| # CHECK-NEXT: Address: | ||
| # CHECK-NEXT: Offset: | ||
| # CHECK-NEXT: Size: | ||
| # CHECK-NEXT: Link: | ||
| # CHECK-NEXT: Info: 66549 | ||
|
|
||
| ## Show that the symbols with segments indexes around the reserved range still | ||
| ## have the right segment indexes afterwards. | ||
| # 65535th segment | ||
| # CHECK: Offset: 0x1183B000 | ||
| # CHECK-NEXT: VirtualAddress: 0x349139F3000 | ||
| # CHECK: } | ||
| # CHECK-NEXT ProgramHeader { | ||
| # CHECK-NEXT Type: PT_LOAD (0x1) | ||
| # CHECK-NEXT Offset: 0x1183C000 | ||
| # CHECK-NEXT VirtualAddress: 0x349139F4000 | ||
| # CHECK-NEXT PhysicalAddress: 0x0 | ||
| # CHECK-NEXT FileSize: 4096 | ||
| # CHECK-NEXT MemSize: 4096 | ||
| # CHECK-NEXT Flags [ (0x4) | ||
| # CHECK-NEXT PF_R (0x4) | ||
| # CHECK-NEXT ] | ||
| # CHECK-NEXT Alignment: 4096 | ||
| # CHECK-NEXT } | ||
| # CHECK-NEXT ProgramHeader { | ||
| # CHECK-NEXT Type: PT_LOAD (0x1) | ||
| # CHECK-NEXT Offset: 0x1183D000 | ||
| # CHECK-NEXT VirtualAddress: 0x349139F5000 | ||
| # CHECK-NEXT PhysicalAddress: 0x0 | ||
| # CHECK-NEXT FileSize: 4096 | ||
| # CHECK-NEXT MemSize: 4096 | ||
| # CHECK-NEXT Flags [ (0x6) | ||
| # CHECK-NEXT PF_R (0x4) | ||
| # CHECK-NEXT PF_W (0x2) | ||
| # CHECK-NEXT ] | ||
| # CHECK-NEXT Alignment: 4096 | ||
| # CHECK-NEXT } | ||
| # CHECK-NEXT ProgramHeader { | ||
| # CHECK-NEXT Type: PT_LOAD (0x1) | ||
| # CHECK-NEXT Offset: 0x1183E000 | ||
| # CHECK-NEXT VirtualAddress: 0x349139F6000 | ||
| # CHECK-NEXT PhysicalAddress: 0x0 | ||
| # CHECK-NEXT FileSize: 4096 | ||
| # CHECK-NEXT MemSize: 4096 | ||
| # CHECK-NEXT Flags [ (0x4) | ||
| # CHECK-NEXT PF_R (0x4) | ||
| # CHECK-NEXT ] | ||
| # CHECK-NEXT Alignment: 4096 | ||
| # CHECK-NEXT } | ||
| # CHECK ProgramHeader { | ||
| # CHECK-NEXT Type: PT_LOAD (0x1) | ||
| # CHECK-NEXT Offset: 0x11C31000 | ||
| # CHECK-NEXT VirtualAddress: 0x30D8E7868000 | ||
| # CHECK-NEXT PhysicalAddress: 0x0 | ||
| # CHECK-NEXT FileSize: 8192 | ||
| # CHECK-NEXT MemSize: 8192 | ||
| # CHECK-NEXT Flags [ (0x6) | ||
| # CHECK-NEXT PF_R (0x4) | ||
| # CHECK-NEXT PF_W (0x2) | ||
| # CHECK-NEXT ] | ||
| # CHECK-NEXT Alignment: 4096 | ||
| # CHECK-NEXT } | ||
|
|
||
| # SYMS: There are 66549 program headers, starting at offset 64 | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't feel like the right warning to be printing. We should just be printing something about the section header table missing or similar. We should probably not continue to try to print the program header table, if the program header count cannot be determined due to an invalid section header table.