From 9aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Fri, 18 May 2007 08:59:43 +0000 Subject: [PATCH] src/ 2007-05-18 Roland McGrath * unstrip.c (copy_elided_sections): Match up non-NOBITS sections with stripped file, so as not to duplicate a section copied in both. * strip.c (handle_elf): Keep SHT_NOTE section copies in the debug file. tests/ 2007-05-18 Roland McGrath * run-strip-test4.sh (stripped, debugfile): Use new reference files. * testfile37.bz2: New data file. * testfile37.debug.bz2: New data file. * run-unstrip-test2.sh: New file. * Makefile.am (TESTS, EXTRA_DIST): Add them. --- ChangeLog | 4 + configure.ac | 3 +- libdwfl/ChangeLog | 20 ++ libdwfl/linux-kernel-modules.c | 34 +- libdwfl/offline.c | 54 ++- src/ChangeLog | 55 +++ src/addr2line.c | 3 +- src/elflint.c | 4 +- src/strip.c | 51 +-- src/unstrip.c | 570 +++++++++++++++++++++++------- tests/ChangeLog | 25 ++ tests/Makefile.am | 12 +- tests/run-dwfl-bug-offline-rel.sh | 36 ++ tests/run-strip-test.sh | 12 +- tests/run-strip-test4.sh | 4 +- tests/run-strip-test6.sh | 4 +- tests/run-unstrip-test.sh | 41 +++ tests/run-unstrip-test2.sh | 5 + tests/testfile35.bz2 | Bin 0 -> 1643 bytes tests/testfile35.debug.bz2 | Bin 0 -> 9106 bytes tests/testfile36.bz2 | Bin 0 -> 714 bytes tests/testfile36.debug.bz2 | Bin 0 -> 24909 bytes tests/testfile37.bz2 | Bin 0 -> 3140 bytes tests/testfile37.debug.bz2 | Bin 0 -> 28522 bytes 24 files changed, 758 insertions(+), 179 deletions(-) create mode 100755 tests/run-dwfl-bug-offline-rel.sh create mode 100755 tests/run-unstrip-test.sh create mode 100755 tests/run-unstrip-test2.sh create mode 100644 tests/testfile35.bz2 create mode 100644 tests/testfile35.debug.bz2 create mode 100644 tests/testfile36.bz2 create mode 100644 tests/testfile36.debug.bz2 create mode 100644 tests/testfile37.bz2 create mode 100644 tests/testfile37.debug.bz2 diff --git a/ChangeLog b/ChangeLog index 760c4d2d8..b9f088a0b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2007-05-16 Roland McGrath + + * configure.ac (AM_INIT_AUTOMAKE): Use -Wno-portability. + 2006-11-02 Roland McGrath * Makefile.am (EXTRA_DIST): Add EXCEPTION file. diff --git a/configure.ac b/configure.ac index 596219e56..b6856ccd8 100644 --- a/configure.ac +++ b/configure.ac @@ -25,7 +25,8 @@ AC_CONFIG_FILES([config/Makefile]) AC_COPYRIGHT([Copyright (C) 1996-2003, 2004, 2005, 2006, 2007 Red Hat, Inc.]) AC_PREREQ(2.59) dnl Minimum Autoconf version required. -AM_INIT_AUTOMAKE([gnits 1.7]) +dnl We use GNU make extensions; automake 1.10 defaults to -Wportability. +AM_INIT_AUTOMAKE([gnits 1.7 -Wno-portability]) AM_MAINTAINER_MODE dnl Unique ID for this build. diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog index 39c7ee29d..6e6407ae2 100644 --- a/libdwfl/ChangeLog +++ b/libdwfl/ChangeLog @@ -1,3 +1,23 @@ +2007-05-17 Roland McGrath + + * linux-kernel-modules.c (dwfl_linux_kernel_report_offline): Look at + whole /lib/modules/VERSION tree, not just /lib/modules/VERSION/kernel. + (dwfl_linux_kernel_find_elf): Likewise. + + * linux-kernel-modules.c (dwfl_linux_kernel_report_modules): Use + getline and sscanf instead of fscanf. + +2007-05-08 Roland McGrath + + * offline.c (dwfl_offline_section_address): Don't assume section + numbers match between stripped and debuginfo files. Instead, assume + only that the ordering among SHF_ALLOC sections matches. + + * linux-kernel-modules.c (report_kernel): Change RELEASE argument to + pointer to string. + (dwfl_linux_kernel_report_offline): Update caller. + (dwfl_linux_kernel_report_kernel): Likewise. + 2007-04-23 Roland McGrath * argp-std.c (options): Fix group title string. diff --git a/libdwfl/linux-kernel-modules.c b/libdwfl/linux-kernel-modules.c index 2aaa25acb..98957521b 100644 --- a/libdwfl/linux-kernel-modules.c +++ b/libdwfl/linux-kernel-modules.c @@ -139,21 +139,24 @@ find_kernel_elf (Dwfl *dwfl, const char *release, char **fname) } static int -report_kernel (Dwfl *dwfl, const char *release, +report_kernel (Dwfl *dwfl, const char **release, int (*predicate) (const char *module, const char *file)) { if (dwfl == NULL) return -1; - if (release == NULL) + const char *release_string = release == NULL ? NULL : *release; + if (release_string == NULL) { - release = kernel_release (); - if (release == NULL) + release_string = kernel_release (); + if (release_string == NULL) return errno; + if (release != NULL) + *release = release_string; } char *fname; - int fd = find_kernel_elf (dwfl, release, &fname); + int fd = find_kernel_elf (dwfl, release_string, &fname); int result = 0; if (fd < 0) @@ -198,17 +201,17 @@ dwfl_linux_kernel_report_offline (Dwfl *dwfl, const char *release, const char *file)) { /* First report the kernel. */ - int result = report_kernel (dwfl, release, predicate); + int result = report_kernel (dwfl, &release, predicate); if (result == 0) { - /* Do "find /lib/modules/RELEASE/kernel -name *.ko". */ + /* Do "find /lib/modules/RELEASE -name *.ko". */ char *modulesdir[] = { NULL, NULL }; if (release[0] == '/') modulesdir[0] = (char *) release; else { - if (asprintf (&modulesdir[0], MODULEDIRFMT "/kernel", release) < 0) + if (asprintf (&modulesdir[0], MODULEDIRFMT, release) < 0) return errno; } @@ -394,10 +397,10 @@ dwfl_linux_kernel_find_elf (Dwfl_Module *mod __attribute__ ((unused)), if (!strcmp (module_name, KERNEL_MODNAME)) return find_kernel_elf (mod->dwfl, release, file_name); - /* Do "find /lib/modules/`uname -r`/kernel -name MODULE_NAME.ko". */ + /* Do "find /lib/modules/`uname -r` -name MODULE_NAME.ko". */ char *modulesdir[] = { NULL, NULL }; - if (asprintf (&modulesdir[0], MODULEDIRFMT "/kernel", release) < 0) + if (asprintf (&modulesdir[0], MODULEDIRFMT, release) < 0) return -1; FTS *fts = fts_open (modulesdir, FTS_LOGICAL | FTS_NOSTAT, NULL); @@ -609,14 +612,21 @@ dwfl_linux_kernel_report_modules (Dwfl *dwfl) Dwarf_Addr modaddr; unsigned long int modsz; char modname[128]; - while (fscanf (f, "%128s %lu %*s %*s %*s %" PRIx64 "\n", - modname, &modsz, &modaddr) == 3) + char *line = NULL; + size_t linesz = 0; + /* We can't just use fscanf here because it's not easy to distinguish \n + from other whitespace so as to take the optional word following the + address but always stop at the end of the line. */ + while (getline (&line, &linesz, f) > 0 + && sscanf (line, "%128s %lu %*s %*s %*s %" PRIx64 " %*s\n", + modname, &modsz, &modaddr) == 3) if (INTUSE(dwfl_report_module) (dwfl, modname, modaddr, modaddr + modsz) == NULL) { result = -1; break; } + free (line); if (result == 0) result = ferror_unlocked (f) ? errno : feof_unlocked (f) ? 0 : ENOEXEC; diff --git a/libdwfl/offline.c b/libdwfl/offline.c index beeb0abf2..0a0645ef3 100644 --- a/libdwfl/offline.c +++ b/libdwfl/offline.c @@ -65,21 +65,53 @@ dwfl_offline_section_address (Dwfl_Module *mod, const GElf_Shdr *shdr __attribute__ ((unused)), Dwarf_Addr *addr) { - GElf_Shdr shdr_mem; - GElf_Shdr *main_shdr = gelf_getshdr (elf_getscn (mod->main.elf, shndx), - &shdr_mem); - if (unlikely (main_shdr == NULL)) - return -1; - + assert (mod->e_type == ET_REL); assert (shdr->sh_addr == 0); assert (shdr->sh_flags & SHF_ALLOC); - assert (main_shdr->sh_flags == shdr->sh_flags); - if (main_shdr->sh_addr != 0) - assert (mod->symfile != &mod->main); + if (mod->symfile == &mod->main) + { + /* Because the actual address is zero, we failed to notice + we in fact had the right address cached already. */ + *addr = 0; + return 0; + } + + /* The section numbers might not match between the two files. + The best we can rely on is the order of SHF_ALLOC sections. */ + + Elf_Scn *ourscn = elf_getscn (mod->symfile->elf, shndx); + Elf_Scn *scn = NULL; + uint_fast32_t skip_alloc = 0; + while ((scn = elf_nextscn (mod->symfile->elf, scn)) != ourscn) + { + assert (scn != NULL); + GElf_Shdr shdr_mem; + GElf_Shdr *sh = gelf_getshdr (scn, &shdr_mem); + if (unlikely (sh == NULL)) + return -1; + if (sh->sh_flags & SHF_ALLOC) + ++skip_alloc; + } + + scn = NULL; + while ((scn = elf_nextscn (mod->main.elf, scn)) != NULL) + { + GElf_Shdr shdr_mem; + GElf_Shdr *main_shdr = gelf_getshdr (elf_getscn (mod->main.elf, shndx), + &shdr_mem); + if (unlikely (main_shdr == NULL)) + return -1; + if ((main_shdr->sh_flags & SHF_ALLOC) && skip_alloc-- == 0) + { + assert (main_shdr->sh_flags == shdr->sh_flags); + *addr = main_shdr->sh_addr; + return 0; + } + } - *addr = main_shdr->sh_addr; - return 0; + /* This should never happen. */ + return -1; } INTDEF (dwfl_offline_section_address) diff --git a/src/ChangeLog b/src/ChangeLog index 39b64ff09..d22769513 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,58 @@ +2007-05-18 Roland McGrath + + * unstrip.c (copy_elided_sections): Match up non-NOBITS sections with + stripped file, so as not to duplicate a section copied in both. + + * strip.c (handle_elf): Keep SHT_NOTE section copies in the debug file. + +2007-05-17 Roland McGrath + + * unstrip.c (copy_elided_sections): Don't call gelf_newphdr for 0. + + * unstrip.c (handle_file): Tweak BIAS != 0 warning. + + * unstrip.c (handle_file): Take new arg CREATE_DIRS. If set, + call make_directories here. + (handle_explicit_files): Take new arg CREATE_DIRS, pass it down. + (handle_dwfl_module): Likewise. + (handle_implicit_modules): Update callers. + (handle_output_dir_module): Likewise. Don't do make_directories here. + + * unstrip.c (get_section_name): New function, broken out of ... + (copy_elided_sections): here. Update callers. + (find_alloc_section): Broken out of ... + (copy_elided_sections): ... here. Update caller. + (symtab_count_leading_section_symbols): Take new arg NEWSYMDATA, + update STT_SECTION symbols' st_value fields as a side effect. + (check_symtab_section_symbols): Update caller. + (add_new_section_symbols): Set st_value in symbols added. + (collect_symbols): Reset S->value for STT_SECTION symbols recorded. + Take new arg SPLIT_BSS. Adjust S->shndx recorded for symbols moved + from .bss to .dynbss. + (find_alloc_sections_prelink): New function. Associate debug file + allocated SHT_NOBITS shdrs with stripped moved by prelink via + .gnu.prelink_undo information. + (copy_elided_sections): Call it when we couldn't find every allocated + section. Don't use a debug file non-NOBITS section if SHF_ALLOC. + Take STRIPPED_EHDR arg instead of E_TYPE and PHNUM. + (handle_file): Update callers. + + * unstrip.c (copy_elided_sections): Ignore unfound unallocated section + named ".comment". + + * elflint.c (check_sections): Fix association of segments with + sections when p_memsz > p_filesz. + +2007-04-29 Roland McGrath + + * addr2line.c (options, main): Tweak argp group settings to fix + usage output. + +2007-04-28 Roland McGrath + + * strip.c (handle_elf): Update debug file's SHT_NOBITS sections' + sizes to match sections adjusted in the stripped file. + 2007-04-24 Roland McGrath * elfcmp.c (OPT_HASH_INEXACT): New macro. diff --git a/src/addr2line.c b/src/addr2line.c index e133e7af9..6f6de1f7e 100644 --- a/src/addr2line.c +++ b/src/addr2line.c @@ -61,7 +61,7 @@ const char *argp_program_bug_address = PACKAGE_BUGREPORT; /* Definitions of arguments for argp functions. */ static const struct argp_option options[] = { - { NULL, 0, NULL, 0, N_("Output Selection:"), 0 }, + { NULL, 0, NULL, 0, N_("Output selection options:"), 2 }, { "basenames", 's', NULL, 0, N_("Show only base names of source files"), 0 }, { "absolute", 'A', NULL, 0, N_("Show absolute file names using compilation directory"), 0 }, @@ -131,6 +131,7 @@ main (int argc, char *argv[]) /* Parse and process arguments. This includes opening the modules. */ argp_children[0].argp = dwfl_standard_argp (); + argp_children[0].group = 1; Dwfl *dwfl = NULL; (void) argp_parse (&argp, argc, argv, 0, &remaining, &dwfl); assert (dwfl != NULL); diff --git a/src/elflint.c b/src/elflint.c index 09c7fbd2f..db3b49c1b 100644 --- a/src/elflint.c +++ b/src/elflint.c @@ -3407,7 +3407,9 @@ section [%2zu] '%s': merge flag set but entry size is zero\n"), || (phdr->p_type == PT_TLS && (shdr->sh_flags & SHF_TLS) != 0)) && phdr->p_offset <= shdr->sh_offset - && phdr->p_offset + phdr->p_memsz > shdr->sh_offset) + && (phdr->p_offset + phdr->p_filesz > shdr->sh_offset + || (phdr->p_offset + phdr->p_memsz > shdr->sh_offset + && shdr->sh_type == SHT_NOBITS))) { /* Found the segment. */ if (phdr->p_offset + phdr->p_memsz diff --git a/src/strip.c b/src/strip.c index 95eded657..5a2da6464 100644 --- a/src/strip.c +++ b/src/strip.c @@ -835,6 +835,7 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname, elf_errmsg (-1)); bool discard_section = (shdr_info[cnt].idx > 0 + && shdr_info[cnt].shdr.sh_type != SHT_NOTE && cnt != ehdr->e_shstrndx); /* Set the section header in the new file. */ @@ -1251,6 +1252,24 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname, symbol table. */ for (cnt = 1; cnt <= shdridx; ++cnt) { + /* Update section headers when the data size has changed. + We also update the SHT_NOBITS section in the debug + file so that the section headers match in sh_size. */ + inline void update_section_size (const Elf_Data *newdata) + { + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); + shdr->sh_size = newdata->d_size; + (void) gelf_update_shdr (scn, shdr); + if (debugelf != NULL) + { + /* libelf will use d_size to set sh_size. */ + Elf_Data *debugdata = elf_getdata (elf_getscn (debugelf, + cnt), NULL); + debugdata->d_size = newdata->d_size; + } + } + if (shdr_info[cnt].idx == 0 && debug_fname == NULL) /* Ignore sections which are discarded. When we are saving a relocation section in a separate debug file, we must fix up @@ -1354,12 +1373,9 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname, Elf32_Word *chain = bucket + nbucket; /* New size of the section. */ - GElf_Shdr shdr_mem; - GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); - shdr->sh_size = hashd->d_size - = (2 + symd->d_size / elsize + nbucket) - * sizeof (Elf32_Word); - (void) gelf_update_shdr (scn, shdr); + hashd->d_size = ((2 + symd->d_size / elsize + nbucket) + * sizeof (Elf32_Word)); + update_section_size (hashd); /* Clear the arrays. */ memset (bucket, '\0', @@ -1411,12 +1427,9 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname, Elf64_Xword *chain = bucket + nbucket; /* New size of the section. */ - GElf_Shdr shdr_mem; - GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); - shdr->sh_size = hashd->d_size - = (2 + symd->d_size / elsize + nbucket) - * sizeof (Elf64_Xword); - (void) gelf_update_shdr (scn, shdr); + hashd->d_size = ((2 + symd->d_size / elsize + nbucket) + * sizeof (Elf64_Xword)); + update_section_size (hashd); /* Clear the arrays. */ memset (bucket, '\0', @@ -1492,14 +1505,12 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname, verstab[newsymidx[inner]] = verstab[inner]; /* New size of the section. */ - GElf_Shdr shdr_mem; - GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); - shdr->sh_size = verd->d_size - = gelf_fsize (newelf, verd->d_type, - symd->d_size / gelf_fsize (elf, symd->d_type, 1, - ehdr->e_version), - ehdr->e_version); - (void) gelf_update_shdr (scn, shdr); + verd->d_size = gelf_fsize (newelf, verd->d_type, + symd->d_size + / gelf_fsize (elf, symd->d_type, 1, + ehdr->e_version), + ehdr->e_version); + update_section_size (verd); } else if (shdr_info[cnt].shdr.sh_type == SHT_GROUP) { diff --git a/src/unstrip.c b/src/unstrip.c index 25ce1f37b..98e165ce8 100644 --- a/src/unstrip.c +++ b/src/unstrip.c @@ -270,6 +270,27 @@ copy_elf (Elf *outelf, Elf *inelf) } } +/* Create directories containing PATH. */ +static void +make_directories (const char *path) +{ + const char *lastslash = strrchr (path, '/'); + if (lastslash == NULL) + return; + + while (lastslash > path && lastslash[-1] == '/') + --lastslash; + if (lastslash == path) + return; + + char *dir = strndupa (path, lastslash - path); + while (mkdir (dir, 0777) < 0 && errno != EEXIST) + if (errno == ENOENT) + make_directories (dir); + else + error (EXIT_FAILURE, errno, _("cannot create directory '%s'"), dir); +} + /* The binutils linker leaves gratuitous section symbols in .symtab that strip has to remove. Older linkers likewise include a @@ -293,9 +314,11 @@ section_can_shrink (const GElf_Shdr *shdr) } /* See if this symbol table has a leading section symbol for every single - section, in order. The binutils linker produces this. */ + section, in order. The binutils linker produces this. While we're here, + update each section symbol's st_value. */ static size_t -symtab_count_leading_section_symbols (Elf_Scn *scn, size_t shnum) +symtab_count_leading_section_symbols (Elf *elf, Elf_Scn *scn, size_t shnum, + Elf_Data *newsymdata) { Elf_Data *data = elf_getdata (scn, NULL); Elf_Data *shndxdata = NULL; /* XXX */ @@ -306,11 +329,22 @@ symtab_count_leading_section_symbols (Elf_Scn *scn, size_t shnum) GElf_Word shndx = SHN_UNDEF; GElf_Sym *sym = gelf_getsymshndx (data, shndxdata, i, &sym_mem, &shndx); ELF_CHECK (sym != NULL, _("cannot get symbol table entry: %s")); + + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (elf_getscn (elf, i), &shdr_mem); + ELF_CHECK (shdr != NULL, _("cannot get section header: %s")); + if (sym->st_shndx != SHN_XINDEX) shndx = sym->st_shndx; if (shndx != i || GELF_ST_TYPE (sym->st_info) != STT_SECTION) return i; + + sym->st_value = shdr->sh_addr; + if (sym->st_shndx != SHN_XINDEX) + shndx = SHN_UNDEF; + ELF_CHECK (gelf_update_symshndx (newsymdata, shndxdata, i, sym, shndx), + _("cannot update symbol table: %s")); } return shnum; @@ -489,7 +523,7 @@ adjust_all_relocs (Elf *elf, Elf_Scn *symtab, const GElf_Shdr *symshdr, /* The original file probably had section symbols for all of its sections, even the unallocated ones. To match it as closely as - possible, to add in section symbols for the added sections. */ + possible, add in section symbols for the added sections. */ static Elf_Data * add_new_section_symbols (Elf_Scn *old_symscn, size_t old_shnum, Elf *elf, Elf_Scn *symscn, size_t shnum) @@ -534,8 +568,12 @@ add_new_section_symbols (Elf_Scn *old_symscn, size_t old_shnum, /* Add in the new section symbols. */ for (size_t i = old_shnum; i < shnum; ++i) { + GElf_Shdr i_shdr_mem; + GElf_Shdr *i_shdr = gelf_getshdr (elf_getscn (elf, i), &i_shdr_mem); + ELF_CHECK (i_shdr != NULL, _("cannot get section header: %s")); GElf_Sym sym = { + .st_value = i_shdr->sh_addr, .st_info = GELF_ST_INFO (STB_LOCAL, STT_SECTION), .st_shndx = i < SHN_LORESERVE ? i : SHN_XINDEX }; @@ -565,13 +603,16 @@ add_new_section_symbols (Elf_Scn *old_symscn, size_t old_shnum, return symdata; } +/* This has the side effect of updating STT_SECTION symbols' values, + in case of prelink adjustments. */ static Elf_Data * check_symtab_section_symbols (Elf *elf, Elf_Scn *scn, size_t shnum, size_t shstrndx, Elf_Scn *oscn, size_t oshnum, size_t oshstrndx, size_t debuglink) { - size_t n = symtab_count_leading_section_symbols (oscn, oshnum); + size_t n = symtab_count_leading_section_symbols (elf, oscn, oshnum, + elf_getdata (scn, NULL)); if (n == oshnum) return add_new_section_symbols (oscn, n, elf, scn, shnum); @@ -659,9 +700,10 @@ struct symbol /* Collect input symbols into our internal form. */ static void -collect_symbols (Elf_Scn *symscn, Elf_Scn *strscn, +collect_symbols (Elf *outelf, Elf_Scn *symscn, Elf_Scn *strscn, const size_t nent, const GElf_Addr bias, - const size_t scnmap[], struct symbol *table, size_t *map) + const size_t scnmap[], struct symbol *table, size_t *map, + struct section *split_bss) { Elf_Data *symdata = elf_getdata (symscn, NULL); Elf_Data *strdata = elf_getdata (strscn, NULL); @@ -677,9 +719,6 @@ collect_symbols (Elf_Scn *symscn, Elf_Scn *strscn, if (sym->st_shndx != SHN_XINDEX) shndx = sym->st_shndx; - if (scnmap != NULL && shndx != SHN_UNDEF && shndx < SHN_LORESERVE) - shndx = scnmap[shndx - 1]; - if (sym->st_name >= strdata->d_size) error (EXIT_FAILURE, 0, _("invalid string offset in symbol [%Zu]"), i); @@ -692,6 +731,27 @@ collect_symbols (Elf_Scn *symscn, Elf_Scn *strscn, s->shndx = shndx; s->info.info = sym->st_info; s->info.other = sym->st_other; + + if (scnmap != NULL && shndx != SHN_UNDEF && shndx < SHN_LORESERVE) + s->shndx = scnmap[shndx - 1]; + + if (GELF_ST_TYPE (s->info.info) == STT_SECTION) + { + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (elf_getscn (outelf, shndx), + &shdr_mem); + ELF_CHECK (shdr != NULL, _("cannot get section header: %s")); + + if (GELF_ST_TYPE (s->info.info) == STT_SECTION) + /* Update the value to match the output section. */ + s->value = shdr->sh_addr; + } + else if (split_bss != NULL + && s->value < split_bss->shdr.sh_addr + && s->value >= split_bss[-1].shdr.sh_addr + && shndx == elf_ndxscn (split_bss->outscn)) + /* This symbol was in .bss and was split into .dynbss. */ + s->shndx = elf_ndxscn (split_bss[-1].outscn); } } @@ -759,11 +819,286 @@ compare_symbols_output (const void *a, const void *b) #undef CMP +/* Locate a matching allocated section in SECTIONS. */ +static struct section * +find_alloc_section (const GElf_Shdr *shdr, GElf_Addr bias, const char *name, + struct section sections[], size_t nalloc) +{ + const GElf_Addr addr = shdr->sh_addr + bias; + size_t l = 0, u = nalloc; + while (l < u) + { + size_t i = (l + u) / 2; + if (addr < sections[i].shdr.sh_addr) + u = i; + else if (addr > sections[i].shdr.sh_addr) + l = i + 1; + else + { + /* We've found allocated sections with this address. + Find one with matching size, flags, and name. */ + while (i > 0 && sections[i - 1].shdr.sh_addr == addr) + --i; + for (; i < nalloc && sections[i].shdr.sh_addr == addr; + ++i) + if (sections[i].shdr.sh_flags == shdr->sh_flags + && (sections[i].shdr.sh_size == shdr->sh_size + || (sections[i].shdr.sh_size < shdr->sh_size + && section_can_shrink (§ions[i].shdr))) + && !strcmp (sections[i].name, name)) + return §ions[i]; + break; + } + } + return NULL; +} + +static inline const char * +get_section_name (size_t ndx, const GElf_Shdr *shdr, const Elf_Data *shstrtab) +{ + if (shdr->sh_name >= shstrtab->d_size) + error (EXIT_FAILURE, 0, _("cannot read section [%Zu] name: %s"), + ndx, elf_errmsg (-1)); + return shstrtab->d_buf + shdr->sh_name; +} + +/* Fix things up when prelink has moved some allocated sections around + and the debuginfo file's section headers no longer match up. + This fills in SECTIONS[0..NALLOC-1].outscn or exits. + If there was a .bss section that was split into two sections + with the new one preceding it in sh_addr, we return that pointer. */ +static struct section * +find_alloc_sections_prelink (Elf *debug, Elf_Data *debug_shstrtab, + Elf *main, const GElf_Ehdr *main_ehdr, + Elf_Data *main_shstrtab, GElf_Addr bias, + struct section *sections, + size_t nalloc, size_t nsections) +{ + /* Clear assignments that might have been bogus. */ + for (size_t i = 0; i < nalloc; ++i) + sections[i].outscn = NULL; + + Elf_Scn *undo = NULL; + for (size_t i = nalloc; i < nsections; ++i) + { + const struct section *sec = §ions[i]; + if (sec->shdr.sh_type == SHT_PROGBITS + && !(sec->shdr.sh_flags & SHF_ALLOC) + && !strcmp (sec->name, ".gnu.prelink_undo")) + { + undo = sec->scn; + break; + } + } + + /* Find the original allocated sections before prelinking. */ + struct section *undo_sections = NULL; + size_t undo_nalloc = 0; + if (undo != NULL) + { + Elf_Data *undodata = elf_rawdata (undo, NULL); + ELF_CHECK (undodata != NULL, + _("cannot read '.gnu.prelink_undo' section: %s")); + + union + { + Elf32_Ehdr e32; + Elf64_Ehdr e64; + } ehdr; + Elf_Data dst = + { + .d_buf = &ehdr, + .d_size = sizeof ehdr, + .d_type = ELF_T_EHDR, + .d_version = EV_CURRENT + }; + Elf_Data src = *undodata; + src.d_size = gelf_fsize (main, ELF_T_EHDR, 1, EV_CURRENT); + src.d_type = ELF_T_EHDR; + ELF_CHECK (gelf_xlatetom (main, &dst, &src, + main_ehdr->e_ident[EI_DATA]) != NULL, + _("cannot read '.gnu.prelink_undo' section: %s")); + + uint_fast16_t phnum; + uint_fast16_t shnum; + if (ehdr.e32.e_ident[EI_CLASS] == ELFCLASS32) + { + phnum = ehdr.e32.e_phnum; + shnum = ehdr.e32.e_shnum; + } + else + { + phnum = ehdr.e64.e_phnum; + shnum = ehdr.e64.e_shnum; + } + + size_t phsize = gelf_fsize (main, ELF_T_PHDR, phnum, EV_CURRENT); + src.d_buf += src.d_size + phsize; + src.d_size = gelf_fsize (main, ELF_T_SHDR, shnum - 1, EV_CURRENT); + src.d_type = ELF_T_SHDR; + if ((size_t) (src.d_buf - undodata->d_buf) > undodata->d_size + || undodata->d_size - (src.d_buf - undodata->d_buf) != src.d_size) + error (EXIT_FAILURE, 0, _("invalid contents in '%s' section"), + ".gnu.prelink_undo"); + + union + { + Elf32_Shdr s32[shnum - 1]; + Elf64_Shdr s64[shnum - 1]; + } shdr; + dst.d_buf = &shdr; + dst.d_size = sizeof shdr; + ELF_CHECK (gelf_xlatetom (main, &dst, &src, + main_ehdr->e_ident[EI_DATA]) != NULL, + _("cannot read '.gnu.prelink_undo' section: %s")); + + undo_sections = xmalloc ((shnum - 1) * sizeof undo_sections[0]); + for (size_t i = 0; i < shnum - 1; ++i) + { + struct section *sec = &undo_sections[undo_nalloc]; + if (ehdr.e32.e_ident[EI_CLASS] == ELFCLASS32) + { +#define COPY(field) sec->shdr.field = shdr.s32[i].field + COPY (sh_name); + COPY (sh_type); + COPY (sh_flags); + COPY (sh_addr); + COPY (sh_offset); + COPY (sh_size); + COPY (sh_link); + COPY (sh_info); + COPY (sh_addralign); + COPY (sh_entsize); +#undef COPY + } + else + sec->shdr = shdr.s64[i]; + if (sec->shdr.sh_flags & SHF_ALLOC) + { + sec->shdr.sh_addr += bias; + sec->name = get_section_name (i + 1, &sec->shdr, main_shstrtab); + sec->scn = elf_getscn (main, i + 1); /* Really just for ndx. */ + sec->outscn = NULL; + sec->strent = NULL; + ++undo_nalloc; + } + } + qsort (undo_sections, undo_nalloc, + sizeof undo_sections[0], compare_sections); + } + + bool fail = false; + inline void check_match (bool match, Elf_Scn *scn, const char *name) + { + if (!match) + { + fail = true; + error (0, 0, _("cannot find matching section for [%Zu] '%s'"), + elf_ndxscn (scn), name); + } + } + + Elf_Scn *scn = NULL; + while ((scn = elf_nextscn (debug, scn)) != NULL) + { + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); + ELF_CHECK (shdr != NULL, _("cannot get section header: %s")); + + if (!(shdr->sh_flags & SHF_ALLOC)) + continue; + + const char *name = get_section_name (elf_ndxscn (scn), shdr, + debug_shstrtab); + + if (undo_sections != NULL) + { + struct section *sec = find_alloc_section (shdr, 0, name, + undo_sections, + undo_nalloc); + if (sec != NULL) + { + sec->outscn = scn; + continue; + } + } + + /* If there is no prelink info, we are just here to find + the sections to give error messages about. */ + for (size_t i = 0; shdr != NULL && i < nalloc; ++i) + if (sections[i].outscn == scn) + shdr = NULL; + check_match (shdr == NULL, scn, name); + } + + if (fail) + exit (EXIT_FAILURE); + + /* Now we have lined up output sections for each of the original sections + before prelinking. Translate those to the prelinked sections. + This matches what prelink's undo_sections does. */ + struct section *split_bss = NULL; + for (size_t i = 0; i < undo_nalloc; ++i) + { + const struct section *undo_sec = &undo_sections[i]; + + const char *name = undo_sec->name; + scn = undo_sec->scn; /* This is just for elf_ndxscn. */ + + for (size_t j = 0; j < nalloc; ++j) + { + struct section *sec = §ions[j]; +#define RELA_SCALED(field) \ + (2 * sec->shdr.field == 3 * undo_sec->shdr.field) + if (sec->outscn == NULL + && sec->shdr.sh_name == undo_sec->shdr.sh_name + && sec->shdr.sh_flags == undo_sec->shdr.sh_flags + && sec->shdr.sh_addralign == undo_sec->shdr.sh_addralign + && (((sec->shdr.sh_type == undo_sec->shdr.sh_type + && sec->shdr.sh_entsize == undo_sec->shdr.sh_entsize + && (sec->shdr.sh_size == undo_sec->shdr.sh_size + || (sec->shdr.sh_size > undo_sec->shdr.sh_size + && main_ehdr->e_type == ET_EXEC + && !strcmp (sec->name, ".dynstr")))) + || (sec->shdr.sh_size == undo_sec->shdr.sh_size + && ((sec->shdr.sh_entsize == undo_sec->shdr.sh_entsize + && undo_sec->shdr.sh_type == SHT_NOBITS) + || undo_sec->shdr.sh_type == SHT_PROGBITS) + && !strcmp (sec->name, ".plt"))) + || (sec->shdr.sh_type == SHT_RELA + && undo_sec->shdr.sh_type == SHT_REL + && RELA_SCALED (sh_entsize) && RELA_SCALED (sh_size)) + || (sec->shdr.sh_entsize == undo_sec->shdr.sh_entsize + && (sec->shdr.sh_type == undo_sec->shdr.sh_type + || (sec->shdr.sh_type == SHT_PROGBITS + && undo_sec->shdr.sh_type == SHT_NOBITS)) + && sec->shdr.sh_size < undo_sec->shdr.sh_size + && (!strcmp (sec->name, ".bss") + || !strcmp (sec->name, ".sbss")) + && (split_bss = sec) > sections))) + { + sec->outscn = undo_sec->outscn; + undo_sec = NULL; + break; + } + } + + check_match (undo_sec == NULL, scn, name); + } + + free (undo_sections); + + if (fail) + exit (EXIT_FAILURE); + + return split_bss; +} + /* Fill in any SHT_NOBITS sections in UNSTRIPPED by copying their contents and sh_type from STRIPPED. */ static void -copy_elided_sections (Elf *unstripped, Elf *stripped, uint_fast16_t e_type, - uint_fast16_t phnum, GElf_Addr bias) +copy_elided_sections (Elf *unstripped, Elf *stripped, + const GElf_Ehdr *stripped_ehdr, GElf_Addr bias) { size_t unstripped_shstrndx; ELF_CHECK (elf_getshstrndx (unstripped, &unstripped_shstrndx) == 0, @@ -811,39 +1146,6 @@ copy_elided_sections (Elf *unstripped, Elf *stripped, uint_fast16_t e_type, stripped_symtab = §ions[nalloc]; } - /* Locate a matching allocated section in SECTIONS. */ - inline struct section *find_alloc_section (const GElf_Shdr *shdr, - const char *name) - { - const GElf_Addr addr = shdr->sh_addr + bias; - size_t l = 0, u = nalloc; - while (l < u) - { - size_t i = (l + u) / 2; - if (addr < sections[i].shdr.sh_addr) - u = i; - else if (addr > sections[i].shdr.sh_addr) - l = i + 1; - else - { - /* We've found allocated sections with this address. - Find one with matching size, flags, and name. */ - while (i > 0 && sections[i - 1].shdr.sh_addr == addr) - --i; - for (; i < nalloc && sections[i].shdr.sh_addr == addr; - ++i) - if (sections[i].shdr.sh_flags == shdr->sh_flags - && (sections[i].shdr.sh_size == shdr->sh_size - || (sections[i].shdr.sh_size < shdr->sh_size - && section_can_shrink (§ions[i].shdr))) - && !strcmp (sections[i].name, name)) - return §ions[i]; - break; - } - } - return NULL; - } - /* Locate a matching unallocated section in SECTIONS. */ inline struct section *find_unalloc_section (const GElf_Shdr *shdr, const char *name) @@ -869,16 +1171,9 @@ copy_elided_sections (Elf *unstripped, Elf *stripped, uint_fast16_t e_type, unstripped_shstrndx), NULL); ELF_CHECK (shstrtab != NULL, _("cannot read section header string table: %s")); - inline const char *unstripped_section_name (Elf_Scn *sec, - const GElf_Shdr *shdr) - { - if (shdr->sh_name >= shstrtab->d_size) - error (EXIT_FAILURE, 0, _("cannot read section [%Zu] name: %s"), - elf_ndxscn (sec), elf_errmsg (-1)); - return shstrtab->d_buf + shdr->sh_name; - } /* Match each debuginfo section with its corresponding stripped section. */ + bool check_prelink = false; Elf_Scn *unstripped_symtab = NULL; size_t unstripped_strtab_ndx = SHN_UNDEF; scn = NULL; @@ -888,31 +1183,68 @@ copy_elided_sections (Elf *unstripped, Elf *stripped, uint_fast16_t e_type, GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); ELF_CHECK (shdr != NULL, _("cannot get section header: %s")); - /* Anything not already SHT_NOBITS is fine as it stands. */ - if (shdr->sh_type != SHT_NOBITS) + if (shdr->sh_type == SHT_SYMTAB) { - if (shdr->sh_type == SHT_SYMTAB) - { - unstripped_symtab = scn; - unstripped_strtab_ndx = shdr->sh_link; - } + unstripped_symtab = scn; + unstripped_strtab_ndx = shdr->sh_link; continue; } - const char *name = unstripped_section_name (scn, shdr); + const size_t ndx = elf_ndxscn (scn); + if (ndx == unstripped_shstrndx) + continue; + + const char *name = get_section_name (ndx, shdr, shstrtab); /* Look for the section that matches. */ struct section *sec = ((shdr->sh_flags & SHF_ALLOC) - ? find_alloc_section (shdr, name) + ? find_alloc_section (shdr, bias, name, + sections, nalloc) : find_unalloc_section (shdr, name)); if (sec == NULL) - error (EXIT_FAILURE, 0, - _("cannot find matching section for [%Zu] '%s'"), - elf_ndxscn (scn), name); + { + if ((shdr->sh_flags & SHF_ALLOC) && stripped_ehdr->e_type != ET_REL) + { + /* If we couldn't figure it out, it may be a prelink issue. */ + check_prelink = true; + continue; + } + + /* An additional unallocated section is fine if not SHT_NOBITS. + We looked it up anyway in case it's an unallocated section + copied in both files (e.g. SHT_NOTE), so we don't keep both. */ + if (shdr->sh_type != SHT_NOBITS && !(shdr->sh_flags & SHF_ALLOC)) + continue; + + /* Somehow some old .debug files wound up with SHT_NOBITS + .comment sections, so let those pass. */ + if (!(shdr->sh_flags & SHF_ALLOC) && !strcmp (name, ".comment")) + continue; + + error (EXIT_FAILURE, 0, + _("cannot find matching section for [%Zu] '%s'"), + elf_ndxscn (scn), name); + } sec->outscn = scn; } + /* If that failed due to changes made by prelink, we take another tack. + We keep track of a .bss section that was partly split into .dynbss + so that collect_symbols can update symbols' st_shndx fields. */ + struct section *split_bss = NULL; + if (check_prelink) + { + Elf_Data *data = elf_getdata (elf_getscn (stripped, stripped_shstrndx), + NULL); + ELF_CHECK (data != NULL, + _("cannot read section header string table: %s")); + split_bss = find_alloc_sections_prelink (unstripped, shstrtab, + stripped, stripped_ehdr, + data, bias, sections, + nalloc, stripped_shnum - 1); + } + /* Make sure each main file section has a place to go. */ const struct section *stripped_dynsym = NULL; size_t debuglink = SHN_UNDEF; @@ -1006,7 +1338,7 @@ copy_elided_sections (Elf *unstripped, Elf *stripped, uint_fast16_t e_type, scn = elf_getscn (unstripped, i + 1); GElf_Shdr shdr_mem; GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); - const char *name = unstripped_section_name (scn, shdr); + const char *name = get_section_name (i + 1, shdr, shstrtab); unstripped_strent[i] = ebl_strtabadd (strtab, name, 0); ELF_CHECK (unstripped_strent[i] != NULL, _("cannot add section name to string table: %s")); @@ -1075,7 +1407,7 @@ copy_elided_sections (Elf *unstripped, Elf *stripped, uint_fast16_t e_type, elf_flagdata (outdata, ELF_C_SET, ELF_F_DIRTY); /* Preserve the file layout of the allocated sections. */ - if (e_type != ET_REL && (shdr_mem.sh_flags & SHF_ALLOC)) + if (stripped_ehdr->e_type != ET_REL && (shdr_mem.sh_flags & SHF_ALLOC)) { shdr_mem.sh_offset = sec->shdr.sh_offset; placed[elf_ndxscn (sec->outscn) - 1] = true; @@ -1140,7 +1472,9 @@ copy_elided_sections (Elf *unstripped, Elf *stripped, uint_fast16_t e_type, struct Ebl_Strtab *symstrtab = NULL; Elf_Data *symstrdata = NULL; if (unstripped_symtab != NULL && (stripped_symtab != NULL - || (e_type != ET_REL && bias != 0))) + || check_prelink /* Section adjustments. */ + || (stripped_ehdr->e_type != ET_REL + && bias != 0))) { /* Merge the stripped file's symbol table into the unstripped one. */ const size_t stripped_nsym = (stripped_symtab == NULL ? 1 @@ -1159,16 +1493,17 @@ copy_elided_sections (Elf *unstripped, Elf *stripped, uint_fast16_t e_type, size_t symndx_map[total_syms]; if (stripped_symtab != NULL) - collect_symbols (stripped_symtab->scn, + collect_symbols (unstripped, stripped_symtab->scn, elf_getscn (stripped, stripped_symtab->shdr.sh_link), stripped_nsym, 0, ndx_section, - symbols, symndx_map); + symbols, symndx_map, NULL); Elf_Scn *unstripped_strtab = elf_getscn (unstripped, shdr->sh_link); - collect_symbols (unstripped_symtab, unstripped_strtab, - unstripped_nsym, e_type == ET_REL ? 0 : bias, NULL, + collect_symbols (unstripped, + unstripped_symtab, unstripped_strtab, unstripped_nsym, + stripped_ehdr->e_type == ET_REL ? 0 : bias, NULL, &symbols[stripped_nsym - 1], - &symndx_map[stripped_nsym - 1]); + &symndx_map[stripped_nsym - 1], split_bss); /* Next, sort our array of all symbols. */ qsort (symbols, total_syms, sizeof symbols[0], compare_symbols); @@ -1243,13 +1578,17 @@ copy_elided_sections (Elf *unstripped, Elf *stripped, uint_fast16_t e_type, ELF_CHECK (gelf_update_shdr (unstripped_symtab, shdr), _("cannot update section header: %s")); - /* Adjust any relocations referring to the old symbol table. */ - const size_t old_sh_link = elf_ndxscn (stripped_symtab->scn); - for (const struct section *sec = sections; - sec < §ions[stripped_shnum - 1]; - ++sec) - if (sec->outscn != NULL && sec->shdr.sh_link == old_sh_link) - adjust_relocs (sec->outscn, sec->scn, &sec->shdr, symndx_map, shdr); + if (stripped_symtab != NULL) + { + /* Adjust any relocations referring to the old symbol table. */ + const size_t old_sh_link = elf_ndxscn (stripped_symtab->scn); + for (const struct section *sec = sections; + sec < §ions[stripped_shnum - 1]; + ++sec) + if (sec->outscn != NULL && sec->shdr.sh_link == old_sh_link) + adjust_relocs (sec->outscn, sec->scn, &sec->shdr, + symndx_map, shdr); + } /* Also adjust references to the other old symbol table. */ adjust_all_relocs (unstripped, unstripped_symtab, shdr, @@ -1328,8 +1667,12 @@ copy_elided_sections (Elf *unstripped, Elf *stripped, uint_fast16_t e_type, } } while (skip_reloc); + if (stripped_ehdr->e_phnum > 0) + ELF_CHECK (gelf_newphdr (unstripped, stripped_ehdr->e_phnum), + _("cannot create program headers: %s")); + /* Copy each program header from the stripped file. */ - for (uint_fast16_t i = 0; i < phnum; ++i) + for (uint_fast16_t i = 0; i < stripped_ehdr->e_phnum; ++i) { GElf_Phdr phdr_mem; GElf_Phdr *phdr = gelf_getphdr (stripped, i, &phdr_mem); @@ -1360,7 +1703,7 @@ copy_elided_sections (Elf *unstripped, Elf *stripped, uint_fast16_t e_type, /* Process one pair of files, already opened. */ static void -handle_file (const char *output_file, +handle_file (const char *output_file, bool create_dirs, Elf *stripped, const GElf_Ehdr *stripped_ehdr, Elf *unstripped) { @@ -1387,15 +1730,24 @@ handle_file (const char *output_file, /* One day we could adjust all the DWARF data (like prelink itself does). */ if (bias != 0) - error (0, 0, - _("DWARF output not adjusted for prelinking bias; use prelink -u")); + { + if (output_file == NULL) + error (0, 0, _("\ +DWARF data not adjusted for prelinking bias; consider prelink -u")); + else + error (0, 0, _("\ +DWARF data in '%s' not adjusted for prelinking bias; consider prelink -u"), + output_file); + } if (output_file == NULL) /* Modify the unstripped file in place. */ - copy_elided_sections (unstripped, stripped, stripped_ehdr->e_type, - stripped_ehdr->e_phnum, bias); + copy_elided_sections (unstripped, stripped, stripped_ehdr, bias); else { + if (create_dirs) + make_directories (output_file); + /* Copy the unstripped file and then modify it. */ int outfd = open64 (output_file, O_RDWR | O_CREAT, stripped_ehdr->e_type == ET_REL ? 0666 : 0777); @@ -1416,8 +1768,7 @@ handle_file (const char *output_file, else { copy_elf (outelf, unstripped); - copy_elided_sections (outelf, stripped, stripped_ehdr->e_type, - stripped_ehdr->e_phnum, bias); + copy_elided_sections (outelf, stripped, stripped_ehdr, bias); } elf_end (outelf); @@ -1436,7 +1787,7 @@ open_file (const char *file, bool writable) /* Handle a pair of files we need to open by name. */ static void -handle_explicit_files (const char *output_file, +handle_explicit_files (const char *output_file, bool create_dirs, const char *stripped_file, const char *unstripped_file) { int stripped_fd = open_file (stripped_file, false); @@ -1465,7 +1816,7 @@ handle_explicit_files (const char *output_file, stripped_file, unstripped_file); } - handle_file (output_file, stripped, &stripped_ehdr, unstripped); + handle_file (output_file, create_dirs, stripped, &stripped_ehdr, unstripped); elf_end (stripped); close (stripped_fd); @@ -1477,8 +1828,8 @@ handle_explicit_files (const char *output_file, /* Handle a pair of files opened implicitly by libdwfl for one module. */ static void -handle_dwfl_module (const char *output_file, Dwfl_Module *mod, - bool all, bool ignore) +handle_dwfl_module (const char *output_file, bool create_dirs, + Dwfl_Module *mod, bool all, bool ignore) { GElf_Addr bias; Elf *stripped = dwfl_module_getelf (mod, &bias); @@ -1547,31 +1898,11 @@ handle_dwfl_module (const char *output_file, Dwfl_Module *mod, (void) dwfl_module_info (mod, NULL, NULL, NULL, NULL, NULL, &stripped_file, &unstripped_file); - handle_explicit_files (output_file, stripped_file, unstripped_file); + handle_explicit_files (output_file, create_dirs, + stripped_file, unstripped_file); } else - handle_file (output_file, stripped, &stripped_ehdr, debug); -} - -/* Create directories containing PATH. */ -static void -make_directories (const char *path) -{ - const char *lastslash = strrchr (path, '/'); - if (lastslash == NULL) - return; - - while (lastslash > path && lastslash[-1] == '/') - --lastslash; - if (lastslash == path) - return; - - char *dir = strndupa (path, lastslash - path); - while (mkdir (dir, 0777) < 0 && errno != EEXIST) - if (errno == ENOENT) - make_directories (dir); - else - error (EXIT_FAILURE, errno, _("cannot create directory '%s'"), dir); + handle_file (output_file, create_dirs, stripped, &stripped_ehdr, debug); } /* Handle one module being written to the output directory. */ @@ -1597,8 +1928,7 @@ handle_output_dir_module (const char *output_dir, Dwfl_Module *mod, if (asprintf (&output_file, "%s/%s", output_dir, modnames ? name : file) < 0) error (EXIT_FAILURE, 0, _("memory exhausted")); - make_directories (output_file); - handle_dwfl_module (output_file, mod, all, ignore); + handle_dwfl_module (output_file, true, mod, all, ignore); } @@ -1665,7 +1995,7 @@ handle_implicit_modules (const struct arg_info *info) { if (next (offset) != 0) error (EXIT_FAILURE, 0, _("matched more than one module")); - handle_dwfl_module (info->output_file, mmi.found, + handle_dwfl_module (info->output_file, false, mmi.found, info->all, info->ignore); } else @@ -1747,12 +2077,12 @@ name of the main file complete with directory underneath OUTPUT-DIRECTORY.") char *file; if (asprintf (&file, "%s/%s", info.output_dir, info.args[0]) < 0) error (EXIT_FAILURE, 0, _("memory exhausted")); - make_directories (file); - handle_explicit_files (file, info.args[0], info.args[1]); + handle_explicit_files (file, true, info.args[0], info.args[1]); free (file); } else - handle_explicit_files (info.output_file, info.args[0], info.args[1]); + handle_explicit_files (info.output_file, false, + info.args[0], info.args[1]); } else { diff --git a/tests/ChangeLog b/tests/ChangeLog index 89fbab7cb..3424c1e2c 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,28 @@ +2007-05-18 Roland McGrath + + * run-strip-test4.sh (stripped, debugfile): Use new reference files. + * testfile37.bz2: New data file. + * testfile37.debug.bz2: New data file. + * run-unstrip-test2.sh: New file. + * Makefile.am (TESTS, EXTRA_DIST): Add them. + +2007-05-10 Roland McGrath + + * run-dwfl-bug-offline-rel.sh: New file. + * testfile36.bz2: New data file. + * testfile36.debug.bz2: New data file. + * Makefile.am (TESTS, EXTRA_DIST): Add them. + +2007-04-28 Roland McGrath + + * run-strip-test6.sh (stripped, debugfile): Use new reference files. + * testfile35.bz2: New data file. + * testfile35.debug.bz2: New data file. + * run-unstrip-test.sh: New file. + * Makefile.am (TESTS, EXTRA_DIST): Add them. + + * run-strip-test.sh: Do all elflint and cmp runs even when some fail. + 2007-04-26 Roland McGrath * run-elflint-self.sh: Run all tests even if one fails. diff --git a/tests/Makefile.am b/tests/Makefile.am index 0715fff83..f485acd11 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -71,13 +71,15 @@ TESTS = run-arextract.sh run-arsymtest.sh newfile test-nlist \ run-show-abbrev.sh run-line2addr.sh hash \ newscn run-strip-test.sh run-strip-test2.sh \ run-strip-test3.sh run-strip-test4.sh run-strip-test5.sh \ - run-strip-test6.sh run-ecp-test.sh run-ecp-test2.sh \ + run-strip-test6.sh run-unstrip-test.sh run-unstrip-test2.sh \ + run-ecp-test.sh run-ecp-test2.sh \ run-elflint-test.sh run-elflint-self.sh run-ranlib-test.sh \ run-ranlib-test2.sh run-ranlib-test3.sh run-ranlib-test4.sh \ run-addrscopes.sh run-strings-test.sh run-funcscopes.sh \ run-find-prologues.sh run-allregs.sh run-readelf-test1.sh \ run-native-test.sh run-bug1-test.sh \ - dwfl-bug-addr-overflow run-addrname-test.sh dwfl-bug-fd-leak + dwfl-bug-addr-overflow run-addrname-test.sh dwfl-bug-fd-leak \ + run-dwfl-bug-offline-rel.sh # run-show-ciefde.sh if !STANDALONE @@ -102,11 +104,12 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh \ testfile13.bz2 run-strip-test3.sh run-allfcts.sh \ run-line2addr.sh run-elflint-test.sh testfile14.bz2 \ run-strip-test4.sh run-strip-test5.sh run-strip-test6.sh \ + run-unstrip-test.sh run-unstrip-test2.sh \ run-elflint-self.sh run-ranlib-test.sh run-ranlib-test2.sh \ run-ranlib-test3.sh run-ranlib-test4.sh \ run-addrscopes.sh run-strings-test.sh run-funcscopes.sh \ run-find-prologues.sh run-allregs.sh run-native-test.sh \ - run-addrname-test.sh \ + run-addrname-test.sh run-dwfl-bug-offline-rel.sh \ testfile15.bz2 testfile15.debug.bz2 \ testfile16.bz2 testfile16.debug.bz2 \ testfile17.bz2 testfile17.debug.bz2 \ @@ -119,7 +122,8 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh \ run-bug1-test.sh testfile28.bz2 testfile28.rdwr.bz2 \ testfile29.bz2 testfile29.rdwr.bz2 \ testfile30.bz2 testfile31.bz2 testfile32.bz2 testfile33.bz2 \ - testfile34.bz2 + testfile34.bz2 testfile35.bz2 testfile35.debug.bz2 + testfile36.bz2 testfile36.debug.bz2 installed_TESTS_ENVIRONMENT = libdir=$(DESTDIR)$(libdir) \ bindir=$(DESTDIR)$(bindir) \ diff --git a/tests/run-dwfl-bug-offline-rel.sh b/tests/run-dwfl-bug-offline-rel.sh new file mode 100755 index 000000000..40e90bec6 --- /dev/null +++ b/tests/run-dwfl-bug-offline-rel.sh @@ -0,0 +1,36 @@ +#! /bin/sh +# Copyright (C) 2007 Red Hat, Inc. +# This file is part of Red Hat elfutils. +# +# Red Hat elfutils is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by the +# Free Software Foundation; version 2 of the License. +# +# Red Hat elfutils is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with Red Hat elfutils; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. +# +# Red Hat elfutils is an included package of the Open Invention Network. +# An included package of the Open Invention Network is a package for which +# Open Invention Network licensees cross-license their patents. No patent +# license is granted, either expressly or impliedly, by designation as an +# included package. Should you wish to participate in the Open Invention +# Network licensing program, please visit www.openinventionnetwork.com +# . + +. $srcdir/test-subr.sh + +testfiles testfile36 testfile36.debug + +testrun_compare ./dwflmodtest -e testfile36 <<\EOF +module: 00000000..00002308 testfile36 (null) +module: 00000000 (nil) 0 (Callback returned failure) +module: 00000000..00002308 testfile36 testfile36.debug +EOF + +exit 0 diff --git a/tests/run-strip-test.sh b/tests/run-strip-test.sh index 9a82d53d2..480101ebd 100755 --- a/tests/run-strip-test.sh +++ b/tests/run-strip-test.sh @@ -36,16 +36,18 @@ tempfiles testfile.temp testfile.debug.temp testfile.unstrip testrun ../src/strip -o testfile.temp $debugout $original -cmp $stripped testfile.temp +status=0 + +cmp $stripped testfile.temp || status=$? # Check elflint and the expected result. -testrun ../src/elflint -q testfile.temp +testrun ../src/elflint -q testfile.temp || status=$? test -z "$debugfile" || { -cmp $debugfile testfile.debug.temp +cmp $debugfile testfile.debug.temp || status=$? # Check elflint and the expected result. -testrun ../src/elflint -q -d testfile.debug.temp +testrun ../src/elflint -q -d testfile.debug.temp || status=$? # Now test unstrip recombining those files. testrun ../src/unstrip -o testfile.unstrip testfile.temp testfile.debug.temp @@ -54,4 +56,4 @@ testrun ../src/unstrip -o testfile.unstrip testfile.temp testfile.debug.temp testrun ../src/elfcmp --hash-inexact $original testfile.unstrip } -exit 0 +exit $status diff --git a/tests/run-strip-test4.sh b/tests/run-strip-test4.sh index 8e9be228b..64924a928 100755 --- a/tests/run-strip-test4.sh +++ b/tests/run-strip-test4.sh @@ -1,5 +1,5 @@ original=testfile11 -stripped=testfile15 -debugfile=testfile15.debug +stripped=testfile37 +debugfile=testfile37.debug . $srcdir/run-strip-test.sh diff --git a/tests/run-strip-test6.sh b/tests/run-strip-test6.sh index 8ee5f02cb..c59bf5e43 100755 --- a/tests/run-strip-test6.sh +++ b/tests/run-strip-test6.sh @@ -1,5 +1,5 @@ original=testfile12 -stripped=testfile17 -debugfile=testfile17.debug +stripped=testfile35 +debugfile=testfile35.debug . $srcdir/run-strip-test.sh diff --git a/tests/run-unstrip-test.sh b/tests/run-unstrip-test.sh new file mode 100755 index 000000000..670290515 --- /dev/null +++ b/tests/run-unstrip-test.sh @@ -0,0 +1,41 @@ +#! /bin/sh +# Copyright (C) 2007 Red Hat, Inc. +# This file is part of Red Hat elfutils. +# +# Red Hat elfutils is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by the +# Free Software Foundation; version 2 of the License. +# +# Red Hat elfutils is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with Red Hat elfutils; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. +# +# Red Hat elfutils is an included package of the Open Invention Network. +# An included package of the Open Invention Network is a package for which +# Open Invention Network licensees cross-license their patents. No patent +# license is granted, either expressly or impliedly, by designation as an +# included package. Should you wish to participate in the Open Invention +# Network licensing program, please visit www.openinventionnetwork.com +# . + +. $srcdir/test-subr.sh + +original=${original:-testfile12} +stripped=${stripped:-testfile17} +debugfile=${debugfile:-${stripped}.debug} + +testfiles $original $stripped $debugfile + +# These are old reference output from run-test-strip6.sh, when +# strip left the .debug file with unchanged sh_size in +# stripped sections that shrank in the stripped file. strip +# no longer does that, but unstrip must still handle it. + +testrun ../src/unstrip -o testfile.unstrip $stripped $debugfile + +testrun ../src/elfcmp --hash-inexact $original testfile.unstrip diff --git a/tests/run-unstrip-test2.sh b/tests/run-unstrip-test2.sh new file mode 100755 index 000000000..44074c19a --- /dev/null +++ b/tests/run-unstrip-test2.sh @@ -0,0 +1,5 @@ +original=testfile11 +stripped=testfile15 +debugfile=testfile15.debug + +. $srcdir/run-unstrip-test.sh diff --git a/tests/testfile35.bz2 b/tests/testfile35.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..b59130157d4c33bf14f70bd5d380e5a433369579 GIT binary patch literal 1643 zc-jGL29)_iT4*^jL0KkKS%IA?g#ZQ~|NsC0|Nr{u|9^k?{(b-d|8UQ0M&n6gNkwh2 zP!vXdWns_-P+p-nEih(K1{x6oC#pYFOlq4`KxvVqN2q9efrw}{+Mc2682}F`2GqpR zdQ8a%fF7ogPzR_6fDH+zlRzozVq$7~n@P1zrV%|RngGygkZ1#H0NR5_fuW!VXn+q; z2ATlTrhq}CMw&8WGHHY{G6sg2LlDrwm87dTG);(24wDRZ=4 zlW#7*QI(Y-NH{qhl^|=c%8hqA_FL0PV zhzAe|8*B!|n?q@|nA00->)L<~aP*@(n*OIQS2F10CH6mRleC>_h0zCTeGUE;RM8&K zj)W;5Xo23?AQ`+Em9c4G#0fVrt!@@4GaS^j)ZA3K?gS? ziJ9>qXeB6C)F7UE z(pU@;#qo16c+-eF>_WPHOBh*phT{L&61Gd$oCTx2<#sYMG5ivwAi-$HVi9#%t?o$< zV!K4m81zrK*MqjFR2#IEv+0Is+n^B*5~&>JqNxf_xX2G@gbt%b!(-Xf@p7>A5)*d<6@!|)RNRzGc!J!tjci#x}nY@FOt#_zoD`-FkAp+W-+m_ zn$(h{rXddkQ#LW(3@AjQN>?|9?C34pps0|IG^H)0k|aS?YVOBE=+q~q%72zd4kYy% zQSGr2&@jN_nSrLYXs|^ht5odZmCPA}{wkBV2i7AJs(;Eg)0L1;n40-yA9LWeCc}pA z3Y7;cNY|p8Fx8yKD*ACzWQ!vCP*Vt)MKo|JkX4?oOw6oS`$YOdAceawHb}^YqxjkE z4FeFGZA4>CleCN|Pp4A%(In(nMIp){-27`A9=eVj)1k($lwdn7gN(*OW!<(1<&x4tA_AX}7ZF0yT;Nlyarj5y$3y{qItilbnvA!j* zNQJCyCZN)U;=fA$nCGKQXE?X|Za1n>8?+s1>V@1Z7ZBir1|bzuc#TO0g0YMe5{qQ~ z+o*8DvDZ}CdEn6n%S3%BLtjHzA=Qs`gogo=BCS3FeFfj&Ka_t5NYc=IBM%{&DvNG= z0JE6c!>cz)8WTx)XlvcIP!WpbAraro6_RnEil}D3PuKQQQRcx=qLLv52&Cc`z>6TK z4yy^WZ;5QK>f(*c;v_1Ag@Q^&O5_U92aGx*xh`Tn`)K+mPamVo>nI?`M_70}nF(&% z3|ftLu#roH0uZLHibmdD$)U_K(n7oW76D^i(R9H^_vO?gDt4${gPwJ$049#?<#X9_ zgEKH?rO85jfwUxGthHIV4FHfA3&SYjoD&>>|0@SQRs~!#OzW(G2MZ6oP pFZ_ZTO2UN6896ypV|TC?nKu;u4~EAp=EC!fxgwk>NI=e%!hljp`4s>F literal 0 Hc-jL100001 diff --git a/tests/testfile35.debug.bz2 b/tests/testfile35.debug.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..f19186272c1286b2263f76f1e15e30c71c3a86ff GIT binary patch literal 9106 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 sYE`3M{=j`=XgQ`V)uo+gPDzeBM z(Vj#Bfv8XyEPOX1BsPJtsLY_k9;e>y-Q{}Cl0akI8J95=iLk};XUdYR%GFf_Kv)7a zk_T(^18i~t#djBh^DL1xs0+(RaH0gZS=7*l%!!cho%X!lB$BD9-T>Am)6tbk<5P+6 zw@lp=pCm(l;c}{gGD!nQF^Yp{6EcT>Ahzl(9r*_Kf)@M-4Rw+_$)(N6(WC(YgJq^W z*Iz?wYv+)9wQWMzf{pVlTfm*{(mSlgjurJ=!NRs*pR>0${L{E28kuCI5(7DWB2OKU zsh5K&?lg%@ES zL2f}W6lcUt9fp@d3yl!fLxXG$QM|N{R;fIE0B2lg&}A5}Ktn4>1w3NKi#MQ!q}p`N z(dWk*%F0uYc~PRPjx@a#2FMtvo?7;2<$GnQW8%}Q^kfmSib@Qm!b3)|42VHBB+?2( z3MQurDEkWsr0tf&T%#*{_~#k^Iiw`7_PLBr}*E`5_KS6pg0qKu>CT3Ya$ zO0?U)YD3()D>SZFJoy&6K1Q-!upvPZkRcdlcfrU?{6*2UnxFGC0RVEFXDe-q@Y z_B%S5G_d8GNtqE6fwEqzILGaV!YUO60xFPMi1M<^y!Ba>;^sCO@q|c50w-c-WG-`Y znp|$nBIMrM78C(M8+r)h1@?prUXLvYks2yCF~Gr>k+DgHiN6K)%~LNr_!vrc(cmyZ zQp0kquwkK6TcWavTA_7DVN(>Kx85a09E|jd)K!_(ZjrK?05X```!)~5fk4)*m6j?6HhYm!dO=os+%uepBUAw@7wl217NG6if(``Z&8W=+r(`eJR zuY0^=60vHQ9J_Nyda|=nS!y+5sDu*Iguw!ZR6vWORu?_$^>4QK*QE1l-6}*nK@p70 z31&Jrw=c5yxB-eMsEo3>ok(Q$y2zY~1@&MUI0bp(QndidMrv)p%q9VJ(#SRp7@P^x z0%3shjjXj1cwK=luuU^`ckwqPh{F?|C1DV7i8M=>Hf(bVRJe^4;wWTiy=|GnLWrH@ zn)3}NeH2-}&xI>)0bZ;m149HcYs<3lPfWwSeltOKuK0D5EUDF~;nrl!Q$1j>5=!x0 zw25Yegt;Zc{Et85W$T&>G#Ny=Zdk5zn)Vhnq48N9Z(BD?2Jw6l)$IhBNu=19Cs#SM zAM+j^eIa>ve3%_^nMiHI4=oEfq63wPi77%V+Qxk~ZkRE*kn6KHYF$Sj8iqAOju$&e(hbq=%|^<8cNO<5176e9S)b&$7cC{f$speqc4ex`O)|(T9nFp+S`H<;u;3 zo8Vyl|oX&HF z@xC%pe&ze^%1~S3-=1<3oom#s_!!u898)=&E5D`XJ(HS`k>Cwyg?kNq3=#Z Qi+}NVBvXY60fVrtkZ>#*;{X5v literal 0 Hc-jL100001 diff --git a/tests/testfile36.bz2 b/tests/testfile36.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..e912a1979c0f5e11f9599ee39c5d6af58eb2305b GIT binary patch literal 714 zc-jHV0yX_YT4*^jL0KkKSp)6KApipHfByge`Qm$vf1-PaPDcOl-|*)IL_|mcfIvV1 z06-uZzyeC*mbRocLXDzECZ488sisY&G{B6F15E=#p`dA|CW9kGAT=~iC!<95F&bz? zOh5nupa2a30BC45Xa@s8&6T7XX>%)d$?i@c;#d z=JQv*eubwhd{*oAwNeo*MTu%@6AWfgI%rEx&vp`q9!mcklR%1?E^pKwuTdIrJ*0qH zEJ!zAa|AXdHYA%ye#D|ADK^n^Aa>g!#33h_3LTb=&fEetTG1!@DZrjC+n{3FpuPc= zozDM7K2h0VU1iXcgbauQA{)a4Z?U!%CcwyO!+7mzSAljIlr+5^Kv0CNG$FAutdfXA z3k-%98G9%c;B%3h{frS!V27V*0ahj4uBGuDtQEf%iyPJK8@I1gt1Y?U!e=0`sRC@& z5Gqj1LtNe{vh)(t;$}0+8ESRs>oXbTkr5#-TuoG-8k|Dat!pe}oYJ4|6cACH`i&n6 zFcKUO65uzc)7CmrRtRDbg5#7_jJ%}RIJu--D_gBoM2d`wQZZDI<*W%dugTdcBssvE zVB`N01F+H8lqKCzj6g0vW>GWK!(q{oB^XE`H5gHf@QOXx_q3LahaM?-uI$^jWrJe7 z)2O8c5MLL@8w6$su%Nh=G%aBuR2Mx{^6lyI_El5M}1&M_<;S^zOQ6T1E wZGvDj1>15Hl*CTY2;)tAZ6L(%4cQUTmHw|?(UzbPbD!~dBvXY606yH35T^q!4gdfE literal 0 Hc-jL100001 diff --git a/tests/testfile36.debug.bz2 b/tests/testfile36.debug.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..76aca42e5b0462b16fcc01103fa42c26dbbd5a45 GIT binary patch literal 24909 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

U~63ExXA0#wCL7!=lft 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

IA{0QQeB0ar*`EVmJe3hP(nx^{qc4_v4*Z&i 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 literal 0 Hc-jL100001 diff --git a/tests/testfile37.bz2 b/tests/testfile37.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..254ce324ad86eca47768bb51f3027e99fbf43ecd GIT binary patch literal 3140 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 literal 0 Hc-jL100001 diff --git a/tests/testfile37.debug.bz2 b/tests/testfile37.debug.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..74e46a87f6d93f635ea7be1de7888105f1177dc3 GIT binary patch literal 28522 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