When running readelf -S
I get:
[27] .strtab STRTAB 0000000000000000 00001630
00000000000001d7 0000000000000000 0 0 1
[28] .shstrtab STRTAB 0000000000000000 00001807
0000000000000103 0000000000000000 0 0 1
How can I get the index of .strtab
?
At first I tried to detect it using the Type
field, but that won't work as you can see (27 and 28 have same type). Plus I can't be sure that it will be the first of type STRTAB to appear.
My struct with some explanations:
/*
* Section header.
*/
typedef struct {
Elf64_Word sh_name; /* Section name (index into the
section header string table). */
Elf64_Word sh_type; /* Section type. */
Elf64_Xword sh_flags; /* Section flags. */
Elf64_Addr sh_addr; /* Address in memory image. */
Elf64_Off sh_offset; /* Offset in file. */
Elf64_Xword sh_size; /* Size in bytes. */
Elf64_Word sh_link; /* Index of a related section. */
Elf64_Word sh_info; /* Depends on section type. */
Elf64_Xword sh_addralign; /* Alignment in bytes. */
Elf64_Xword sh_entsize; /* Size of each entry in section. */
} Elf64_Shdr;
How can I get the index of
.strtab
?
You read the Elf64_Shdr
s one by one. When you've read the 28th entry, you will have read the .strtab
, and you'll know its index.
You'll know that it's the .strtab
section by comparing its name with ".strtab"
string literal.
(You are probably intending to ask a different question, but if that's the case, you haven't expressed it well.)
Update:
Can't I do anything else rather than comparing strings
Maybe. If your real question is finding the .strtab
section, then not really.
(which is somehow hard) can I assume it will be the first STRTAB in the file for example?
There is no guarantee that that will be the case.
Note: if you are worried about the speed of strcmp()
, note that you can only do that strcmp()
when .sh_type == SHT_STRTAB
, and since there are usually at most two such sections in any given file, the concern about the speed of strcmp()
is likely misplaced. Your code would look something like:
if (shdr.sh_type == SHT_STRTAB) {
const char *sh_name = contents_of_shstrab + shdr.sh_name;
if (strcmp(sh_name, ".strtab") == 0) {
/* found .strtab; do whatever you need with it */
}
}
Update 2:
your solution is wrong, please see: http://stackoverflow.com/questions/68074508/
You can't claim that my solution is wrong, since I haven't provided a complete solution. It is also not wrong.
Here is complete code (with most error checking omitted):
#include <elf.h>
#include <fcntl.h>
#include <link.h>
#include <stdio.h>
#include <sys/mman.h>
#include <sys/stat.h>
int main(int argc, char *argv[])
{
if (argc < 1) return 1;
int fd = open(argv[1], O_RDONLY);
if (fd == -1) return 2;
struct stat st_buf;
if (fstat(fd, &st_buf) != 0) return 3;
char *data = mmap(NULL, st_buf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
if (data == MAP_FAILED) return 4;
const ElfW(Ehdr) *ehdr = (const ElfW(Ehdr) *)data;
const ElfW(Shdr) *shdr = (const ElfW(Shdr) *)(data + ehdr->e_shoff);
const char *shstrtab = data + shdr[ehdr->e_shstrndx].sh_offset;
for (int j = 0; j < ehdr->e_shnum; j++) {
printf("[%2d] %s\n", j, shstrtab + shdr[j].sh_name);
}
return 0;
}
$ gcc -g t.c -Wall
$ ./a.out ./a.out
[ 0]
[ 1] .interp
[ 2] .note.gnu.build-id
[ 3] .note.ABI-tag
[ 4] .gnu.hash
[ 5] .dynsym
[ 6] .dynstr
...
[32] .symtab
[33] .strtab
[34] .shstrtab