summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog72
-rw-r--r--src/Makefile.am42
-rw-r--r--src/addr2line.c4
-rw-r--r--src/ar.c181
-rw-r--r--src/elfcmp.c2
-rw-r--r--src/elfcompress.c15
-rw-r--r--src/elflint.c2
-rw-r--r--src/findtextrel.c4
-rw-r--r--src/nm.c2
-rw-r--r--src/objdump.c2
-rw-r--r--src/ranlib.c48
-rw-r--r--src/readelf.c7
-rw-r--r--src/size.c6
-rw-r--r--src/stack.c24
-rw-r--r--src/strings.c7
-rw-r--r--src/strip.c66
-rw-r--r--src/unstrip.c7
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));
diff --git a/src/ar.c b/src/ar.c
index ec32cee5..6ad12ca8 100644
--- a/src/ar.c
+++ b/src/ar.c
@@ -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);
diff --git a/src/nm.c b/src/nm.c
index 969c6d35..6ab22b25 100644
--- a/src/nm.c
+++ b/src/nm.c
@@ -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
diff --git a/src/size.c b/src/size.c
index ad8dbcbb..9e5c20a1 100644
--- a/src/size.c
+++ b/src/size.c
@@ -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;