RPM z LUA
Artur Frysiak
wiget w pld-linux.org
Nie, 21 Mar 2004, 23:22:15 CET
On Fri, Mar 19, 2004 at 01:04:54AM +0100, Jakub Bogusz wrote:
> On Thu, Mar 18, 2004 at 11:14:44PM +0100, Artur Frysiak wrote:
> > Witam.
> > Zabieram się za przygotowanie nowego snapa rpma ponieważ posiada on
> > wsparcie do wbudowanego języka skryptowego lua.
> > Korzyści płynące z lua to możliwość pisania skryptów %pre/%post które
> > nie będą wymagały sh. Może się to okazać bardzo przydatne w pakietach
> > typu FHS, setup, glibc itp.
> >
> > Cały eksperyment zostanie przeprowadzony na branchu DEVEL.
>
> Popatrzysz przy okazji, czy nie ma jakichś poprawek w readelf?
> W poprzednim snapie były błędy, ale po uaktualnieniu (z nowszego file)
> coś się sypie na amd64 i nie mam jak zdiagnozować bez dostępu do
> maszyny.
revision 1.4
date: 2004/03/16 17:13:25; author: jbj; state: Exp; lines: +37 -14
- fix: grrr, skip notes on non-i386 entirely.
----------------------------
revision 1.3
date: 2004/03/13 13:34:45; author: jbj; state: Exp; lines: +30 -31
- fix: handle elf64 note sections correctly.
i podobne zmiany w branczach rpm-4_3 oraz rpm-4_2.
Łatka w załączniku.
Pozdrawiam
--
Artur Frysiak
http://www.pld-linux.org/
-------------- następna część ---------
Index: file/src/readelf.c
===================================================================
RCS file: /cvs/devel/rpm/file/src/readelf.c,v
retrieving revision 1.2
retrieving revision 1.4
diff -u -r1.2 -r1.4
--- file/src/readelf.c 15 Apr 2003 15:19:30 -0000 1.2
+++ file/src/readelf.c 16 Mar 2004 17:13:25 -0000 1.4
@@ -88,6 +88,7 @@
#define shs_type (fm->cls == ELFCLASS32 \
? getu32(fm, sh32.sh_type) \
: getu32(fm, sh64.sh_type))
+
#define ph_addr (fm->cls == ELFCLASS32 \
? (void *) &ph32 \
: (void *) &ph64)
@@ -103,9 +104,10 @@
#define ph_align (fm->cls == ELFCLASS32 \
? (ph32.p_align ? getu32(fm, ph32.p_align) : 4) \
: (ph64.p_align ? getu64(fm, ph64.p_align) : 4))
-#define nh_size (fm->cls == ELFCLASS32 \
- ? sizeof *nh32 \
- : sizeof *nh64)
+#define ph_filesz (fm->cls == ELFCLASS32 \
+ ? getu32(fm, ph32.p_filesz) \
+ : getu64(fm, ph64.p_filesz))
+
#define nh_type (fm->cls == ELFCLASS32 \
? getu32(fm, nh32->n_type) \
: getu32(fm, nh64->n_type))
@@ -170,8 +172,11 @@
char *linking_style = "statically";
char *shared_libraries = "";
char nbuf[BUFSIZ];
- int bufsize;
- size_t offset, nameoffset;
+ int nb;
+ size_t nbufsize, offset, end, noff, doff;
+ size_t align = (fm->cls == ELFCLASS32 ? 4 : 8);
+#define ALIGNED_LEN(len) (((len) + align - 1) & ~(align - 1))
+ int printed;
if (size != ph_size) {
error(EXIT_FAILURE, 0, "corrupted program header size.\n");
@@ -184,11 +189,19 @@
}
for ( ; num; num--) {
- if (read(fm->fd, ph_addr, size) == -1) {
+ /* Read the program header data. */
+ nb = read(fm->fd, ph_addr, size);
+ if (nb == -1) {
error(EXIT_FAILURE, 0, "read failed (%s).\n", strerror(errno));
/*@notreached@*/
}
+ /* XXX Elf64 notes cannot be read, so don't attempt for now. */
+#if !defined(__i386__)
+ if (ph_type == PT_NOTE)
+ break;
+#endif
+
switch (ph_type) {
case PT_DYNAMIC:
linking_style = "dynamically";
@@ -205,50 +218,56 @@
error(EXIT_FAILURE, 0, "lseek failed (%s).\n", strerror(errno));
/*@notreached@*/
}
- bufsize = read(fm->fd, nbuf, sizeof(nbuf));
- if (bufsize == -1) {
+
+ /* XXX Read only the notes section. */
+ nbufsize = (ph_filesz < sizeof(nbuf)
+ ? ph_filesz : sizeof(nbuf));
+ nb = read(fm->fd, nbuf, nbufsize);
+ if (nb == -1) {
error(EXIT_FAILURE, 0, ": " "read failed (%s).\n",
strerror(errno));
/*@notreached@*/
}
offset = 0;
+ printed = 0;
for (;;) {
- if (offset >= bufsize)
+ end = offset + 12;
+ if (end >= nb)
/*@innerbreak@*/ break;
+
if (fm->cls == ELFCLASS32)
nh32 = (Elf32_Nhdr *)&nbuf[offset];
else
nh64 = (Elf64_Nhdr *)&nbuf[offset];
- offset += nh_size;
-
- if (offset + nh_namesz >= bufsize) {
- /*
- * We're past the end of the buffer.
- */
- /*@innerbreak@*/ break;
- }
- nameoffset = offset;
- offset += nh_namesz;
- offset = ((offset+ph_align-1)/ph_align)*ph_align;
+ offset = end; /* skip note header. */
- if ((nh_namesz == 0) && (nh_descsz == 0)) {
- /*
- * We're out of note headers.
- */
+ /* XXX Avoid notes that are not 1-16 bytes */
+ if (nh_namesz <= 0 || nh_descsz <= 0)
+ break;
+ if (nh_namesz > 16 || nh_descsz > 16)
+ break;
+
+ end = offset + ALIGNED_LEN (nh_namesz)
+ + ALIGNED_LEN (nh_descsz);
+ if (end > nb)
/*@innerbreak@*/ break;
- }
- if (offset + nh_descsz >= bufsize)
- /*@innerbreak@*/ break;
+ noff = offset;
+ doff = ALIGNED_LEN(offset + nh_namesz);
+ offset = end;
+
+ if (printed)
+ continue;
if (nh_namesz == 4 &&
- strcmp(&nbuf[nameoffset], "GNU") == 0 &&
+ strcmp(&nbuf[noff], "GNU") == 0 &&
nh_type == NT_GNU_VERSION &&
nh_descsz == 16) {
uint32_t *desc =
- (uint32_t *)&nbuf[offset];
+ (uint32_t *)&nbuf[doff];
+ if (!printed)
file_printf(fm, ", for GNU/");
switch (getu32(fm, desc[0])) {
case GNU_OS_LINUX:
@@ -268,10 +287,11 @@
getu32(fm, desc[1]),
getu32(fm, desc[2]),
getu32(fm, desc[3]));
+ printed = 1;
}
if (nh_namesz == 7 &&
- strcmp(&nbuf[nameoffset], "NetBSD") == 0 &&
+ strcmp(&nbuf[noff], "NetBSD") == 0 &&
nh_type == NT_NETBSD_VERSION &&
nh_descsz == 4) {
file_printf(fm, ", for NetBSD");
@@ -279,14 +299,15 @@
* Version number is stuck at 199905,
* and hence is basically content-free.
*/
+ printed = 1;
}
if (nh_namesz == 8 &&
- strcmp(&nbuf[nameoffset], "FreeBSD") == 0 &&
+ strcmp(&nbuf[noff], "FreeBSD") == 0 &&
nh_type == NT_FREEBSD_VERSION &&
nh_descsz == 4) {
uint32_t desc = getu32(fm,
- *(uint32_t *)&nbuf[offset]);
+ *(uint32_t *)&nbuf[doff]);
file_printf(fm, ", for FreeBSD");
/*
* Contents is __FreeBSD_version,
@@ -303,14 +324,16 @@
if (desc / 1000 % 10 > 0)
file_printf(fm, ".%d",
desc / 1000 % 10);
+ printed = 1;
}
if (nh_namesz == 8 &&
- strcmp(&nbuf[nameoffset], "OpenBSD") == 0 &&
+ strcmp(&nbuf[noff], "OpenBSD") == 0 &&
nh_type == NT_OPENBSD_VERSION &&
nh_descsz == 4) {
file_printf(fm, ", for OpenBSD");
/* Content of note is always 0 */
+ printed = 1;
}
}
if ((lseek(fm->fd, ph_offset + offset, SEEK_SET)) == -1) {
@@ -389,7 +412,7 @@
unsigned char c;
int i, j;
char nbuf[BUFSIZ];
- int bufsize;
+ int nb;
int os_style = -1;
if (size != ph_size) {
@@ -421,26 +444,26 @@
error(EXIT_FAILURE, 0, "lseek failed (%s).\n", strerror(errno));
/*@notreached@*/
}
- bufsize = read(fm->fd, nbuf, BUFSIZ);
- if (bufsize == -1) {
+ nb = read(fm->fd, nbuf, BUFSIZ);
+ if (nb == -1) {
error(EXIT_FAILURE, 0, ": " "read failed (%s).\n", strerror(errno));
/*@notreached@*/
}
offset = 0;
for (;;) {
- if (offset >= bufsize)
+ if (offset >= nb)
/*@innerbreak@*/ break;
if (fm->cls == ELFCLASS32)
nh32 = (Elf32_Nhdr *)&nbuf[offset];
else
nh64 = (Elf64_Nhdr *)&nbuf[offset];
- offset += nh_size;
+ offset += 12;
/*
* Check whether this note has the name "CORE" or
* "FreeBSD", or "NetBSD-CORE".
*/
- if (offset + nh_namesz >= bufsize) {
+ if (offset + nh_namesz >= nb) {
/*
* We're past the end of the buffer.
*/
@@ -529,7 +552,7 @@
* the end of the buffer; if
* we are, just give up.
*/
- if (noffset >= bufsize)
+ if (noffset >= nb)
goto tryanother;
/*
@@ -615,7 +638,6 @@
|| fm->buf[EI_MAG2] != ELFMAG2 || fm->buf[EI_MAG3] != ELFMAG3)
return;
-
fm->cls = fm->buf[EI_CLASS];
if (fm->cls == ELFCLASS32) {
Więcej informacji o liście dyskusyjnej pld-devel-pl