--- /dev/null
+diff -ruN rpm-4.1/lib/psm.c rpm-4.1-9/lib/psm.c
+--- rpm-4.1/lib/psm.c Tue Sep 17 16:18:50 2002
++++ rpm-4.1-9/lib/psm.c Mon Oct 7 12:36:35 2002
+@@ -695,15 +695,19 @@
+ (void) sigaddset(&caught, signum);
+ switch (signum) {
+ case SIGCHLD:
+- { int status = 0;
+- pid_t reaped = waitpid(0, &status, WNOHANG);
+- int i;
+-
+- if (psmtbl.psms)
+- for (i = 0; i < psmtbl.npsms; i++) {
+- rpmpsm psm = psmtbl.psms[i];
+- if (psm->child != reaped)
+- /*@innercontinue@*/ continue;
++ while (1) {
++ int status = 0;
++ pid_t reaped = waitpid(0, &status, WNOHANG);
++ int i;
++
++ if (reaped <= 0)
++ /*@innerbreak@*/ break;
++
++ if (psmtbl.psms)
++ for (i = 0; i < psmtbl.npsms; i++) {
++ rpmpsm psm = psmtbl.psms[i];
++ if (psm->child != reaped)
++ /*@innercontinue@*/ continue;
+
+ #if _PSM_DEBUG
+ /*@-modfilesys@*/
+@@ -712,11 +716,12 @@
+ /*@=modfilesys@*/
+ #endif
+
+- psm->reaped = reaped;
+- psm->status = status;
+- /*@innerbreak@*/ break;
++ psm->reaped = reaped;
++ psm->status = status;
++ /*@innerbreak@*/ break;
++ }
+ }
+- } /*@switchbreak@*/ break;
++ /*@switchbreak@*/ break;
+ default:
+ /*@switchbreak@*/ break;
+ }
+@@ -782,26 +787,6 @@
+ }
+
+ /**
+- * Fork a new process.
+- * @param psm package state machine data
+- * @return fork(2) pid
+- */
+-static pid_t psmFork(rpmpsm psm)
+- /*@globals fileSystem, internalState @*/
+- /*@modifies fileSystem, internalState @*/
+-{
+- pid_t pid;
+-
+- if ((pid = fork()) != 0) {
+-/*@-modfilesys@*/
+-if (_psm_debug)
+-fprintf(stderr, " Fork: %p[%d:%d:%d] = %p child %d\n", psmtbl.psms, 0, psmtbl.npsms, psmtbl.nalloced, psm, pid);
+-/*@=modfilesys@*/
+- }
+- return pid;
+-}
+-
+-/**
+ * Register a child reaper, then fork a child.
+ * @param psm package state machine data
+ * @return fork(2) pid
+@@ -835,7 +820,6 @@
+ }
+ empty = psmtbl.npsms++;
+ }
+- psm->reaped = 0;
+ if (psmtbl.psms) /* XXX can't happen */
+ psmtbl.psms[empty] = rpmpsmLink(psm, "psmRegister");
+ /*@-modfilesys@*/
+@@ -844,15 +828,24 @@
+ /*@=modfilesys@*/
+
+ (void) enableSignal(SIGCHLD);
++
++ psm->reaped = 0;
++ if ((psm->child = fork()) != 0) {
++/*@-modfilesys@*/
++if (_psm_debug)
++fprintf(stderr, " Fork: %p[%d:%d:%d] = %p child %d\n", psmtbl.psms, 0, psmtbl.npsms, psmtbl.nalloced, psm, psm->child);
++/*@=modfilesys@*/
++ }
++
+ (void) sigprocmask(SIG_SETMASK, &oldMask, NULL);
+
+- return psmFork(psm);
++ return psm->child;
+ }
+
+ /**
+ * Unregister a child reaper.
+ */
+-static int psmUnregister(rpmpsm psm, pid_t child)
++static int psmWaitUnregister(rpmpsm psm, pid_t child)
+ /*@globals psmtbl, fileSystem, internalState @*/
+ /*@modifies psmtbl, fileSystem, internalState @*/
+ {
+@@ -862,6 +855,19 @@
+ (void) sigfillset(&newMask); /* block all signals */
+ (void) sigprocmask(SIG_BLOCK, &newMask, &oldMask);
+
++ /*@-infloops@*/
++ while (psm->reaped != psm->child) {
++ (void) sigprocmask(SIG_SETMASK, &oldMask, NULL);
++ (void) pause();
++ (void) sigprocmask(SIG_BLOCK, &newMask, &oldMask);
++ }
++ /*@=infloops@*/
++
++/*@-modfilesys@*/
++if (_psm_debug)
++fprintf(stderr, " Wait: %p[%d:%d:%d] = %p child %d\n", psmtbl.psms, 0, psmtbl.npsms, psmtbl.nalloced, psm, psm->child);
++/*@=modfilesys@*/
++
+ if (psmtbl.psms)
+ for (i = 0; i < psmtbl.npsms; i++) {
+ if (psmtbl.psms[i] == NULL)
+@@ -893,25 +899,6 @@
+ }
+
+ /**
+- * Return reaped pid safely (i.e. with signals blocked).
+- * @param psm package state machine data
+- * @return
+- */
+-static inline pid_t psmGetReaped(rpmpsm psm)
+- /*@globals fileSystem @*/
+- /*@modifies fileSystem @*/
+-{
+- sigset_t newMask, oldMask;
+- pid_t reaped;
+-
+- (void) sigfillset(&newMask); /* block all signals */
+- (void) sigprocmask(SIG_BLOCK, &newMask, &oldMask);
+- reaped = psm->reaped;
+- (void) sigprocmask(SIG_SETMASK, &oldMask, NULL);
+- return reaped;
+-}
+-
+-/**
+ * Wait for child process to be reaped.
+ * @param psm package state machine data
+ * @return
+@@ -921,15 +908,7 @@
+ /*@modifies psm, fileSystem, internalState @*/
+ {
+ if (psm->reaper) {
+- /*@-infloops@*/
+- while (psmGetReaped(psm) == 0)
+- (void) pause();
+- /*@=infloops@*/
+-/*@-modfilesys@*/
+-if (_psm_debug)
+-fprintf(stderr, " Wait: %p[%d:%d:%d] = %p child %d\n", psmtbl.psms, 0, psmtbl.npsms, psmtbl.nalloced, psm, psm->child);
+-/*@=modfilesys@*/
+- (void) psmUnregister(psm, psm->child);
++ (void) psmWaitUnregister(psm, psm->child);
+ } else {
+ do {
+ psm->reaped = waitpid(psm->child, &psm->status, 0);
+@@ -997,7 +976,6 @@
+ FD_t out;
+ rpmRC rc = RPMRC_OK;
+ const char *n, *v, *r;
+- pid_t pid;
+
+ if (progArgv == NULL && script == NULL)
+ return rc;
+@@ -1119,8 +1097,7 @@
+ if (out == NULL) return RPMRC_FAIL; /* XXX can't happen */
+
+ /*@-branchstate@*/
+- pid = psmRegisterFork(psm);
+- psm->child = pid;
++ (void) psmRegisterFork(psm);
+ if (psm->child == 0) {
+ const char * rootDir;
+ int pipes[2];
+
+diff -ruN rpm-4.1/rpmio/rpmlog.c rpm-4.1-9/rpmio/rpmlog.c
+--- rpm-4.1/rpmio/rpmlog.c Wed Jul 3 01:54:38 2002
++++ rpm-4.1-9/rpmio/rpmlog.c Fri Sep 20 18:33:06 2002
+@@ -179,6 +179,7 @@
+ else /* glibc 2.0 */
+ msgnb *= 2;
+ msgbuf = xrealloc(msgbuf, msgnb);
++ va_end(apc);
+ }
+ msgbuf[msgnb - 1] = '\0';
+ msg = msgbuf;
+diff -ruN rpm-4.1/tools/sections.c rpm-4.1-9/tools/sections.c
+--- rpm-4.1/tools/sections.c Thu Aug 22 19:57:41 2002
++++ rpm-4.1-9/tools/sections.c Sun Oct 6 07:30:41 2002
+@@ -24,38 +24,168 @@
+ } UnstripInfo32;
+
+ typedef struct {
+- Elf32_Off orig_e_shoff;
+- Elf32_Off n_sections;
++ Elf64_Off orig_e_shoff;
++ Elf64_Off n_sections;
+ UnstripInfoSection64 sections[1];
+ } UnstripInfo64;
+
++static uint32_t
++elf_32_to_file (uint32_t x, int file_is_little_endian)
++{
++ volatile uint32_t out;
++ unsigned char *outbytes;
++
++ outbytes = (unsigned char *)&out;
++ if (file_is_little_endian)
++ {
++ outbytes[0] = (x >> 0) & 0xff;
++ outbytes[1] = (x >> 8) & 0xff;
++ outbytes[2] = (x >> 16) & 0xff;
++ outbytes[3] = (x >> 24) & 0xff;
++ }
++ else /* big endian */
++ {
++ outbytes[0] = (x >> 24) & 0xff;
++ outbytes[1] = (x >> 16) & 0xff;
++ outbytes[2] = (x >> 8) & 0xff;
++ outbytes[3] = (x >> 0) & 0xff;
++ }
++
++ return out;
++}
++
++static uint64_t
++elf_64_to_file (uint64_t x, int file_is_little_endian)
++{
++ volatile uint64_t out;
++ unsigned char *outbytes;
++ int i;
++
++ outbytes = (unsigned char *)&out;
++ if (file_is_little_endian)
++ {
++ for (i = 0; i < 8; i++)
++ outbytes[i] = (x >> (8*i)) & 0xff;
++ }
++ else /* big endian */
++ {
++ for (i = 0; i < 8; i++)
++ outbytes[7-i] = (x >> (8*i)) & 0xff;
++ }
++
++ return out;
++}
+
+ static Elf32_Word
+ word32_to_file (Elf32_Word x, Elf *elf)
+ {
+- /* FIXME: implement */
+- return x;
++ Elf32_Ehdr *ehdr = elf32_getehdr (elf);
++ return elf_32_to_file (x, ehdr->e_ident[EI_DATA] & ELFDATA2LSB);
+ }
+
+ static Elf32_Off
+ off32_to_file (Elf32_Off x, Elf *elf)
+ {
+- /* FIXME: implement */
+- return x;
++ Elf32_Ehdr *ehdr = elf32_getehdr (elf);
++ return elf_32_to_file (x, ehdr->e_ident[EI_DATA] & ELFDATA2LSB);
++}
++
++static Elf64_Word
++word64_to_file (Elf64_Word x, Elf *elf)
++{
++ Elf64_Ehdr *ehdr = elf64_getehdr (elf);
++ return elf_32_to_file (x, ehdr->e_ident[EI_DATA] & ELFDATA2LSB);
++}
++
++static Elf64_Off
++off64_to_file (Elf64_Off x, Elf *elf)
++{
++ Elf64_Ehdr *ehdr = elf64_getehdr (elf);
++ return elf_64_to_file (x, ehdr->e_ident[EI_DATA] & ELFDATA2LSB);
++}
++
++static uint32_t
++elf_32_from_file (uint32_t x, int file_is_little_endian)
++{
++ unsigned char *inbytes;
++
++ inbytes = (unsigned char *)&x;
++ if (file_is_little_endian)
++ {
++ return
++ (inbytes[0] << 0) |
++ (inbytes[1] << 8) |
++ (inbytes[2] << 16) |
++ (inbytes[3] << 24);
++ }
++ else /* big endian */
++ {
++ return
++ (inbytes[0] << 24) |
++ (inbytes[1] << 16) |
++ (inbytes[2] << 8) |
++ (inbytes[3] << 0);
++ }
++}
++
++static uint64_t
++elf_64_from_file (uint64_t x, int file_is_little_endian)
++{
++ unsigned char *inbytes;
++
++ inbytes = (unsigned char *)&x;
++ if (file_is_little_endian)
++ {
++ return
++ ((uint64_t)inbytes[0] << 0) |
++ ((uint64_t)inbytes[1] << 8) |
++ ((uint64_t)inbytes[2] << 16) |
++ ((uint64_t)inbytes[3] << 24) |
++ ((uint64_t)inbytes[4] << 32) |
++ ((uint64_t)inbytes[5] << 40) |
++ ((uint64_t)inbytes[6] << 48) |
++ ((uint64_t)inbytes[7] << 56);
++ }
++ else /* big endian */
++ {
++ return
++ ((uint64_t)inbytes[0] << 56) |
++ ((uint64_t)inbytes[1] << 48) |
++ ((uint64_t)inbytes[2] << 40) |
++ ((uint64_t)inbytes[3] << 32) |
++ ((uint64_t)inbytes[4] << 24) |
++ ((uint64_t)inbytes[5] << 16) |
++ ((uint64_t)inbytes[6] << 8) |
++ ((uint64_t)inbytes[7] << 0);
++ }
+ }
+
+ static Elf32_Word
+ word32_from_file (Elf32_Word x, Elf *elf)
+ {
+- /* FIXME: implement */
+- return x;
++ Elf32_Ehdr *ehdr = elf32_getehdr (elf);
++ return elf_32_from_file (x, ehdr->e_ident[EI_DATA] & ELFDATA2LSB);
+ }
+
+ static Elf32_Off
+ off32_from_file (Elf32_Off x, Elf *elf)
+ {
+- /* FIXME: implement */
+- return x;
++ Elf32_Ehdr *ehdr = elf32_getehdr (elf);
++ return elf_32_from_file (x, ehdr->e_ident[EI_DATA] & ELFDATA2LSB);
++}
++
++static Elf64_Word
++word64_from_file (Elf64_Word x, Elf *elf)
++{
++ Elf64_Ehdr *ehdr = elf64_getehdr (elf);
++ return elf_32_from_file (x, ehdr->e_ident[EI_DATA] & ELFDATA2LSB);
++}
++
++static Elf64_Off
++off64_from_file (Elf64_Off x, Elf *elf)
++{
++ Elf64_Ehdr *ehdr = elf64_getehdr (elf);
++ return elf_64_from_file (x, ehdr->e_ident[EI_DATA] & ELFDATA2LSB);
+ }
+
+ static void
+@@ -93,7 +223,29 @@
+ Elf *elf,
+ Elf_Data *data)
+ {
++ UnstripInfo64 *info64;
++ int i;
++
+ data->d_align = 8;
++
++ data->d_size =
++ /* orig_e_shoff */ sizeof (Elf64_Off) +
++ /* n_sections */ sizeof (Elf64_Off) +
++ /* sections */ info->n_sections * sizeof (UnstripInfoSection64);
++
++ data->d_buf = calloc (1, data->d_size);
++
++ info64 = (UnstripInfo64 *) data->d_buf;
++
++ info64->orig_e_shoff = off64_to_file (info->orig_e_shoff, elf);
++ info64->n_sections = off64_to_file (info->n_sections, elf);
++
++ for (i = 0; i < info->n_sections; i++)
++ {
++ info64->sections[i].debug_section = word64_to_file (info->sections[i].debug_section, elf);
++ info64->sections[i].name = word64_to_file (info->sections[i].name, elf);
++ info64->sections[i].orig_offset = off64_to_file (info->sections[i].orig_offset, elf);
++ }
+ }
+
+ void
+@@ -101,11 +253,18 @@
+ Elf *elf,
+ Elf_Data *data)
+ {
++ GElf_Ehdr ehdr;
++
+ data->d_type = ELF_T_BYTE;
+ data->d_off = 0;
+
+- /* FIXME: use right version */
+- unstrip_info_to_data32 (info, elf, data);
++ gelf_getehdr (elf, &ehdr);
++ if (ehdr.e_ident[EI_CLASS] == ELFCLASS32)
++ unstrip_info_to_data32 (info, elf, data);
++ else if (ehdr.e_ident[EI_CLASS] == ELFCLASS64)
++ unstrip_info_to_data64 (info, elf, data);
++ else
++ fprintf (stderr, "Warning. unsupported elf class\n");
+ }
+
+ void
+@@ -130,23 +289,49 @@
+ }
+ }
+
++void
++unstrip_info_from_data64 (UnstripInfo *info,
++ Elf *elf,
++ Elf_Data *data)
++{
++ UnstripInfo64 *info64;
++ int i;
++
++ info64 = (UnstripInfo64 *) data->d_buf;
++
++ info->orig_e_shoff = off64_from_file (info64->orig_e_shoff, elf);
++ info->n_sections = off64_from_file (info64->n_sections, elf);
++
++ info->sections = calloc (info->n_sections, sizeof (UnstripInfoSection));
++ for (i = 0; i < info->n_sections; i++)
++ {
++ info->sections[i].debug_section = word64_from_file (info64->sections[i].debug_section, elf);
++ info->sections[i].name = word64_from_file (info64->sections[i].name, elf);
++ info->sections[i].orig_offset = off64_from_file (info64->sections[i].orig_offset, elf);
++ }
++}
++
+ UnstripInfo *
+ unstrip_info_from_data (Elf *elf,
+ Elf_Data *data)
+ {
++ GElf_Ehdr ehdr;
++
+ UnstripInfo *info;
+
+ info = malloc (sizeof (UnstripInfo));
+
+- /* FIXME: use right version */
+- unstrip_info_from_data32 (info,
+- elf,
+- data);
++ gelf_getehdr (elf, &ehdr);
++ if (ehdr.e_ident[EI_CLASS] == ELFCLASS32)
++ unstrip_info_from_data32 (info, elf, data);
++ else if (ehdr.e_ident[EI_CLASS] == ELFCLASS64)
++ unstrip_info_from_data64 (info, elf, data);
++ else
++ fprintf (stderr, "Warning. unsupported elf class\n");
+
+ return info;
+ }
+
+-
+ static void
+ debug_link_to_data32 (DebugLink *debuglink,
+ Elf *elf,
+@@ -169,17 +354,47 @@
+ p = data->d_buf + namelen_aligned;
+
+ *(Elf32_Word *)p = word32_to_file (debuglink->checksum, elf);
+- p += sizeof (Elf32_Word);
++}
++
++static void
++debug_link_to_data64 (DebugLink *debuglink,
++ Elf *elf,
++ Elf_Data *data)
++{
++ size_t namelen_aligned;
++ char *p;
++
++ data->d_align = 4;
++
++ namelen_aligned = align_up (strlen(debuglink->filename) + 1, 4);
++
++ data->d_size =
++ /* name */ namelen_aligned +
++ /* checksum */ sizeof (Elf64_Word);
++
++ data->d_buf = calloc (1, data->d_size);
++
++ strcpy (data->d_buf, debuglink->filename);
++ p = data->d_buf + namelen_aligned;
++
++ *(Elf64_Word *)p = word64_to_file (debuglink->checksum, elf);
+ }
+
+ void
+ debug_link_to_data (DebugLink *debuglink, Elf *elf, Elf_Data *data)
+ {
++ GElf_Ehdr ehdr;
++
+ data->d_type = ELF_T_BYTE;
+ data->d_off = 0;
+
+- /* FIXME: use right version */
+- debug_link_to_data32 (debuglink, elf, data);
++ gelf_getehdr (elf, &ehdr);
++ if (ehdr.e_ident[EI_CLASS] == ELFCLASS32)
++ debug_link_to_data32 (debuglink, elf, data);
++ else if (ehdr.e_ident[EI_CLASS] == ELFCLASS64)
++ debug_link_to_data64 (debuglink, elf, data);
++ else
++ fprintf (stderr, "Warning. unsupported elf class\n");
+ }
+
+ void
+@@ -197,21 +412,41 @@
+ p = data->d_buf + namelen_aligned;
+
+ debuglink->checksum = word32_from_file (*(Elf32_Word *)p, elf);
+- p += sizeof (Elf32_Word);
++}
++
++void
++debug_link_from_data64 (DebugLink *debuglink,
++ Elf *elf,
++ Elf_Data *data)
++{
++ size_t namelen_aligned;
++ char *p;
++
++ debuglink->filename = strdup (data->d_buf);
++
++ namelen_aligned = align_up (strlen (debuglink->filename) + 1, 4);
++
++ p = data->d_buf + namelen_aligned;
++
++ debuglink->checksum = word64_from_file (*(Elf64_Word *)p, elf);
+ }
+
+
+ DebugLink *
+ debug_link_from_data (Elf *elf, Elf_Data *data)
+ {
++ GElf_Ehdr ehdr;
+ DebugLink *debuglink;
+
+ debuglink = malloc (sizeof (DebugLink));
+
+- /* FIXME: use right version */
+- debug_link_from_data32 (debuglink,
+- elf,
+- data);
++ gelf_getehdr (elf, &ehdr);
++ if (ehdr.e_ident[EI_CLASS] == ELFCLASS32)
++ debug_link_from_data32 (debuglink, elf, data);
++ else if (ehdr.e_ident[EI_CLASS] == ELFCLASS64)
++ debug_link_from_data64 (debuglink, elf, data);
++ else
++ fprintf (stderr, "Warning. unsupported elf class\n");
+
+ return debuglink;
+ }
+diff -ruN rpm-4.1/tools/striptofile.c rpm-4.1-9/tools/striptofile.c
+--- rpm-4.1/tools/striptofile.c Thu Aug 22 21:08:25 2002
++++ rpm-4.1-9/tools/striptofile.c Sun Oct 6 07:30:41 2002
+@@ -201,7 +201,7 @@
+ /* Update section header stringtab ref */
+ gelf_getehdr (out_elf, &out_ehdr);
+ out_ehdr.e_shstrndx = section_map[out_ehdr.e_shstrndx];
+- out_ehdr.e_shoff = align_up (last_offset, 4);
++ out_ehdr.e_shoff = align_up (last_offset, 8);
+ gelf_update_ehdr(out_elf, &out_ehdr);
+
+ /* Update section header links */
+@@ -402,6 +402,7 @@
+ Elf *elf, *out_elf;
+ int fd, out;
+ const char *origname;
++ char *origname_base;
+ char *debugname, *strippedname;
+ DebugLink *debuglink;
+ poptContext optCon; /* context for parsing command-line options */
+@@ -433,14 +434,13 @@
+
+ origname = args[0];
+
+- if (output_dir) {
+- const char * bn = strrchr(origname, '/');
+- if ((bn = strrchr(origname, '/')) != NULL)
+- bn++;
+- else
+- bn = origname;
+- debugname = strconcat (output_dir, "/", bn, ".debug", NULL);
+- } else
++ if (output_dir)
++ {
++ origname_base = path_basename (origname);
++ debugname = strconcat (output_dir, "/", origname_base, ".debug", NULL);
++ free (origname_base);
++ }
++ else
+ debugname = strconcat (origname, ".debug", NULL);
+
+ strippedname = strconcat (origname, ".XXXXXX", NULL);