summaryrefslogtreecommitdiff
path: root/documentation/libelf-by-example/prog5.txt
diff options
context:
space:
mode:
Diffstat (limited to 'documentation/libelf-by-example/prog5.txt')
-rw-r--r--documentation/libelf-by-example/prog5.txt133
1 files changed, 133 insertions, 0 deletions
diff --git a/documentation/libelf-by-example/prog5.txt b/documentation/libelf-by-example/prog5.txt
new file mode 100644
index 0000000000000..d44cf935fe1cb
--- /dev/null
+++ b/documentation/libelf-by-example/prog5.txt
@@ -0,0 +1,133 @@
+/*
+ * Create an ELF object.
+ *
+ * $Id: prog5.txt 2133 2011-11-10 08:28:22Z jkoshy $
+ */
+
+#include <err.h>
+#include <fcntl.h>
+#include <libelf.h> @\co{1}@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+uint32_t hash_words[] = { @\co{2}@
+ 0x01234567,
+ 0x89abcdef,
+ 0xdeadc0de
+};
+
+char string_table[] = { @\co{3}@
+ /* Offset 0 */ '\0',
+ /* Offset 1 */ '.', 'f', 'o', 'o', '\0',
+ /* Offset 6 */ '.', 's', 'h', 's', 't',
+ 'r', 't', 'a', 'b', '\0'
+};
+
+int
+main(int argc, char **argv)
+{
+ int fd;
+ Elf *e;
+ Elf_Scn *scn;
+ Elf_Data *data;
+ Elf32_Ehdr *ehdr;
+ Elf32_Phdr *phdr;
+ Elf32_Shdr *shdr;
+
+ 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_WRONLY|O_CREAT, 0777)) < 0) @\co{4}@
+ err(EXIT_FAILURE, "open \%s\" failed", argv[1]);
+
+ if ((e = elf_begin(fd, ELF_C_WRITE, NULL)) == NULL) @\co{5}@
+ errx(EXIT_FAILURE, "elf_begin() failed: %s.",
+ elf_errmsg(-1));
+
+ if ((ehdr = elf32_newehdr(e)) == NULL) @\co{6}@
+ errx(EXIT_FAILURE, "elf32_newehdr() failed: %s.",
+ elf_errmsg(-1));
+
+ ehdr->e_ident[EI_DATA] = ELFDATA2MSB;
+ ehdr->e_machine = EM_PPC; /* 32-bit PowerPC object */
+ ehdr->e_type = ET_EXEC;
+
+ if ((phdr = elf32_newphdr(e, 1)) == NULL) @\co{7}@
+ errx(EXIT_FAILURE, "elf32_newphdr() failed: %s.",
+ elf_errmsg(-1));
+
+ if ((scn = elf_newscn(e)) == NULL) @\co{8}@
+ errx(EXIT_FAILURE, "elf_newscn() failed: %s.",
+ elf_errmsg(-1));
+
+ if ((data = elf_newdata(scn)) == NULL)
+ errx(EXIT_FAILURE, "elf_newdata() failed: %s.",
+ elf_errmsg(-1));
+
+ data->d_align = 4;
+ data->d_off = 0LL;
+ data->d_buf = hash_words;
+ data->d_type = ELF_T_WORD;
+ data->d_size = sizeof(hash_words);
+ data->d_version = EV_CURRENT;
+
+ if ((shdr = elf32_getshdr(scn)) == NULL)
+ errx(EXIT_FAILURE, "elf32_getshdr() failed: %s.",
+ elf_errmsg(-1));
+
+ shdr->sh_name = 1;
+ shdr->sh_type = SHT_HASH;
+ shdr->sh_flags = SHF_ALLOC;
+ shdr->sh_entsize = 0;
+
+ if ((scn = elf_newscn(e)) == NULL) @\co{9}@
+ errx(EXIT_FAILURE, "elf_newscn() failed: %s.",
+ elf_errmsg(-1));
+
+ if ((data = elf_newdata(scn)) == NULL)
+ errx(EXIT_FAILURE, "elf_newdata() failed: %s.",
+ elf_errmsg(-1));
+
+ data->d_align = 1;
+ data->d_buf = string_table;
+ data->d_off = 0LL;
+ data->d_size = sizeof(string_table);
+ data->d_type = ELF_T_BYTE;
+ data->d_version = EV_CURRENT;
+
+ if ((shdr = elf32_getshdr(scn)) == NULL)
+ errx(EXIT_FAILURE, "elf32_getshdr() failed: %s.",
+ elf_errmsg(-1));
+
+ shdr->sh_name = 6;
+ shdr->sh_type = SHT_STRTAB;
+ shdr->sh_flags = SHF_STRINGS | SHF_ALLOC;
+ shdr->sh_entsize = 0;
+
+ elf_setshstrndx(e, elf_ndxscn(scn)); @\co{10}@
+
+ if (elf_update(e, ELF_C_NULL) < 0) @\co{11}@
+ errx(EXIT_FAILURE, "elf_update(NULL) failed: %s.",
+ elf_errmsg(-1));
+
+ phdr->p_type = PT_PHDR;
+ phdr->p_offset = ehdr->e_phoff;
+ phdr->p_filesz = elf32_fsize(ELF_T_PHDR, 1, EV_CURRENT);
+
+ (void) elf_flagphdr(e, ELF_C_SET, ELF_F_DIRTY);
+
+ if (elf_update(e, ELF_C_WRITE) < 0) @\co{12}@
+ errx(EXIT_FAILURE, "elf_update() failed: %s.",
+ elf_errmsg(-1));
+
+ (void) elf_end(e);
+ (void) close(fd);
+
+ exit(EXIT_SUCCESS);
+}
+