@@ -46,7 +46,10 @@ static uint64_t file64_to_cpu(uint64_t val)
46
46
static unsigned long read_elf32 (int fd )
47
47
{
48
48
Elf32_Ehdr ehdr32 ;
49
+ Elf32_Shdr shdr32 ;
50
+ off_t last_shdr_offset ;
49
51
ssize_t ret ;
52
+ unsigned long sht_end , last_section_end ;
50
53
51
54
ret = pread (fd , & ehdr32 , sizeof (ehdr32 ), 0 );
52
55
if (ret < 0 || (size_t )ret != sizeof (ehdr32 )) {
@@ -59,16 +62,30 @@ static unsigned long read_elf32(int fd)
59
62
ehdr .e_shentsize = file16_to_cpu (ehdr32 .e_shentsize );
60
63
ehdr .e_shnum = file16_to_cpu (ehdr32 .e_shnum );
61
64
62
- return (ehdr .e_shoff + (ehdr .e_shentsize * ehdr .e_shnum ));
65
+ last_shdr_offset = ehdr .e_shoff + (ehdr .e_shentsize * (ehdr .e_shnum - 1 ));
66
+ ret = pread (fd , & shdr32 , sizeof (shdr32 ), last_shdr_offset );
67
+ if (ret < 0 || (size_t )ret != sizeof (shdr32 )) {
68
+ fprintf (stderr , "Read of ELF section header from %s failed: %s\n" ,
69
+ fname , strerror (errno ));
70
+ exit (10 );
71
+ }
72
+
73
+ /* ELF ends either with the table of section headers (SHT) or with a section. */
74
+ sht_end = ehdr .e_shoff + (ehdr .e_shentsize * ehdr .e_shnum );
75
+ last_section_end = file64_to_cpu (shdr32 .sh_offset ) + file64_to_cpu (shdr32 .sh_size );
76
+ return sht_end > last_section_end ? sht_end : last_section_end ;
63
77
}
64
78
65
79
static unsigned long read_elf64 (int fd )
66
80
{
67
81
Elf64_Ehdr ehdr64 ;
82
+ Elf64_Shdr shdr64 ;
83
+ off_t last_shdr_offset ;
68
84
ssize_t ret ;
85
+ unsigned long sht_end , last_section_end ;
69
86
70
87
ret = pread (fd , & ehdr64 , sizeof (ehdr64 ), 0 );
71
- if (ret < 0 || (size_t )ret != sizeof (ehdr )) {
88
+ if (ret < 0 || (size_t )ret != sizeof (ehdr64 )) {
72
89
fprintf (stderr , "Read of ELF header from %s failed: %s\n" ,
73
90
fname , strerror (errno ));
74
91
exit (10 );
@@ -78,15 +95,21 @@ static unsigned long read_elf64(int fd)
78
95
ehdr .e_shentsize = file16_to_cpu (ehdr64 .e_shentsize );
79
96
ehdr .e_shnum = file16_to_cpu (ehdr64 .e_shnum );
80
97
81
- return (ehdr .e_shoff + (ehdr .e_shentsize * ehdr .e_shnum ));
98
+ last_shdr_offset = ehdr .e_shoff + (ehdr .e_shentsize * (ehdr .e_shnum - 1 ));
99
+ ret = pread (fd , & shdr64 , sizeof (shdr64 ), last_shdr_offset );
100
+ if (ret < 0 || (size_t )ret != sizeof (shdr64 )) {
101
+ fprintf (stderr , "Read of ELF section header from %s failed: %s\n" ,
102
+ fname , strerror (errno ));
103
+ exit (10 );
104
+ }
105
+
106
+ /* ELF ends either with the table of section headers (SHT) or with a section. */
107
+ sht_end = ehdr .e_shoff + (ehdr .e_shentsize * ehdr .e_shnum );
108
+ last_section_end = file64_to_cpu (shdr64 .sh_offset ) + file64_to_cpu (shdr64 .sh_size );
109
+ return sht_end > last_section_end ? sht_end : last_section_end ;
82
110
}
83
111
84
112
unsigned long get_elf_size (const char * fname )
85
- /* TODO, FIXME: This assumes that the section header table (SHT) is
86
- the last part of the ELF. This is usually the case but
87
- it could also be that the last section is the last part
88
- of the ELF. This should be checked for.
89
- */
90
113
{
91
114
ssize_t ret ;
92
115
int fd ;
0 commit comments