diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 72 | ||||
| -rw-r--r-- | src/Makefile.am | 42 | ||||
| -rw-r--r-- | src/addr2line.c | 4 | ||||
| -rw-r--r-- | src/ar.c | 181 | ||||
| -rw-r--r-- | src/elfcmp.c | 2 | ||||
| -rw-r--r-- | src/elfcompress.c | 15 | ||||
| -rw-r--r-- | src/elflint.c | 2 | ||||
| -rw-r--r-- | src/findtextrel.c | 4 | ||||
| -rw-r--r-- | src/nm.c | 2 | ||||
| -rw-r--r-- | src/objdump.c | 2 | ||||
| -rw-r--r-- | src/ranlib.c | 48 | ||||
| -rw-r--r-- | src/readelf.c | 7 | ||||
| -rw-r--r-- | src/size.c | 6 | ||||
| -rw-r--r-- | src/stack.c | 24 | ||||
| -rw-r--r-- | src/strings.c | 7 | ||||
| -rw-r--r-- | src/strip.c | 66 | ||||
| -rw-r--r-- | src/unstrip.c | 7 |
17 files changed, 296 insertions, 195 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index cbb77fc8..32cd0c37 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,75 @@ +2017-05-04 Ulf Hermann <[email protected]> + + * ar.c: Use trees rather than hashes. + +2017-05-04 Ulf Hermann <[email protected]> + + * ar.c: Use octal numbers instead of permission macros. + * elfcompress.c: Likewise. + * ranlib.c: Likewise. + * strip.c: Likewise. + +2017-05-04 Ulf Hermann <[email protected]> + + * unstrip.c: Use strndup and free instead of strndupa. + +2017-05-04 Ulf Hermann <[email protected]> + + * stack.c: Cast pid_t to int when printing using %d. + +2017-05-04 Ulf Hermann <[email protected]> + + * strip.c: Close and reopen file when renaming. + +2017-05-04 Ulf Hermann <[email protected]> + + * addr2line.c: Don't assume unix file system conventions. + * size.c: Likewise. + * strip.c: Likewise. + +2017-05-04 Ulf Hermann <[email protected]> + + * ar.c: Open files in O_BINARY. + * elfcmp.c: Likewise. + * elfcompress.c: Likewise. + * elflint.c: Likewise. + * findtextrel.c: Likewise. + * nm.c: Likewise. + * objdump.c: Likewise. + * ranlib.c: Likewise. + * readelf.c: Likewise. + * size.c: Likewise. + * stack.c: Likewise. + * strings.c: Likewise. + * strip.c: Likewise. + * unstrip.c: Likewise. + +2017-05-04 Ulf Hermann <[email protected]> + + * ar.c: Don't fchmod or fchown the output file if fchmod or fchown + don't exist. + * elfcompress.c: Likewise. + * ranlib.c: Likewise. + * strip.c: Likewise. + * strings.c: Skip posix_fadvise if it doesn't exist. + +2017-05-04 Ulf Hermann <[email protected]> + + * strings.c: If roundup() is not defined, define it. + +2017-04-28 Ulf Hermann <[email protected]> + + * Makefile.am: Use the predefined names for libelf, libdw, libasm, + rather than hardcoding to the elf conventions. + +2017-04-27 Ulf Hermann <[email protected]> + + * Makefile.am: Drop argp_LDADD. + +2017-04-21 Ulf Hermann <[email protected]> + + * Makefile.am: Link tools agaist libgnu.a if requested. + 2017-04-20 Ulf Hermann <[email protected]> * readelf.c: Include strings.h. diff --git a/src/Makefile.am b/src/Makefile.am index 2b1c0dcb..39ade95b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -24,6 +24,7 @@ AM_CPPFLAGS += -I$(srcdir)/../libelf -I$(srcdir)/../libebl \ -I$(srcdir)/../libdwfl -I$(srcdir)/../libasm AM_LDFLAGS = -Wl,-rpath-link,../libelf:../libdw +AM_CFLAGS += -Wno-null-dereference bin_PROGRAMS = readelf nm size strip elflint findtextrel addr2line \ elfcmp objdump ranlib strings ar unstrip stack elfcompress @@ -43,12 +44,17 @@ libasm = ../libasm/libasm.a libdw = ../libdw/libdw.a -lz $(zip_LIBS) $(libelf) $(libebl) -ldl libelf = ../libelf/libelf.a -lz else -libasm = ../libasm/libasm.so -libdw = ../libdw/libdw.so -libelf = ../libelf/libelf.so +libasm = ../libasm/$(libasm_BARE) +libdw = ../libdw/$(libdw_BARE) +libelf = ../libelf/$(libelf_BARE) endif libebl = ../libebl/libebl.a libeu = ../lib/libeu.a +if USE_GNULIB +libgnu = ../libgnu/libgnu.a +else +libgnu = +endif if DEMANGLE demanglelib = -lstdc++ @@ -67,22 +73,22 @@ ranlib_no_Wstack_usage = yes ar_no_Wstack_usage = yes unstrip_no_Wstack_usage = yes -readelf_LDADD = $(libdw) $(libebl) $(libelf) $(libeu) $(argp_LDADD) -ldl -nm_LDADD = $(libdw) $(libebl) $(libelf) $(libeu) $(argp_LDADD) -ldl \ +readelf_LDADD = $(libdw) $(libebl) $(libelf) $(libeu) $(libgnu) $(intl_LDADD) -ldl +nm_LDADD = $(libdw) $(libebl) $(libelf) $(libeu) $(libgnu) $(intl_LDADD) -ldl \ $(demanglelib) -size_LDADD = $(libelf) $(libeu) $(argp_LDADD) -strip_LDADD = $(libebl) $(libelf) $(libdw) $(libeu) $(argp_LDADD) -ldl -elflint_LDADD = $(libebl) $(libelf) $(libeu) $(argp_LDADD) -ldl -findtextrel_LDADD = $(libdw) $(libelf) $(libeu) $(argp_LDADD) -addr2line_LDADD = $(libdw) $(libelf) $(libeu) $(argp_LDADD) $(demanglelib) -elfcmp_LDADD = $(libebl) $(libelf) $(libeu) $(argp_LDADD) -ldl -objdump_LDADD = $(libasm) $(libebl) $(libelf) $(libeu) $(argp_LDADD) -ldl -ranlib_LDADD = libar.a $(libelf) $(libeu) $(argp_LDADD) -strings_LDADD = $(libelf) $(libeu) $(argp_LDADD) -ar_LDADD = libar.a $(libelf) $(libeu) $(argp_LDADD) -unstrip_LDADD = $(libebl) $(libelf) $(libdw) $(libeu) $(argp_LDADD) -ldl -stack_LDADD = $(libebl) $(libelf) $(libdw) $(libeu) $(argp_LDADD) -ldl $(demanglelib) -elfcompress_LDADD = $(libebl) $(libelf) $(libdw) $(libeu) $(argp_LDADD) +size_LDADD = $(libelf) $(libeu) $(libgnu) $(intl_LDADD) +strip_LDADD = $(libebl) $(libelf) $(libdw) $(libeu) $(libgnu) $(intl_LDADD) -ldl +elflint_LDADD = $(libebl) $(libelf) $(libeu) $(libgnu) $(intl_LDADD) -ldl +findtextrel_LDADD = $(libdw) $(libelf) $(libeu) $(libgnu) $(intl_LDADD) +addr2line_LDADD = $(libdw) $(libelf) $(libeu) $(libgnu) $(intl_LDADD) $(demanglelib) +elfcmp_LDADD = $(libebl) $(libelf) $(libeu) $(libgnu) $(intl_LDADD) -ldl +objdump_LDADD = $(libasm) $(libebl) $(libelf) $(libeu) $(libgnu) $(intl_LDADD) -ldl +ranlib_LDADD = libar.a $(libelf) $(libeu) $(libgnu) $(intl_LDADD) +strings_LDADD = $(libelf) $(libeu) $(libgnu) $(intl_LDADD) +ar_LDADD = libar.a $(libelf) $(libeu) $(libgnu) $(intl_LDADD) +unstrip_LDADD = $(libebl) $(libelf) $(libdw) $(libeu) $(libgnu) $(intl_LDADD) -ldl +stack_LDADD = $(libebl) $(libelf) $(libdw) $(libeu) $(libgnu) $(intl_LDADD) -ldl $(demanglelib) +elfcompress_LDADD = $(libebl) $(libelf) $(libdw) $(libeu) $(libgnu) $(intl_LDADD) installcheck-binPROGRAMS: $(bin_PROGRAMS) bad=0; pid=$$$$; list="$(bin_PROGRAMS)"; for p in $$list; do \ diff --git a/src/addr2line.c b/src/addr2line.c index ba414a74..7ee9fcfc 100644 --- a/src/addr2line.c +++ b/src/addr2line.c @@ -375,7 +375,7 @@ print_dwarf_function (Dwfl_Module *mod, Dwarf_Addr addr) file = "???"; else if (only_basenames) file = basename (file); - else if (use_comp_dir && file[0] != '/') + else if (use_comp_dir && !IS_ABSOLUTE_PATH(file)) { const char *const *dirs; size_t ndirs; @@ -559,7 +559,7 @@ print_src (const char *src, int lineno, int linecol, Dwarf_Die *cu) if (only_basenames) src = basename (src); - else if (use_comp_dir && src[0] != '/') + else if (use_comp_dir && !IS_ABSOLUTE_PATH(src)) { Dwarf_Attribute attr; comp_dir = dwarf_formstring (dwarf_attr (cu, DW_AT_comp_dir, &attr)); @@ -393,14 +393,14 @@ open_archive (const char *arfname, int flags, int mode, Elf **elf, if (elf != NULL) { - Elf_Cmd cmd = flags == O_RDONLY ? ELF_C_READ_MMAP : ELF_C_RDWR_MMAP; + Elf_Cmd cmd = flags == (O_RDONLY | O_BINARY) ? ELF_C_READ_MMAP : ELF_C_RDWR_MMAP; *elf = elf_begin (fd, cmd, NULL); if (*elf == NULL) error (EXIT_FAILURE, 0, gettext ("cannot open archive '%s': %s"), arfname, elf_errmsg (-1)); - if (flags == O_RDONLY && elf_kind (*elf) != ELF_K_AR) + if (flags == (O_RDONLY | O_BINARY) && elf_kind (*elf) != ELF_K_AR) error (EXIT_FAILURE, 0, gettext ("%s: not an archive file"), arfname); } @@ -439,6 +439,20 @@ copy_content (Elf *elf, int newfd, off_t off, size_t n) static int +string_compare (const void *a, const void *b) +{ + return strcmp((const char *)a, (const char *)b); +} + + +void +free_node (void *node) +{ + (void) node; +} + + +static int do_oper_extract (int oper, const char *arfname, char **argv, int argc, long int instance) { @@ -448,16 +462,6 @@ do_oper_extract (int oper, const char *arfname, char **argv, int argc, size_t name_max = 0; inline bool should_truncate_fname (void) { - if (errno == ENAMETOOLONG && allow_truncate_fname) - { - if (name_max == 0) - { - long int len = pathconf (".", _PC_NAME_MAX); - if (len > 0) - name_max = len; - } - return name_max != 0; - } return false; } @@ -467,15 +471,13 @@ do_oper_extract (int oper, const char *arfname, char **argv, int argc, int status = 0; Elf *elf; - int fd = open_archive (arfname, O_RDONLY, 0, &elf, NULL, false); + int fd = open_archive (arfname, O_RDONLY | O_BINARY, 0, &elf, NULL, false); - if (hcreate (2 * argc) == 0) - error (EXIT_FAILURE, errno, gettext ("cannot create hash table")); + void *root = NULL; for (int cnt = 0; cnt < argc; ++cnt) { - ENTRY entry = { .key = argv[cnt], .data = &argv[cnt] }; - if (hsearch (entry, ENTER) == NULL) + if (tsearch (argv[cnt], &root, &string_compare) == NULL) error (EXIT_FAILURE, errno, gettext ("cannot insert into hash table")); } @@ -517,12 +519,10 @@ do_oper_extract (int oper, const char *arfname, char **argv, int argc, bool do_extract = argc <= 0; if (!do_extract) { - ENTRY entry; - entry.key = arhdr->ar_name; - ENTRY *res = hsearch (entry, FIND); + void *res = tfind (arhdr->ar_name, &root, &string_compare); if (res != NULL && (instance < 0 || instance-- == 0) - && !found[(char **) res->data - argv]) - found[(char **) res->data - argv] = do_extract = true; + && !found[(char **) res - argv]) + found[(char **) res - argv] = do_extract = true; } if (do_extract) @@ -540,7 +540,7 @@ do_oper_extract (int oper, const char *arfname, char **argv, int argc, else if (oper == oper_list) { char datestr[100]; - strftime (datestr, sizeof (datestr), "%b %e %H:%M %Y", + strftime (datestr, sizeof (datestr), "%b %d %H:%M %Y", localtime (&arhdr->ar_date)); printf ("%c%c%c%c%c%c%c%c%c %u/%u %6ju %s %s\n", @@ -600,7 +600,7 @@ do_oper_extract (int oper, const char *arfname, char **argv, int argc, { /* We cannot create a temporary file. Try to overwrite the file or create it if it does not exist. */ - int flags = O_WRONLY | O_CREAT; + int flags = O_WRONLY | O_BINARY | O_CREAT; if (dont_replace_existing) flags |= O_EXCL; else @@ -655,6 +655,7 @@ do_oper_extract (int oper, const char *arfname, char **argv, int argc, if (oper != oper_print) { +#if HAVE_DECL_FCHMOD /* Fix up the mode. */ if (unlikely (fchmod (xfd, arhdr->ar_mode) != 0)) { @@ -662,23 +663,7 @@ do_oper_extract (int oper, const char *arfname, char **argv, int argc, arhdr->ar_name); status = 0; } - - if (preserve_dates) - { - struct timespec tv[2]; - tv[0].tv_sec = arhdr->ar_date; - tv[0].tv_nsec = 0; - tv[1].tv_sec = arhdr->ar_date; - tv[1].tv_nsec = 0; - - if (unlikely (futimens (xfd, tv) != 0)) - { - error (0, errno, - gettext ("cannot change modification time of %s"), - arhdr->ar_name); - status = 1; - } - } +#endif /* If we used a temporary file, move it do the right name now. */ @@ -739,7 +724,8 @@ cannot rename temporary file to %.*s"), error (1, 0, "%s: %s", arfname, elf_errmsg (-1)); } - hdestroy (); + tdestroy(root, &free_node); + root = NULL; if (force_symtab) { @@ -788,20 +774,25 @@ cannot rename temporary file to %.*s"), != (ssize_t) symtab.symsofflen) || (write_retry (newfd, symtab.symsname, symtab.symsnamelen) - != (ssize_t) symtab.symsnamelen))) + != (ssize_t) symtab.symsnamelen))) || /* Even if the original file had content before the symbol table, we write it in the correct order. */ - || (index_off != SARMAG - && copy_content (elf, newfd, SARMAG, index_off - SARMAG)) - || copy_content (elf, newfd, rest_off, st.st_size - rest_off) + (index_off != SARMAG + && copy_content (elf, newfd, SARMAG, index_off - SARMAG)) || + copy_content (elf, newfd, rest_off, st.st_size - rest_off) || +#if HAVE_DECL_FCHMOD /* Set the mode of the new file to the same values the original file has. */ - || fchmod (newfd, st.st_mode & ALLPERMS) != 0 + fchmod (newfd, st.st_mode & 07777) != 0 || +#endif + ( +#if HAVE_DECL_FCHOWN /* Never complain about fchown failing. */ - || (({asm ("" :: "r" (fchown (newfd, st.st_uid, + ({asm ("" :: "r" (fchown (newfd, st.st_uid, st.st_gid))); }), - close (newfd) != 0) - || (newfd = -1, rename (tmpfname, arfname) != 0)) +#endif + close (newfd) != 0) || + (newfd = -1, rename (tmpfname, arfname) != 0)) goto nonew_unlink; } } @@ -912,15 +903,13 @@ do_oper_delete (const char *arfname, char **argv, int argc, int status = 0; Elf *elf; struct stat st; - int fd = open_archive (arfname, O_RDONLY, 0, &elf, &st, false); + int fd = open_archive (arfname, O_RDONLY | O_BINARY, 0, &elf, &st, false); - if (hcreate (2 * argc) == 0) - error (EXIT_FAILURE, errno, gettext ("cannot create hash table")); + void *root = NULL; for (int cnt = 0; cnt < argc; ++cnt) { - ENTRY entry = { .key = argv[cnt], .data = &argv[cnt] }; - if (hsearch (entry, ENTER) == NULL) + if (tsearch (argv[cnt], &root, &string_compare) == NULL) error (EXIT_FAILURE, errno, gettext ("cannot insert into hash table")); } @@ -942,12 +931,10 @@ do_oper_delete (const char *arfname, char **argv, int argc, bool do_delete = argc <= 0; if (!do_delete) { - ENTRY entry; - entry.key = arhdr->ar_name; - ENTRY *res = hsearch (entry, FIND); + void *res = tfind (arhdr->ar_name, &root, &string_compare); if (res != NULL && (instance < 0 || instance-- == 0) - && !found[(char **) res->data - argv]) - found[(char **) res->data - argv] = do_delete = true; + && !found[(char **) res - argv]) + found[(char **) res - argv] = do_delete = true; } if (do_delete) @@ -988,7 +975,8 @@ do_oper_delete (const char *arfname, char **argv, int argc, arlib_finalize (); - hdestroy (); + tdestroy (root, &free_node); + root = NULL; /* Create a new, temporary file in the same directory as the original file. */ @@ -1046,13 +1034,19 @@ do_oper_delete (const char *arfname, char **argv, int argc, goto nonew_unlink; } - /* Set the mode of the new file to the same values the original file - has. */ - if (fchmod (newfd, st.st_mode & ALLPERMS) != 0 + if ( +#if HAVE_DECL_FCHMOD + /* Set the mode of the new file to the same values the original file + has. */ + fchmod (newfd, st.st_mode & 07777) != 0 || +#endif + ( +#if HAVE_DECL_FCHOWN /* Never complain about fchown failing. */ - || (({asm ("" :: "r" (fchown (newfd, st.st_uid, st.st_gid))); }), - close (newfd) != 0) - || (newfd = -1, rename (tmpfname, arfname) != 0)) + ({asm ("" :: "r" (fchown (newfd, st.st_uid, st.st_gid))); }), +#endif + close (newfd) != 0) || + (newfd = -1, rename (tmpfname, arfname) != 0)) goto nonew_unlink; errout: @@ -1080,13 +1074,21 @@ no0print (bool ofmt, char *buf, int bufsize, long int val) static int +basename_compare(const void *a, const void *b) +{ + return strcmp(basename((const char *)a), basename((const char *)b)); +} + + +static int do_oper_insert (int oper, const char *arfname, char **argv, int argc, const char *member) { int status = 0; Elf *elf; struct stat st; - int fd = open_archive (arfname, O_RDONLY, 0, &elf, &st, oper != oper_move); + int fd = open_archive (arfname, O_RDONLY | O_BINARY, 0, &elf, &st, oper != oper_move); + void *root = NULL; /* List of the files we keep. */ struct armem *all = NULL; @@ -1114,15 +1116,9 @@ do_oper_insert (int oper, const char *arfname, char **argv, int argc, index. */ if (oper != oper_qappend) { - if (hcreate (2 * argc) == 0) - error (EXIT_FAILURE, errno, gettext ("cannot create hash table")); - for (int cnt = 0; cnt < argc; ++cnt) { - ENTRY entry; - entry.key = full_path ? argv[cnt] : basename (argv[cnt]); - entry.data = &argv[cnt]; - if (hsearch (entry, ENTER) == NULL) + if (tsearch (argv[cnt], &root, full_path ? &basename_compare : &string_compare) == NULL) error (EXIT_FAILURE, errno, gettext ("cannot insert into hash table")); } @@ -1165,12 +1161,10 @@ do_oper_insert (int oper, const char *arfname, char **argv, int argc, member = NULL; } - ENTRY entry; - entry.key = arhdr->ar_name; - ENTRY *res = hsearch (entry, FIND); - if (res != NULL && found[(char **) res->data - argv] == NULL) + void *res = tfind(arhdr->ar_name, &root, full_path ? &basename_compare : &string_compare); + if (res != NULL && found[(char **) res - argv] == NULL) { - found[(char **) res->data - argv] = newp; + found[(char **) res - argv] = newp; /* If we insert before or after a certain element move all files to a special list. */ @@ -1202,7 +1196,10 @@ do_oper_insert (int oper, const char *arfname, char **argv, int argc, } if (oper != oper_qappend) - hdestroy (); + { + tdestroy(root, &free_node); + root = NULL; + } no_old: if (member != NULL) @@ -1242,7 +1239,7 @@ do_oper_insert (int oper, const char *arfname, char **argv, int argc, struct stat newst; Elf *newelf; - int newfd = open (argv[cnt], O_RDONLY); + int newfd = open (argv[cnt], O_RDONLY | O_BINARY); if (newfd == -1) { error (0, errno, gettext ("cannot open %s"), argv[cnt]); @@ -1386,7 +1383,7 @@ do_oper_insert (int oper, const char *arfname, char **argv, int argc, newfd = mkstemp (tmpfname); else { - newfd = open (arfname, O_RDWR | O_CREAT | O_EXCL, DEFFILEMODE); + newfd = open (arfname, O_RDWR | O_BINARY | O_CREAT | O_EXCL, 0666); if (newfd == -1 && errno == EEXIST) /* Bah, first the file did not exist, now it does. Restart. */ return do_oper_insert (oper, arfname, argv, argc, member); @@ -1503,14 +1500,20 @@ do_oper_insert (int oper, const char *arfname, char **argv, int argc, goto nonew_unlink; } - /* Set the mode of the new file to the same values the original file - has. */ if (fd != -1 - && (fchmod (newfd, st.st_mode & ALLPERMS) != 0 + && ( +#if HAVE_DECL_FCHMOD + /* Set the mode of the new file to the same values the original file + has. */ + fchmod (newfd, st.st_mode & 07777) != 0 || +#endif + ( +#if HAVE_DECL_FCHOWN /* Never complain about fchown failing. */ - || (({asm ("" :: "r" (fchown (newfd, st.st_uid, st.st_gid))); }), - close (newfd) != 0) - || (newfd = -1, rename (tmpfname, arfname) != 0))) + ({asm ("" :: "r" (fchown (newfd, st.st_uid, st.st_gid))); }), +#endif + close (newfd) != 0) || + (newfd = -1, rename (tmpfname, arfname) != 0))) goto nonew_unlink; errout: diff --git a/src/elfcmp.c b/src/elfcmp.c index 50464207..7ca7efa3 100644 --- a/src/elfcmp.c +++ b/src/elfcmp.c @@ -714,7 +714,7 @@ parse_opt (int key, char *arg, static Elf * open_file (const char *fname, int *fdp, Ebl **eblp) { - int fd = open (fname, O_RDONLY); + int fd = open (fname, O_RDONLY | O_BINARY); if (unlikely (fd == -1)) error (2, errno, gettext ("cannot open '%s'"), fname); Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL); diff --git a/src/elfcompress.c b/src/elfcompress.c index 8e0d5c55..d1cef85b 100644 --- a/src/elfcompress.c +++ b/src/elfcompress.c @@ -135,7 +135,10 @@ parse_opt (int key, char *arg __attribute__ ((unused)), if (type == T_UNSET) type = T_COMPRESS_ZLIB; if (patterns == NULL) - add_pattern (".?(z)debug*"); + { + add_pattern (".debug*"); + add_pattern (".zdebug*"); + } break; case ARGP_KEY_NO_ARGS: @@ -321,7 +324,7 @@ process_file (const char *fname) return res; } - fd = open (fname, O_RDONLY); + fd = open (fname, O_RDONLY | O_BINARY); if (fd < 0) { error (0, errno, "Couldn't open %s\n", fname); @@ -542,7 +545,7 @@ process_file (const char *fname) else { fnew = xstrdup (foutput); - fdnew = open (fnew, O_WRONLY | O_CREAT, st.st_mode & ALLPERMS); + fdnew = open (fnew, O_WRONLY | O_BINARY | O_CREAT, st.st_mode & 07777); } if (fdnew < 0) @@ -1235,13 +1238,17 @@ process_file (const char *fname) elf_end (elfnew); elfnew = NULL; +#if HAVE_DECL_FCHMOD /* Try to match mode and owner.group of the original file. */ - if (fchmod (fdnew, st.st_mode & ALLPERMS) != 0) + if (fchmod (fdnew, st.st_mode & 07777) != 0) if (verbose >= 0) error (0, errno, "Couldn't fchmod %s", fnew); +#endif +#if HAVE_DECL_FCHOWN if (fchown (fdnew, st.st_uid, st.st_gid) != 0) if (verbose >= 0) error (0, errno, "Couldn't fchown %s", fnew); +#endif /* Finally replace the old file with the new file. */ if (foutput == NULL) diff --git a/src/elflint.c b/src/elflint.c index 51e53c23..18b5a4be 100644 --- a/src/elflint.c +++ b/src/elflint.c @@ -149,7 +149,7 @@ main (int argc, char *argv[]) do { /* Open the file. */ - int fd = open (argv[remaining], O_RDONLY); + int fd = open (argv[remaining], O_RDONLY | O_BINARY); if (fd == -1) { error (0, errno, gettext ("cannot open input file")); diff --git a/src/findtextrel.c b/src/findtextrel.c index 8f1e239a..642c0237 100644 --- a/src/findtextrel.c +++ b/src/findtextrel.c @@ -200,7 +200,7 @@ process_file (const char *fname, bool more_than_one) real_fname = new_fname; } - int fd = open (real_fname, O_RDONLY); + int fd = open (real_fname, O_RDONLY | O_BINARY); if (fd == -1) { error (0, errno, gettext ("cannot open '%s'"), fname); @@ -373,7 +373,7 @@ cannot get program header index at offset %zd: %s"), fname, fname_len), ".debug"); - fd2 = open (difname, O_RDONLY); + fd2 = open (difname, O_RDONLY | O_BINARY); if (fd2 != -1 && (elf2 = elf_begin (fd2, ELF_C_READ_MMAP, NULL)) != NULL) dw = dwarf_begin_elf (elf2, DWARF_C_READ, NULL); @@ -359,7 +359,7 @@ static int process_file (const char *fname, bool more_than_one) { /* Open the file. */ - int fd = open (fname, O_RDONLY); + int fd = open (fname, O_RDONLY | O_BINARY); if (fd == -1) { error (0, errno, gettext ("cannot open '%s'"), fname); diff --git a/src/objdump.c b/src/objdump.c index 860cfac6..13d3e0b8 100644 --- a/src/objdump.c +++ b/src/objdump.c @@ -236,7 +236,7 @@ static int process_file (const char *fname, bool more_than_one) { /* Open the file. */ - int fd = open (fname, O_RDONLY); + int fd = open (fname, O_RDONLY | O_BINARY); if (fd == -1) { error (0, errno, gettext ("cannot open %s"), fname); diff --git a/src/ranlib.c b/src/ranlib.c index cc0ee233..cd52219d 100644 --- a/src/ranlib.c +++ b/src/ranlib.c @@ -136,7 +136,7 @@ copy_content (Elf *elf, int newfd, off_t off, size_t n) static int handle_file (const char *fname) { - int fd = open (fname, O_RDONLY); + int fd = open (fname, O_RDONLY | O_BINARY); if (fd == -1) { error (0, errno, gettext ("cannot open '%s'"), fname); @@ -207,6 +207,9 @@ handle_file (const char *fname) /* If the file contains no symbols we need not do anything. */ int status = 0; + char tmpfname[strlen (fname) + 7]; + tmpfname[0] = '\0'; + if (symtab.symsnamelen != 0 /* We have to rewrite the file also if it initially had an index but now does not need one anymore. */ @@ -214,7 +217,6 @@ handle_file (const char *fname) { /* Create a new, temporary file in the same directory as the original file. */ - char tmpfname[strlen (fname) + 7]; strcpy (stpcpy (tmpfname, fname), "XXXXXX"); int newfd = mkstemp (tmpfname); if (unlikely (newfd == -1)) @@ -252,19 +254,23 @@ handle_file (const char *fname) != (ssize_t) symtab.symsofflen) || (write_retry (newfd, symtab.symsname, symtab.symsnamelen) - != (ssize_t) symtab.symsnamelen))) + != (ssize_t) symtab.symsnamelen))) || /* Even if the original file had content before the symbol table, we write it in the correct order. */ - || (index_off > SARMAG - && copy_content (arelf, newfd, SARMAG, index_off - SARMAG)) - || copy_content (arelf, newfd, rest_off, st.st_size - rest_off) + (index_off > SARMAG + && copy_content (arelf, newfd, SARMAG, index_off - SARMAG)) || + copy_content (arelf, newfd, rest_off, st.st_size - rest_off) || +#if HAVE_DECL_FCHMOD /* Set the mode of the new file to the same values the original file has. */ - || fchmod (newfd, st.st_mode & ALLPERMS) != 0 + fchmod (newfd, st.st_mode & 07777) != 0 || +#endif + ( +#if HAVE_DECL_FCHOWN /* Never complain about fchown failing. */ - || (({asm ("" :: "r" (fchown (newfd, st.st_uid, st.st_gid))); }), - close (newfd) != 0) - || (newfd = -1, rename (tmpfname, fname) != 0)) + ({asm ("" :: "r" (fchown (newfd, st.st_uid, st.st_gid))); }), +#endif + close (newfd) != 0) || (newfd = -1, false)) goto nonew_unlink; } } @@ -275,6 +281,28 @@ handle_file (const char *fname) close (fd); + if (status == 0 && tmpfname[0]) + { + char swapfname[strlen (fname) + 7]; + strcpy (stpcpy (swapfname, fname), "XXXXXX"); + mktemp (swapfname); + if (rename (fname, swapfname) != 0) + { + error (0, errno, gettext ("cannot move original file out of the way")); + status = 1; + } + if (rename (tmpfname, fname) != 0) + { + error (0, errno, gettext ("cannot move new file into place")); + if (rename (swapfname, fname) != 0) + error (0, errno, gettext ("cannot rescue original file")); + status = 1; + } + else + unlink (swapfname); + } + + unlink (tmpfname); return status; } diff --git a/src/readelf.c b/src/readelf.c index 40d49139..3ddd7c36 100644 --- a/src/readelf.c +++ b/src/readelf.c @@ -297,7 +297,7 @@ main (int argc, char *argv[]) do { /* Open the file. */ - int fd = open (argv[remaining], O_RDONLY); + int fd = open (argv[remaining], O_RDONLY | O_BINARY); if (fd == -1) { error (0, errno, gettext ("cannot open input file")); @@ -8418,7 +8418,6 @@ print_debug (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr) may happen in some cases of the core items. */ static unsigned int -__attribute__ ((format (printf, 6, 7))) print_core_item (unsigned int colno, char sep, unsigned int wrap, size_t name_width, const char *name, const char *format, ...) { @@ -9247,7 +9246,9 @@ handle_siginfo_note (Elf *core, GElf_Word descsz, GElf_Off desc_pos) case SIGILL: case SIGFPE: case SIGSEGV: +#ifdef SIGBUS case SIGBUS: +#endif { uint64_t addr; if (! buf_read_ulong (core, &ptr, end, &addr)) @@ -9258,6 +9259,7 @@ handle_siginfo_note (Elf *core, GElf_Word descsz, GElf_Off desc_pos) default: ; } +#ifdef SI_USER else if (si_code == SI_USER) { int pid, uid; @@ -9266,6 +9268,7 @@ handle_siginfo_note (Elf *core, GElf_Word descsz, GElf_Off desc_pos) goto fail; printf (" sender PID: %d, sender UID: %d\n", pid, uid); } +#endif } static void @@ -267,7 +267,7 @@ parse_opt (int key, char *arg, static int process_file (const char *fname) { - int fd = open (fname, O_RDONLY); + int fd = open (fname, O_RDONLY | O_BINARY); if (unlikely (fd == -1)) { error (0, errno, gettext ("cannot open '%s'"), fname); @@ -350,7 +350,7 @@ handle_ar (int fd, Elf *elf, const char *prefix, const char *fname) if (prefix != NULL) { cp = mempcpy (cp, prefix, prefix_len); - *cp++ = ':'; + *cp++ = PATHSEP; } memcpy (cp, fname, fname_len); @@ -635,7 +635,7 @@ handle_elf (Elf *elf, const char *prefix, const char *fname) if (prefix != NULL) { cp = mempcpy (cp, prefix, prefix_len); - *cp++ = ':'; + *cp++ = PATHSEP; } memcpy (cp, fname, fname_len); diff --git a/src/stack.c b/src/stack.c index 6f2ff69f..da912e5e 100644 --- a/src/stack.c +++ b/src/stack.c @@ -362,7 +362,7 @@ print_frames (struct frames *frames, pid_t tid, int dwflerr, const char *what) if (frames->frames > 0) frames_shown = true; - printf ("TID %d:\n", tid); + printf ("TID %lld:\n", (long long)tid); int frame_nr = 0; for (int nr = 0; nr < frames->frames && (maxframes == 0 || frame_nr < maxframes); nr++) @@ -419,8 +419,8 @@ print_frames (struct frames *frames, pid_t tid, int dwflerr, const char *what) } if (frames->frames > 0 && frame_nr == maxframes) - error (0, 0, "tid %d: shown max number of frames " - "(%d, use -n 0 for unlimited)", tid, maxframes); + error (0, 0, "tid %lld: shown max number of frames " + "(%d, use -n 0 for unlimited)", (long long)tid, maxframes); else if (dwflerr != 0) { if (frames->frames > 0) @@ -440,11 +440,11 @@ print_frames (struct frames *frames, pid_t tid, int dwflerr, const char *what) else modname = "<unknown>"; } - error (0, 0, "%s tid %d at 0x%" PRIx64 " in %s: %s", what, tid, + error (0, 0, "%s tid %lld at 0x%" PRIx64 " in %s: %s", what, (long long)tid, pc_adjusted, modname, dwfl_errmsg (dwflerr)); } else - error (0, 0, "%s tid %d: %s", what, tid, dwfl_errmsg (dwflerr)); + error (0, 0, "%s tid %lld: %s", what, (long long)tid, dwfl_errmsg (dwflerr)); } } @@ -483,7 +483,7 @@ parse_opt (int key, char *arg __attribute__ ((unused)), break; case OPT_COREFILE: - core_fd = open (arg, O_RDONLY); + core_fd = open (arg, O_RDONLY | O_BINARY); if (core_fd < 0) error (EXIT_BAD, errno, N_("Cannot open core file '%s'"), arg); elf_version (EV_CURRENT); @@ -575,10 +575,10 @@ parse_opt (int key, char *arg __attribute__ ((unused)), int err = dwfl_linux_proc_report (dwfl, pid); if (err < 0) - error (EXIT_BAD, 0, "dwfl_linux_proc_report pid %d: %s", pid, + error (EXIT_BAD, 0, "dwfl_linux_proc_report pid %lld: %s", (long long)pid, dwfl_errmsg (-1)); else if (err > 0) - error (EXIT_BAD, err, "dwfl_linux_proc_report pid %d", pid); + error (EXIT_BAD, err, "dwfl_linux_proc_report pid %lld", (long long)pid); } if (core != NULL) @@ -597,10 +597,10 @@ parse_opt (int key, char *arg __attribute__ ((unused)), { int err = dwfl_linux_proc_attach (dwfl, pid, false); if (err < 0) - error (EXIT_BAD, 0, "dwfl_linux_proc_attach pid %d: %s", pid, + error (EXIT_BAD, 0, "dwfl_linux_proc_attach pid %lld: %s", (long long)pid, dwfl_errmsg (-1)); else if (err > 0) - error (EXIT_BAD, err, "dwfl_linux_proc_attach pid %d", pid); + error (EXIT_BAD, err, "dwfl_linux_proc_attach pid %lld", (long long)pid); } if (core != NULL) @@ -688,7 +688,7 @@ invoked with bad or missing arguments it will exit with return code 64.") if (show_modules) { - printf ("PID %d - %s module memory map\n", dwfl_pid (dwfl), + printf ("PID %lld - %s module memory map\n", (long long)dwfl_pid (dwfl), pid != 0 ? "process" : "core"); if (dwfl_getmodules (dwfl, module_callback, NULL, 0) != 0) error (EXIT_BAD, 0, "dwfl_getmodules: %s", dwfl_errmsg (-1)); @@ -721,7 +721,7 @@ invoked with bad or missing arguments it will exit with return code 64.") } else { - printf ("PID %d - %s\n", dwfl_pid (dwfl), pid != 0 ? "process" : "core"); + printf ("PID %lld - %s\n", (long long)dwfl_pid (dwfl), pid != 0 ? "process" : "core"); switch (dwfl_getthreads (dwfl, thread_callback, &frames)) { case DWARF_CB_OK: diff --git a/src/strings.c b/src/strings.c index d214356c..8e2d098c 100644 --- a/src/strings.c +++ b/src/strings.c @@ -180,7 +180,7 @@ main (int argc, char *argv[]) do { int fd = (strcmp (argv[remaining], "-") == 0 - ? STDIN_FILENO : open (argv[remaining], O_RDONLY)); + ? STDIN_FILENO : open (argv[remaining], O_RDONLY | O_BINARY)); if (unlikely (fd == -1)) { error (0, errno, gettext ("cannot open '%s'"), argv[remaining]); @@ -450,6 +450,9 @@ process_chunk (const char *fname, const unsigned char *buf, off_t to, *unprinted = xstrndup ((const char *) start, curlen); } +#ifndef roundup +#define roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y)) +#endif /* Map a file in as large chunks as possible. */ static void * @@ -571,9 +574,11 @@ read_block (int fd, const char *fname, off_t fdlen, off_t from, off_t to) elfmap_off = from & ~(ps - 1); elfmap_base = elfmap = map_file (fd, elfmap_off, fdlen, &elfmap_size); +#if HAVE_DECL_POSIX_FADVISE if (unlikely (elfmap == MAP_FAILED)) /* Let the kernel know we are going to read everything in sequence. */ (void) posix_fadvise (fd, 0, 0, POSIX_FADV_SEQUENTIAL); +#endif } if (unlikely (elfmap == MAP_FAILED)) diff --git a/src/strip.c b/src/strip.c index f7474418..c114a170 100644 --- a/src/strip.c +++ b/src/strip.c @@ -110,11 +110,11 @@ static int process_file (const char *fname); /* Handle one ELF file. */ static int handle_elf (int fd, Elf *elf, const char *prefix, - const char *fname, mode_t mode, struct timespec tvp[2]); + const char *fname, mode_t mode); /* Handle all files contained in the archive. */ -static int handle_ar (int fd, Elf *elf, const char *prefix, const char *fname, - struct timespec tvp[2]) __attribute__ ((unused)); +static int handle_ar (int fd, Elf *elf, const char *prefix, const char *fname) + __attribute__ ((unused)); static int debug_fd = -1; static char *tmp_debug_fname = NULL; @@ -298,7 +298,6 @@ process_file (const char *fname) now. We cannot use fstat() after opening the file since the open would change the access time. */ struct stat pre_st; - struct timespec tv[2]; again: if (preserve_dates) { @@ -307,15 +306,10 @@ process_file (const char *fname) error (0, errno, gettext ("cannot stat input file '%s'"), fname); return 1; } - - /* If we have to preserve the timestamp, we need it in the - format utimes() understands. */ - tv[0] = pre_st.st_atim; - tv[1] = pre_st.st_mtim; } /* Open the file. */ - int fd = open (fname, output_fname == NULL ? O_RDWR : O_RDONLY); + int fd = open (fname, output_fname == NULL ? (O_RDWR | O_BINARY) : (O_RDONLY | O_BINARY)); if (fd == -1) { error (0, errno, gettext ("while opening '%s'"), fname); @@ -347,8 +341,7 @@ process_file (const char *fname) switch (elf_kind (elf)) { case ELF_K_ELF: - result = handle_elf (fd, elf, NULL, fname, st.st_mode & ACCESSPERMS, - preserve_dates ? tv : NULL); + result = handle_elf (fd, elf, NULL, fname, st.st_mode & 0777); break; case ELF_K_AR: @@ -365,8 +358,7 @@ process_file (const char *fname) /* We would like to support ar archives, but currently it just doesn't work at all since we call elf_clone on the members which doesn't really support ar members. - result = handle_ar (fd, elf, NULL, fname, - preserve_dates ? tv : NULL); + result = handle_ar (fd, elf, NULL, fname); */ error (0, 0, gettext ("%s: no support for stripping archive"), fname); @@ -394,7 +386,7 @@ process_file (const char *fname) static int handle_elf (int fd, Elf *elf, const char *prefix, const char *fname, - mode_t mode, struct timespec tvp[2]) + mode_t mode) { size_t prefix_len = prefix == NULL ? 0 : strlen (prefix); size_t fname_len = strlen (fname) + 1; @@ -440,14 +432,14 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname, if (prefix != NULL) { cp = mempcpy (cp, prefix, prefix_len); - *cp++ = ':'; + *cp++ = PATHSEP; } memcpy (cp, fname, fname_len); /* If we are not replacing the input file open a new file here. */ if (output_fname != NULL) { - fd = open (output_fname, O_RDWR | O_CREAT, mode); + fd = open (output_fname, O_RDWR | O_BINARY | O_CREAT, mode); if (unlikely (fd == -1)) { error (0, errno, gettext ("cannot open '%s'"), output_fname); @@ -2006,8 +1998,14 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname, /* Create the real output file. First rename, then change the mode. */ - if (rename (tmp_debug_fname, debug_fname) != 0 - || fchmod (debug_fd, mode) != 0) + close (debug_fd); + int rename_result = rename (tmp_debug_fname, debug_fname); + debug_fd = open (debug_fname, O_RDONLY | O_BINARY); + if (rename_result != 0 || debug_fd == -1 +#if HAVE_DECL_FCHMOD + || fchmod (debug_fd, mode) != 0 +#endif + ) { error (0, errno, gettext ("while creating '%s'"), debug_fname); result = 1; @@ -2212,18 +2210,6 @@ while computing checksum for debug information")); cleanup_debug (); - /* If requested, preserve the timestamp. */ - if (tvp != NULL) - { - if (futimens (fd, tvp) != 0) - { - error (0, errno, gettext ("\ -cannot set access and modification date of '%s'"), - output_fname ?: fname); - result = 1; - } - } - /* Close the file descriptor if we created a new file. */ if (output_fname != NULL) close (fd); @@ -2248,8 +2234,7 @@ cleanup_debug (void) } static int -handle_ar (int fd, Elf *elf, const char *prefix, const char *fname, - struct timespec tvp[2]) +handle_ar (int fd, Elf *elf, const char *prefix, const char *fname) { size_t prefix_len = prefix == NULL ? 0 : strlen (prefix); size_t fname_len = strlen (fname) + 1; @@ -2260,7 +2245,7 @@ handle_ar (int fd, Elf *elf, const char *prefix, const char *fname, if (prefix != NULL) { cp = mempcpy (cp, prefix, prefix_len); - *cp++ = ':'; + *cp++ = PATHSEP; } memcpy (cp, fname, fname_len); @@ -2275,9 +2260,9 @@ handle_ar (int fd, Elf *elf, const char *prefix, const char *fname, Elf_Arhdr *arhdr = elf_getarhdr (subelf); if (elf_kind (subelf) == ELF_K_ELF) - result |= handle_elf (fd, subelf, new_prefix, arhdr->ar_name, 0, NULL); + result |= handle_elf (fd, subelf, new_prefix, arhdr->ar_name, 0); else if (elf_kind (subelf) == ELF_K_AR) - result |= handle_ar (fd, subelf, new_prefix, arhdr->ar_name, NULL); + result |= handle_ar (fd, subelf, new_prefix, arhdr->ar_name); /* Get next archive element. */ cmd = elf_next (subelf); @@ -2285,15 +2270,6 @@ handle_ar (int fd, Elf *elf, const char *prefix, const char *fname, INTERNAL_ERROR (fname); } - if (tvp != NULL) - { - if (unlikely (futimens (fd, tvp) != 0)) - { - error (0, errno, gettext ("\ -cannot set access and modification date of '%s'"), fname); - result = 1; - } - } if (unlikely (close (fd) != 0)) error (EXIT_FAILURE, errno, gettext ("while closing '%s'"), fname); diff --git a/src/unstrip.c b/src/unstrip.c index 50749093..6b4598c8 100644 --- a/src/unstrip.c +++ b/src/unstrip.c @@ -291,12 +291,13 @@ make_directories (const char *path) if (lastslash == path) return; - char *dir = strndupa (path, lastslash - path); + char *dir = strndup (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); + free (dir); } /* Keep track of new section data we are creating, so we can free it @@ -2017,7 +2018,7 @@ DWARF data in '%s' not adjusted for prelinking bias; consider prelink -u"), make_directories (output_file); /* Copy the unstripped file and then modify it. */ - int outfd = open (output_file, O_RDWR | O_CREAT, + int outfd = open (output_file, O_RDWR | O_BINARY | O_CREAT, stripped_ehdr->e_type == ET_REL ? 0666 : 0777); if (outfd < 0) error (EXIT_FAILURE, errno, _("cannot open '%s'"), output_file); @@ -2047,7 +2048,7 @@ DWARF data in '%s' not adjusted for prelinking bias; consider prelink -u"), static int open_file (const char *file, bool writable) { - int fd = open (file, writable ? O_RDWR : O_RDONLY); + int fd = open (file, writable ? (O_RDWR | O_BINARY) : (O_RDONLY | O_BINARY)); if (fd < 0) error (EXIT_FAILURE, errno, _("cannot open '%s'"), file); return fd; |
