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 |
From: Y G. A. N. <gir...@ap...> - 2008-08-01 08:36:59
|
Hi Kai, On 08/07/31 18:41 +0200, Kai Wang said ... > 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 did this a few weeks ago and sent a patch to Koshy, unfortunately this mailing list wasn't set up then. > 2. strlcat/strlcpy > > 3. STAILQ For Debian, these definitions are provided in the libbsd package. For other Linuxes, we would have to define these. > 4. pmake compatibility The pmake in Debian is very old, for Debian packages, I was intending to use the make from the freebsd5-buildutils package. Regards, Giridhar -- Y Giridhar Appaji Nag | http://appaji.net/ |
From: Kai W. <kai...@gm...> - 2008-08-05 18:50:07
|
On Fri, Aug 01, 2008 at 02:06:42PM +0530, Y Giridhar Appaji Nag wrote: > Hi Kai, > > On 08/07/31 18:41 +0200, Kai Wang said ... > > 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 did this a few weeks ago and sent a patch to Koshy, unfortunately this > mailing list wasn't set up then. > > > 2. strlcat/strlcpy > > > > 3. STAILQ > > For Debian, these definitions are provided in the libbsd package. For > other Linuxes, we would have to define these. > > > 4. pmake compatibility > > The pmake in Debian is very old, for Debian packages, I was intending to > use the make from the freebsd5-buildutils package. I just tried this package, the header files can be correctly installed with freebsd-make. Thanks, Kai |
From: Joseph K. <jk...@us...> - 2008-08-02 14:49:27
|
> I've been trying to port libelf to Debian today, and I managed > make it basically working. There are some issues unclear to me: Thanks. Giridhar (yganag@) had sent in a patch for a prior revision of libelf, enabling compilation for GNU/Linux, GNU/Hurd, and GNU/kFreeBSD. I'll take a stab at merging the information in both patches. kaiw> I found that there are two versions of ELF header files which kaiw> contain ELF structures and other definitions. One is provided by kaiw> GNU libc, the other one is linux/elf.h(includes asm/elf.h, etc, kaiw> provided by kernel? ). I noticed that the one provided by GNU kaiw> libc has more definitions thus maybe better for us to use. But kaiw> asm/elf.h provides arch-dependent defines. kaiw> So, in the patch I included asm/elf.h in _libelf_config.h to get kaiw> arch-dependent defines (ELF_CLASS, ELF_ARCH, ELF_DATA), and kaiw> included elf.h(GNU libc) in libelf.h. This seems ok. kaiw> 2. strlcat/strlcpy kaiw> These two functions are very convenient but unfortunately not inside kaiw> GNU libc. I guess there are two solutions for this: kaiw> a) Use portable strncpy/strncat, as a result, the code will become kaiw> less elegant. kaiw> b) define strlcpy/strlcat. kaiw> In the patch I chose b), I added a file called libelf_util.c which kaiw> defines these two function. (stolen from FreeBSD libc) yganag> For Debian, these definitions are provided in the libbsd yganag> package. For other Linuxes, we would have to define these. The strl*() APIs are cleaner, but I'm wondering if we should just bite the bullet and stick to the portable APIs. For example: Index: elf_errmsg.c =================================================================== --- elf_errmsg.c (revision 209) +++ elf_errmsg.c (working copy) @@ -27,6 +27,7 @@ #include <sys/cdefs.h> #include <libelf.h> +#include <stdio.h> #include <string.h> #include "_libelf.h" @@ -74,11 +75,9 @@ if (error < 0 || error >= ELF_E_NUM) return _libelf_errors[ELF_E_NUM]; if (oserr) { - strlcpy(LIBELF_PRIVATE(msg), _libelf_errors[error], - sizeof(LIBELF_PRIVATE(msg))); - strlcat(LIBELF_PRIVATE(msg), ": ", sizeof(LIBELF_PRIVATE(msg))); - strlcat(LIBELF_PRIVATE(msg), strerror(oserr), - sizeof(LIBELF_PRIVATE(msg))); + (void) snprintf(LIBELF_PRIVATE(msg), + sizeof(LIBELF_PRIVATE(msg)), "%s: %s", + _libelf_errors[error], strerror(oserr)); return (const char *)&LIBELF_PRIVATE(msg); } return _libelf_errors[error]; Comments? kaiw> 3. STAILQ Should we just add missing STAILQ defines like we did kaiw> for NetBSD? Question 1: Is there a package that provides <sys/queue.h> for GNU/Linux? Question 2: is there a way to distinguish between Debian GNU/Linux and the other distributions at compile time? E.g., is a __Debian__ or other pre-processor symbol defined at compile time? kaiw> 4. pmake compatibility kaiw> a) Seems that header files (gelf.h, libelf.h) can not be kaiw> installed. After I typed "pmake install", libraries and manual kaiw> pages got installed, but not header files. If there's a port of NetBSD `bmake', could you try that instead of pmake? http://www.crufty.net/help/sjg/bmake.html kaiw> b) GNU and BSD tsort are probably incompatibible, you can see some kaiw> tsort warnings during compiling, but I don't know if that affects the kaiw> resulting files. What are these warnings? Our Makefiles don't invoke tsort directly so if there are warnings we would need to look at the packaged <bsd.lib.mk>. Koshy |
From: Y G. A. N. <gir...@ap...> - 2008-08-03 18:08:25
|
On 08/08/02 14:47 -0000, Joseph Koshy said ... > kaiw> 3. STAILQ Should we just add missing STAILQ defines like we did > kaiw> for NetBSD? > > Question 1: Is there a package that provides <sys/queue.h> for > GNU/Linux? None as far I know. Debian though has libbsd that provides this as <bsd/queue.h> > Question 2: is there a way to distinguish between Debian GNU/Linux and > the other distributions at compile time? E.g., is a __Debian__ or > other pre-processor symbol defined at compile time? No. Regards, Giridhar -- Y Giridhar Appaji Nag | http://appaji.net/ |
From: Kai W. <kai...@gm...> - 2008-08-05 18:45:14
|
Sorry about the late reply, my $job is pushing me recently... On Sat, Aug 02, 2008 at 02:47:22PM -0000, Joseph Koshy wrote: > The strl*() APIs are cleaner, but I'm wondering if we should just bite > the bullet and stick to the portable APIs. > > For example: > > Index: elf_errmsg.c > =================================================================== > --- elf_errmsg.c (revision 209) > +++ elf_errmsg.c (working copy) > @@ -27,6 +27,7 @@ > #include <sys/cdefs.h> > > #include <libelf.h> > +#include <stdio.h> > #include <string.h> > > #include "_libelf.h" > @@ -74,11 +75,9 @@ > if (error < 0 || error >= ELF_E_NUM) > return _libelf_errors[ELF_E_NUM]; > if (oserr) { > - strlcpy(LIBELF_PRIVATE(msg), _libelf_errors[error], > - sizeof(LIBELF_PRIVATE(msg))); > - strlcat(LIBELF_PRIVATE(msg), ": ", sizeof(LIBELF_PRIVATE(msg))); > - strlcat(LIBELF_PRIVATE(msg), strerror(oserr), > - sizeof(LIBELF_PRIVATE(msg))); > + (void) snprintf(LIBELF_PRIVATE(msg), > + sizeof(LIBELF_PRIVATE(msg)), "%s: %s", > + _libelf_errors[error], strerror(oserr)); > return (const char *)&LIBELF_PRIVATE(msg); > } > return _libelf_errors[error]; > > > Comments? This looks great! I wasn't thinking of "snprintf"... I just tried compiling libelf r217 on Debian and I think the patches you committed today work well. Thanks, Kai |
From: Joseph K. <jk...@Fr...> - 2008-08-05 04:54:40
|
> 4. pmake compatibility So I took a look at pmake-1.111 in Ubuntu 8.04.1. For one, the 'unix' variable is set incorrectly: % pmake -V unix We run NetBSD. This should be changed to "We run GNU/Linux." in the installed "/usr/share/mk/sys.mk". There's a similar bug for the FreeBSD make package: % freebsd-make -V unix We run FreeBSD, not UNIX. Koshy |
From: Y G. A. N. <gir...@ap...> - 2008-08-05 11:31:53
|
On 08/08/05 04:52 -0000, Joseph Koshy said ... > % pmake -V unix > We run NetBSD. > > % freebsd-make -V unix > We run FreeBSD, not UNIX. I filed these as #493839 (pmake) and #493841 (freebsd5-buildutils) in Debian. Do we intend to use the output of these in building libelf? Giridhar -- Y Giridhar Appaji Nag | http://appaji.net/ |
From: Joseph K. <jk...@us...> - 2008-08-05 13:43:56
|
> > % pmake -V unix > > We run NetBSD. > > > > % freebsd-make -V unix > > We run FreeBSD, not UNIX. > > I filed these as #493839 (pmake) and #493841 (freebsd5-buildutils) in Debian. > Do we intend to use the output of these in building libelf? Yes, we use the contents of the 'unix' make(1) variable to determine the *target* OS in a cross-build that libelf is being built for. More info in README.build. Koshy |
From: Joseph K. <jk...@us...> - 2008-08-05 08:04:33
|
[Resending] kaiw> b) GNU and BSD tsort are probably incompatibible, you can see some kaiw> tsort warnings during compiling, but I don't know if that affects kaiw> the resulting files. The warning turns out to be caused by the following: - In "elf_memory.o", elf_memory() uses _libelf_ar_open() to open ar(1) archives. - However, in "libelf_ar.o", the _libelf_ar_open_member() function in turn uses elf_memory() on archive members inside an archive. >From the point of view of tsort(1) these two objects have a cyclic dependency. Bug #2038553 has been logged. Koshy |
From: Kai W. <kai...@gm...> - 2008-08-05 19:15:33
|
On Tue, Aug 05, 2008 at 08:02:31AM -0000, Joseph Koshy wrote: > > [Resending] > > kaiw> b) GNU and BSD tsort are probably incompatibible, you can see some > kaiw> tsort warnings during compiling, but I don't know if that affects > kaiw> the resulting files. > > The warning turns out to be caused by the following: > > - In "elf_memory.o", elf_memory() uses _libelf_ar_open() to open ar(1) > archives. > - However, in "libelf_ar.o", the _libelf_ar_open_member() function > in turn uses elf_memory() on archive members inside an archive. > > >From the point of view of tsort(1) these two objects have a cyclic > dependency. Bug #2038553 has been logged. I guess this is not a problem? Also, excerpt from the manual page of BSD tsort(1): -q Do not display informational messages about cycles. This is pri- marily intended for building libraries, where optimal ordering is not critical, and cycles occur often. and freebsd make(1) always invoke tsort with -q: % cd /usr/share/mk % grep tsort * bsd.lib.mk: @${AR} cq ${.TARGET} `lorder ${OBJS} ${STATICOBJS} | tsort -q` ${ARADD} bsd.lib.mk: @${AR} cq ${.TARGET} `NM='${NM}' lorder ${OBJS} ${STATICOBJS} | tsort -q` ${ARADD} bsd.lib.mk: @${AR} cq ${.TARGET} `lorder ${POBJS} | tsort -q` ${ARADD} bsd.lib.mk: @${AR} cq ${.TARGET} `NM='${NM}' lorder ${POBJS} | tsort -q` ${ARADD} bsd.lib.mk: `lorder ${SOBJS} | tsort -q` ${LDADD} bsd.lib.mk: `NM='${NM}' lorder ${SOBJS} | tsort -q` ${LDADD} |