From: Kai W. <kai...@gm...> - 2008-07-31 16:56:00
|
Hi, I've been trying to port libelf to Debian today, and I managed make it basically working. There are some issues unclear to me: (I attached a patch below) 1. elf header files I found that there are two versions of ELF header files which contain ELF structures and other definitions. One is provided by GNU libc, the other one is linux/elf.h(includes asm/elf.h, etc, provided by kernel? ). I noticed that the one provided by GNU libc has more definitions thus maybe better for us to use. But asm/elf.h provides arch-dependent defines. So, in the patch I included asm/elf.h in _libelf_config.h to get arch-dependent defines (ELF_CLASS, ELF_ARCH, ELF_DATA), and included elf.h(GNU libc) in libelf.h. 2. strlcat/strlcpy These two functions are very convenient but unfortunately not inside GNU libc. I guess there are two solutions for this: a) Use portable strncpy/strncat, as a result, the code will become less elegant. b) define strlcpy/strlcat. In the patch I chose b), I added a file called libelf_util.c which defines these two function. (stolen from FreeBSD libc) 3. STAILQ Should we just add missing STAILQ defines like we did for NetBSD? 4. pmake compatibility a) Seems that header files (gelf.h, libelf.h) can not be installed. After I typed "pmake install", libraries and manual pages got installed, but not header files. b) GNU and BSD tsort are probably incompatibible, you can see some tsort warnings during compiling, but I don't know if that affects the resulting files. The patch: diff -urN elftoolchain/projects/libelf/trunk/_libelf_config.h libelf/_libelf_config.h --- elftoolchain/projects/libelf/trunk/_libelf_config.h 2008-07-31 12:53:48.000000000 +0200 +++ libelf/_libelf_config.h 2008-07-31 17:37:44.000000000 +0200 @@ -135,6 +135,92 @@ #endif /* __NetBSD__ */ +#ifdef __linux__ + +#include <asm/elf.h> + +#define LIBELF_CONFIG_ADDR 1 +#define LIBELF_CONFIG_BYTE 1 +#define LIBELF_CONFIG_DYN 1 +#define LIBELF_CONFIG_EHDR 1 +#define LIBELF_CONFIG_HALF 1 +#define LIBELF_CONFIG_NOTE 1 +#define LIBELF_CONFIG_OFF 1 +#define LIBELF_CONFIG_PHDR 1 +#define LIBELF_CONFIG_REL 1 +#define LIBELF_CONFIG_RELA 1 +#define LIBELF_CONFIG_SHDR 1 +#define LIBELF_CONFIG_SWORD 1 +#define LIBELF_CONFIG_SYM 1 +#define LIBELF_CONFIG_WORD 1 + +#define LIBELF_CONFIG_SXWORD 1 +#define LIBELF_CONFIG_XWORD 1 + +#define LIBELF_CONFIG_MOVEP 1 + +#define LIBELF_CONFIG_VDEF 1 +#define LIBELF_CONFIG_VNEED 1 + +#define LIBELF_VCSID(ID) + +#ifndef STAILQ_EMPTY +#define STAILQ_EMPTY(head) ((head)->stqh_first == NULL) +#endif + +#ifndef STAILQ_FIRST +#define STAILQ_FIRST(head) ((head)->stqh_first) +#endif + +#ifndef STAILQ_FOREACH +#define STAILQ_FOREACH(var, head, field) \ + for((var) = STAILQ_FIRST((head)); \ + (var); \ + (var) = STAILQ_NEXT((var), field)) +#endif + +#ifndef SLIST_FOREACH_SAFE +#define STAILQ_FOREACH_SAFE(var, head, field, tvar) \ + for ((var) = STAILQ_FIRST((head)); \ + (var) && ((tvar) = STAILQ_NEXT((var), field), 1); \ + (var) = (tvar)) +#endif + +#ifndef STAILQ_INIT +#define STAILQ_INIT(head) do { \ + STAILQ_FIRST((head)) = NULL; \ + (head)->stqh_last = &STAILQ_FIRST((head)); \ +} while (0) +#endif + +#ifndef STAILQ_INSERT_TAIL +#define STAILQ_INSERT_TAIL(head, elm, field) do { \ + STAILQ_NEXT((elm), field) = NULL; \ + *(head)->stqh_last = (elm); \ + (head)->stqh_last = &STAILQ_NEXT((elm), field); \ +} while (0) +#endif + +#ifndef STAILQ_LAST +#define STAILQ_LAST(head, type, field) \ + (STAILQ_EMPTY((head)) ? \ + NULL : \ + ((struct type *)(void *) \ + ((char *)((head)->stqh_last) - offsetof(struct type, field)))) +#endif + +#define LIBELF_ARCH ELF_ARCH +#define LIBELF_BYTEORDER ELF_DATA +#define LIBELF_CLASS ELF_CLASS + +#if ELF_CLASS == ELFCLASS32 +#define Elf_Note Elf32_Nhdr +#else +#define Elf_Note Elf64_Nhdr +#endif + +#endif /* __linux__ */ + /* * Symbols that are sometimes missing in system headers. */ diff -urN elftoolchain/projects/libelf/trunk/libelf.h libelf/libelf.h --- elftoolchain/projects/libelf/trunk/libelf.h 2008-07-31 12:53:48.000000000 +0200 +++ libelf/libelf.h 2008-07-31 17:34:29.000000000 +0200 @@ -38,6 +38,8 @@ #elif defined(__NetBSD__) #include <sys/exec_elf.h> #elif defined(__linux__) +#include <elf.h> +#include <stdint.h> #endif /* Library private data structures */ diff -urN elftoolchain/projects/libelf/trunk/libelf_util.c libelf/libelf_util.c --- elftoolchain/projects/libelf/trunk/libelf_util.c 1970-01-01 01:00:00.000000000 +0100 +++ libelf/libelf_util.c 2008-07-31 17:14:37.000000000 +0200 @@ -0,0 +1,65 @@ +#ifdef __linux__ + +#include <string.h> + +size_t +strlcat(dst, src, siz) + char *dst; + const char *src; + size_t siz; +{ + char *d = dst; + const char *s = src; + size_t n = siz; + size_t dlen; + + /* Find the end of dst and adjust bytes left but don't go past end */ + while (n-- != 0 && *d != '\0') + d++; + dlen = d - dst; + n = siz - dlen; + + if (n == 0) + return(dlen + strlen(s)); + while (*s != '\0') { + if (n != 1) { + *d++ = *s; + n--; + } + s++; + } + *d = '\0'; + + return(dlen + (s - src)); /* count does not include NUL */ +} + +size_t +strlcpy(dst, src, siz) + char *dst; + const char *src; + size_t siz; +{ + char *d = dst; + const char *s = src; + size_t n = siz; + + /* Copy as many bytes as will fit */ + if (n != 0 && --n != 0) { + do { + if ((*d++ = *s++) == 0) + break; + } while (--n != 0); + } + + /* Not enough room in dst, add NUL and traverse rest of src */ + if (n == 0) { + if (siz != 0) + *d = '\0'; /* NUL-terminate dst */ + while (*s++) + ; + } + + return(s - src - 1); /* count does not include NUL */ +} + +#endif diff -urN elftoolchain/projects/libelf/trunk/Makefile libelf/Makefile --- elftoolchain/projects/libelf/trunk/Makefile 2008-07-31 12:53:48.000000000 +0200 +++ libelf/Makefile 2008-07-31 17:14:57.000000000 +0200 @@ -50,6 +50,7 @@ libelf_extended.c \ libelf_phdr.c \ libelf_shdr.c \ + libelf_util.c \ libelf_xlate.c \ ${GENSRCS} INCS= libelf.h gelf.h |