diff options
Diffstat (limited to 'documentation/libelf-by-example/prog4.txt')
-rw-r--r-- | documentation/libelf-by-example/prog4.txt | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/documentation/libelf-by-example/prog4.txt b/documentation/libelf-by-example/prog4.txt new file mode 100644 index 0000000000000..465f9df595d7b --- /dev/null +++ b/documentation/libelf-by-example/prog4.txt @@ -0,0 +1,92 @@ +/* + * Print the names of ELF sections. + * + * $Id: prog4.txt 2133 2011-11-10 08:28:22Z jkoshy $ + */ + +#include <err.h> +#include <fcntl.h> +#include <gelf.h> +#include <stdio.h> +#include <stdint.h> +#include <stdlib.h> +#include <unistd.h> +#include <vis.h> + +int +main(int argc, char **argv) +{ + int fd; + Elf *e; + char *name, *p, pc[4*sizeof(char)]; + Elf_Scn *scn; + Elf_Data *data; + GElf_Shdr shdr; + size_t n, shstrndx, sz; + + if (argc != 2) + errx(EXIT_FAILURE, "usage: %s file-name", argv[0]); + + if (elf_version(EV_CURRENT) == EV_NONE) + errx(EXIT_FAILURE, "ELF library initialization " + "failed: %s", elf_errmsg(-1)); + + if ((fd = open(argv[1], O_RDONLY, 0)) < 0) + err(EXIT_FAILURE, "open \%s\" failed", argv[1]); + + if ((e = elf_begin(fd, ELF_C_READ, NULL)) == NULL) + errx(EXIT_FAILURE, "elf_begin() failed: %s.", + elf_errmsg(-1)); + + if (elf_kind(e) != ELF_K_ELF) + errx(EXIT_FAILURE, "%s is not an ELF object.", + argv[1]); + + if (elf_getshdrstrndx(e, &shstrndx) != 0) @\co{1}@ + errx(EXIT_FAILURE, "elf_getshdrstrndx() failed: %s.", + elf_errmsg(-1)); + + scn = NULL; @\co{2}@ + while ((scn = elf_nextscn(e, scn)) != NULL) { @\co{3}@ + if (gelf_getshdr(scn, &shdr) != &shdr) @\co{4}@ + errx(EXIT_FAILURE, "getshdr() failed: %s.", + elf_errmsg(-1)); + + if ((name = elf_strptr(e, shstrndx, shdr.sh_name)) + == NULL) @\co{5}@ + errx(EXIT_FAILURE, "elf_strptr() failed: %s.", + elf_errmsg(-1)); + + (void) printf("Section %-4.4jd %s\n", (uintmax_t) + elf_ndxscn(scn), name); + } + + if ((scn = elf_getscn(e, shstrndx)) == NULL) @\co{6}@ + errx(EXIT_FAILURE, "getscn() failed: %s.", + elf_errmsg(-1)); + + if (gelf_getshdr(scn, &shdr) != &shdr) + errx(EXIT_FAILURE, "getshdr(shstrndx) failed: %s.", + elf_errmsg(-1)); + + (void) printf(".shstrab: size=%jd\n", (uintmax_t) + shdr.sh_size); + + data = NULL; n = 0; + while (n < shdr.sh_size && + (data = elf_getdata(scn, data)) != NULL) { @\co{7}@ + p = (char *) data->d_buf; + while (p < (char *) data->d_buf + data->d_size) { + if (vis(pc, *p, VIS_WHITE, 0)) + printf("%s", pc); + n++; p++; + (void) putchar((n % 16) ? ' ' : '\n'); + } + } + (void) putchar('\n'); + + (void) elf_end(e); + (void) close(fd); + exit(EXIT_SUCCESS); +} + |