This is the mail archive of the glibc-cvs@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

GNU C Library master sources branch, master, updated. glibc-2.15-714-gf5a01ca


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU C Library master sources".

The branch, master has been updated
       via  f5a01ca927f9141606276b05ad87974593a608a1 (commit)
       via  90fe4186b377c7bda6788ddd8607c9f30a027355 (commit)
       via  82397ed6eab79f3f17f66efae5ccfa19fa0e03d0 (commit)
       via  82a79e7d1843f9d90075a0bf2f04557040829bb0 (commit)
      from  615605c94eb3238fa1a0721506d70871f1610967 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://sources.redhat.com/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=f5a01ca927f9141606276b05ad87974593a608a1

commit f5a01ca927f9141606276b05ad87974593a608a1
Author: Roland McGrath <roland@hack.frob.com>
Date:   Tue May 1 13:30:55 2012 -0700

    Redirect check-localplt output to check-localplt.out.

diff --git a/ChangeLog b/ChangeLog
index 924920f..66deec2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,8 @@
 2012-05-01  Roland McGrath  <roland@hack.frob.com>
 
+	* elf/Makefile ($(objpfx)check-localplt.out): Redirect the test's
+	output to the target.
+
 	* scripts/localplt.awk: New file.
 	* elf/Makefile ($(objpfx)check-localplt): Target removed.
 	(check-localplt-CFLAGS): Variable removed.
diff --git a/elf/Makefile b/elf/Makefile
index 0b5359f..57dcab0 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -958,7 +958,8 @@ $(objpfx)check-localplt.out: $(..)scripts/check-localplt.awk \
 			     $(localplt-built-dso:=.jmprel) \
 			     $(check-data)
 	LC_ALL=C $(AWK) -f $(filter-out $< $(check-data),$^) | \
-	  LC_ALL=C $(AWK) -f $< $(check-data) -
+	  LC_ALL=C $(AWK) -f $< $(check-data) - \
+	  > $@
 endif
 
 $(objpfx)tst-dlopenrpathmod.so: $(libdl)

http://sources.redhat.com/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=90fe4186b377c7bda6788ddd8607c9f30a027355

commit 90fe4186b377c7bda6788ddd8607c9f30a027355
Author: Roland McGrath <roland@hack.frob.com>
Date:   Tue May 1 09:26:23 2012 -0700

    Do check-localplt test using readelf rather than a build-time C program.

diff --git a/ChangeLog b/ChangeLog
index 91d6cbb..924920f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,15 @@
 2012-05-01  Roland McGrath  <roland@hack.frob.com>
 
+	* scripts/localplt.awk: New file.
+	* elf/Makefile ($(objpfx)check-localplt): Target removed.
+	(check-localplt-CFLAGS): Variable removed.
+	($(all-built-dso:=.jmprel)): New static pattern rule.
+	(generated): Add those targets.
+	(localplt-built-dso): New variable.
+	($(objpfx)check-localplt.out): Use the script on the .jmprel files.
+
+	* elf/check-localplt.c: File removed.
+
 	* scripts/check-execstack.awk: New file.
 	* elf/Makefile ($(objpfx)check-execstack): Target removed.
 	(check-execstack-CFLAGS): Variable removed.
diff --git a/elf/Makefile b/elf/Makefile
index c207b53..0b5359f 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -872,10 +872,6 @@ CFLAGS-tst-pie1.c += $(pie-ccflag)
 
 $(objpfx)tst-pie1: $(objpfx)tst-piemod1.so
 
-check-localplt-CFLAGS = -O -Wall -D_GNU_SOURCE -std=gnu99
-$(objpfx)check-localplt: check-localplt.c
-	$(native-compile)
-
 ifeq (yes,$(build-shared))
 tests: $(objpfx)check-textrel.out $(objpfx)check-execstack.out
 
@@ -927,6 +923,13 @@ generated += check-execstack.out
 $(objpfx)tst-dlmodcount: $(libdl)
 $(objpfx)tst-dlmodcount.out: $(test-modules)
 
+$(all-built-dso:=.jmprel): %.jmprel: % Makefile
+	@rm -f $@T
+	LC_ALL=C $(READELF) -W -S -d -r $< > $@T
+	test -s $@T
+	mv -f $@T $@
+generated += $(all-built-dso:=.jmprel)
+
 check-data := $(firstword $(wildcard \
 		$(foreach D,$(add-ons) scripts,\
 			  $(patsubst %,$(..)$D/data/localplt-%.data,\
@@ -938,20 +941,24 @@ check-data := $(firstword $(wildcard \
 
 tests: $(objpfx)check-localplt.out
 
+localplt-built-dso := $(addprefix $(common-objpfx),\
+				  libc.so \
+				  math/libm.so \
+				  rt/librt.so \
+				  dlfcn/libdl.so \
+				  resolv/libresolv.so \
+				  crypt/libcrypt.so \
+		       )
 ifeq ($(have-thread-library),yes)
-thread-dso := $(filter-out %_nonshared.a, $(shared-thread-library))
+localplt-built-dso += $(filter-out %_nonshared.a, $(shared-thread-library))
 endif
 
-$(objpfx)check-localplt.out: $(objpfx)check-localplt \
-			     $(common-objpfx)libc.so \
-			     $(common-objpfx)math/libm.so $(thread-dso) \
-			     $(common-objpfx)rt/librt.so \
-			     $(common-objpfx)dlfcn/libdl.so \
-			     $(common-objpfx)resolv/libresolv.so \
-			     $(common-objpfx)crypt/libcrypt.so \
+$(objpfx)check-localplt.out: $(..)scripts/check-localplt.awk \
+			     $(..)scripts/localplt.awk \
+			     $(localplt-built-dso:=.jmprel) \
 			     $(check-data)
-	$(dir $<)$(notdir $<) $(filter-out $< $(check-data),$^) | \
-	  $(AWK) -f $(..)scripts/check-localplt.awk $(check-data) -
+	LC_ALL=C $(AWK) -f $(filter-out $< $(check-data),$^) | \
+	  LC_ALL=C $(AWK) -f $< $(check-data) -
 endif
 
 $(objpfx)tst-dlopenrpathmod.so: $(libdl)
diff --git a/elf/check-localplt.c b/elf/check-localplt.c
deleted file mode 100644
index edab1d2..0000000
--- a/elf/check-localplt.c
+++ /dev/null
@@ -1,298 +0,0 @@
-/* Show local PLT use in DSOs.
-   Copyright (C) 2006 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contribute by Ulrich Drepper <drepper@redhat.com>. 2006.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library 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
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <byteswap.h>
-#include <elf.h>
-#include <endian.h>
-#include <fcntl.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-
-#ifdef BITS
-
-# define AB(name) _AB (name, BITS)
-# define _AB(name, bits) __AB (name, bits)
-# define __AB(name, bits) name##bits
-# define E(name) _E (name, BITS)
-# define _E(name, bits) __E (name, bits)
-# define __E(name, bits) Elf##bits##_##name
-# define EE(name) _EE (name, BITS)
-# define _EE(name, bits) __EE (name, bits)
-# define __EE(name, bits) ELF##bits##_##name
-# define SWAP(val) \
-  ({ __typeof (val) __res;						      \
-     if (((ehdr.e_ident[EI_DATA] == ELFDATA2MSB				      \
-	   && BYTE_ORDER == LITTLE_ENDIAN)				      \
-	  || (ehdr.e_ident[EI_DATA] == ELFDATA2LSB			      \
-	      && BYTE_ORDER == BIG_ENDIAN))				      \
-	 && sizeof (val) != 1)						      \
-       {								      \
-	 if (sizeof (val) == 2)						      \
-	   __res = bswap_16 (val);					      \
-	 else if (sizeof (val) == 4)					      \
-	   __res = bswap_32 (val);					      \
-	 else								      \
-	   __res = bswap_64 (val);					      \
-       }								      \
-     else								      \
-       __res = (val);							      \
-     __res; })
-
-
-static int
-AB(handle_file) (const char *fname, int fd)
-{
-  E(Ehdr) ehdr;
-
-  if (pread (fd, &ehdr, sizeof (ehdr), 0) != sizeof (ehdr))
-    {
-    read_error:
-      printf ("%s: read error: %m\n", fname);
-      return 1;
-    }
-
-  const size_t phnum = SWAP (ehdr.e_phnum);
-  const size_t phentsize = SWAP (ehdr.e_phentsize);
-
-  /* Read the program header.  */
-  E(Phdr) *phdr = alloca (phentsize * phnum);
-  if (pread (fd, phdr, phentsize * phnum, SWAP (ehdr.e_phoff))
-      != phentsize * phnum)
-    goto read_error;
-
-  /* Search for the PT_DYNAMIC entry.  */
-  size_t cnt;
-  E(Phdr) *dynphdr = NULL;
-  for (cnt = 0; cnt < phnum; ++cnt)
-    if (SWAP (phdr[cnt].p_type) == PT_DYNAMIC)
-      {
-	dynphdr = &phdr[cnt];
-	break;
-      }
-
-  if (dynphdr == NULL)
-    {
-      printf ("%s: no DYNAMIC segment found\n", fname);
-      return 1;
-    }
-
-  /* Read the dynamic segment.  */
-  size_t pmemsz = SWAP(dynphdr->p_memsz);
-  E(Dyn) *dyn = alloca (pmemsz);
-  if (pread64 (fd, dyn, pmemsz, SWAP(dynphdr->p_offset)) != pmemsz)
-    goto read_error;
-
-  /* Search for an DT_PLTREL, DT_JMPREL, DT_PLTRELSZ, DT_STRTAB,
-     DT_STRSZ, and DT_SYMTAB entries.  */
-  size_t pltrel_idx = SIZE_MAX;
-  size_t jmprel_idx = SIZE_MAX;
-  size_t pltrelsz_idx = SIZE_MAX;
-  size_t strtab_idx = SIZE_MAX;
-  size_t strsz_idx = SIZE_MAX;
-  size_t symtab_idx = SIZE_MAX;
-  for (cnt = 0; (cnt + 1) * sizeof (E(Dyn)) - 1 < pmemsz; ++cnt)
-    {
-      unsigned int tag = SWAP (dyn[cnt].d_tag);
-
-      if (tag == DT_NULL)
-	/* We reached the end.  */
-	break;
-
-      if (tag == DT_PLTREL)
-	pltrel_idx = cnt;
-      else if (tag == DT_JMPREL)
-	jmprel_idx = cnt;
-      else if (tag == DT_PLTRELSZ)
-	pltrelsz_idx = cnt;
-      else if (tag == DT_STRTAB)
-	strtab_idx = cnt;
-      else if (tag == DT_STRSZ)
-	strsz_idx = cnt;
-      else if (tag == DT_SYMTAB)
-	symtab_idx = cnt;
-    }
-
-  if (pltrel_idx == SIZE_MAX || jmprel_idx == SIZE_MAX
-      || pltrelsz_idx == SIZE_MAX || strtab_idx == SIZE_MAX
-      || strsz_idx == SIZE_MAX || symtab_idx == SIZE_MAX)
-    {
-      puts ("not all PLT information found");
-      return 1;
-    }
-
-  E(Xword) relsz = SWAP (dyn[pltrelsz_idx].d_un.d_val);
-
-  void *relmem = NULL;
-  char *strtab = NULL;
-  E(Xword) symtab_offset = 0;
-
-  /* Find the offset of DT_JMPREL and load the data.  */
-  for (cnt = 0; cnt < phnum; ++cnt)
-    if (SWAP (phdr[cnt].p_type) == PT_LOAD)
-      {
-	E(Addr) vaddr = SWAP (phdr[cnt].p_vaddr);
-	E(Xword) memsz = SWAP (phdr[cnt].p_memsz);
-
-	if (vaddr <= SWAP (dyn[jmprel_idx].d_un.d_val)
-	    && vaddr + memsz >= SWAP (dyn[jmprel_idx].d_un.d_val) + relsz)
-	  {
-	    relmem = alloca (SWAP (dyn[pltrelsz_idx].d_un.d_val));
-	    if (pread64 (fd, relmem, relsz,
-			 SWAP (phdr[cnt].p_offset)
-			 + SWAP (dyn[jmprel_idx].d_un.d_val) - vaddr)
-		!= relsz)
-	      {
-		puts ("cannot read JMPREL");
-		return 1;
-	      }
-	  }
-
-	if (vaddr <= SWAP (dyn[symtab_idx].d_un.d_val)
-	    && vaddr + memsz > SWAP (dyn[symtab_idx].d_un.d_val))
-	  symtab_offset = (SWAP (phdr[cnt].p_offset)
-			   + SWAP (dyn[symtab_idx].d_un.d_val) - vaddr);
-
-	if (vaddr <= SWAP (dyn[strtab_idx].d_un.d_val)
-	    && vaddr + memsz >= (SWAP (dyn[strtab_idx].d_un.d_val)
-				 + SWAP(dyn[strsz_idx].d_un.d_val)))
-	  {
-	    strtab = alloca (SWAP(dyn[strsz_idx].d_un.d_val));
-	    if (pread64 (fd, strtab, SWAP(dyn[strsz_idx].d_un.d_val),
-			 SWAP (phdr[cnt].p_offset)
-			 + SWAP (dyn[strtab_idx].d_un.d_val) - vaddr)
-		!= SWAP(dyn[strsz_idx].d_un.d_val))
-	      {
-		puts ("cannot read STRTAB");
-		return 1;
-	      }
-	  }
-      }
-
-  if (relmem == NULL || strtab == NULL || symtab_offset == 0)
-    {
-      puts ("couldn't load PLT data");
-      return 1;
-    }
-
-  if (SWAP (dyn[pltrel_idx].d_un.d_val) == DT_RELA)
-    for (E(Rela) *rela = relmem; (char *) rela - (char *) relmem < relsz;
-	 ++rela)
-      {
-	E(Sym) sym;
-
-	if (pread64 (fd, &sym, sizeof (sym),
-		     symtab_offset
-		     + EE(R_SYM) (SWAP (rela->r_info)) * sizeof (sym))
-	    != sizeof (sym))
-	  {
-	    puts ("cannot read symbol");
-	    return 1;
-	  }
-
-	if (sym.st_value != 0)
-	  /* This symbol is locally defined.  */
-	  printf ("%s: %s\n", basename (fname), strtab + SWAP (sym.st_name));
-      }
-  else
-    for (E(Rel) *rel = relmem; (char *) rel - (char *) relmem < relsz; ++rel)
-      {
-	E(Sym) sym;
-
-	if (pread64 (fd, &sym, sizeof (sym),
-		     symtab_offset
-		     + EE(R_SYM) (SWAP (rel->r_info)) * sizeof (sym))
-	    != sizeof (sym))
-	  {
-	    puts ("cannot read symbol");
-	    return 1;
-	  }
-
-	if (sym.st_value != 0)
-	  /* This symbol is locally defined.  */
-	  printf ("%s: %s\n", basename (fname), strtab + SWAP (sym.st_name));
-      }
-
-  return 0;
-}
-
-# undef BITS
-#else
-
-# define BITS 32
-# include "check-localplt.c"
-
-# define BITS 64
-# include "check-localplt.c"
-
-
-static int
-handle_file (const char *fname)
-{
-  int fd = open (fname, O_RDONLY);
-  if (fd == -1)
-    {
-      printf ("cannot open %s: %m\n", fname);
-      return 1;
-    }
-
-  /* Read was is supposed to be the ELF header.  Read the initial
-     bytes to determine whether this is a 32 or 64 bit file.  */
-  char ident[EI_NIDENT];
-  if (read (fd, ident, EI_NIDENT) != EI_NIDENT)
-    {
-      printf ("%s: read error: %m\n", fname);
-      close (fd);
-      return 1;
-    }
-
-  if (memcmp (&ident[EI_MAG0], ELFMAG, SELFMAG) != 0)
-    {
-      printf ("%s: not an ELF file\n", fname);
-      close (fd);
-      return 1;
-    }
-
-  int result;
-  if (ident[EI_CLASS] == ELFCLASS64)
-    result = handle_file64 (fname, fd);
-  else
-    result = handle_file32 (fname, fd);
-
-  close (fd);
-
-  return result;
-}
-
-
-int
-main (int argc, char *argv[])
-{
-  int cnt;
-  int result = 0;
-
-  for (cnt = 1; cnt < argc; ++cnt)
-    result |= handle_file (argv[cnt]);
-
-  return result;
-}
-#endif
diff --git a/scripts/localplt.awk b/scripts/localplt.awk
new file mode 100644
index 0000000..2265b02
--- /dev/null
+++ b/scripts/localplt.awk
@@ -0,0 +1,59 @@
+# This awk script expects to get command-line files that are each
+# the output of 'readelf -WSdr' on a single shared object, and named
+# .../NAME.jmprel where NAME is the unadorned file name of the shared object.
+# It writes "NAME: SYMBOL" for each PLT entry in NAME that refers to a
+# symbol defined in the same object.
+
+BEGIN { result = 0 }
+
+FILENAME != lastfile {
+  if (lastfile && jmprel_offset == 0) {
+    print FILENAME ": *** failed to find expected output (readelf -WSdr)";
+    result = 2;
+  }
+  lastfile = FILENAME;
+  jmprel_offset = 0;
+  delete section_offset_by_address;
+}
+
+/^Section Headers:/ { in_shdrs = 1; next }
+in_shdrs && !/^ +\[/ { in_shdrs = 0 }
+
+in_shdrs && /^ +\[/ { sub(/\[ +/, "[") }
+in_shdrs {
+  address = strtonum("0x" $4);
+  offset = strtonum("0x" $5);
+  section_offset_by_address[address] = offset;
+}
+
+in_shdrs { next }
+
+$1 == "Offset" && $2 == "Info" { in_relocs = 1; next }
+NF == 0 { in_relocs = 0 }
+
+in_relocs && relocs_offset == jmprel_offset && NF >= 5 {
+  symval = strtonum("0x" $4);
+  if (symval != 0)
+    print whatfile, $5
+}
+
+in_relocs { next }
+
+$1 == "Relocation" && $2 == "section" && $5 == "offset" {
+  relocs_offset = strtonum($6);
+  whatfile = gensub(/^.*\/([^/]+)\.jmprel$/, "\\1:", 1, FILENAME);
+  next
+}
+
+$2 == "(JMPREL)" {
+  jmprel_addr = strtonum($3);
+  if (jmprel_addr in section_offset_by_address) {
+    jmprel_offset = section_offset_by_address[jmprel_addr];
+  } else {
+    print FILENAME ": *** DT_JMPREL does not match any section's address";
+    result = 2;
+  }
+  next
+}
+
+END { exit(result) }

http://sources.redhat.com/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=82397ed6eab79f3f17f66efae5ccfa19fa0e03d0

commit 82397ed6eab79f3f17f66efae5ccfa19fa0e03d0
Author: Roland McGrath <roland@hack.frob.com>
Date:   Mon Apr 30 15:41:15 2012 -0700

    Do check-execstack test using readelf rather than a build-time C program.

diff --git a/ChangeLog b/ChangeLog
index e486924..91d6cbb 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,15 @@
 2012-05-01  Roland McGrath  <roland@hack.frob.com>
 
+	* scripts/check-execstack.awk: New file.
+	* elf/Makefile ($(objpfx)check-execstack): Target removed.
+	(check-execstack-CFLAGS): Variable removed.
+	($(objpfx)check-execstack.h): Target removed.
+	($(objpfx)execstack-default): New target.
+	(generated): Add that instead of check-execstack.h.
+	($(all-built-dso:=.phdr)): New static pattern rule.
+	(generated): Add those targets.
+	* elf/check-execstack.c: File removed.
+
 	* scripts/check-textrel.awk: New file.
 	* elf/Makefile ($(objpfx)check-textrel): Target removed.
 	(check-textrel-CFLAGS): Variable removed.
diff --git a/elf/Makefile b/elf/Makefile
index 50934be..c207b53 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -872,18 +872,6 @@ CFLAGS-tst-pie1.c += $(pie-ccflag)
 
 $(objpfx)tst-pie1: $(objpfx)tst-piemod1.so
 
-check-execstack-CFLAGS = -O -Wall -D_XOPEN_SOURCE=600 -D_BSD_SOURCE -std=gnu99 \
-			 $(objpfx:%/=-I%)
-$(objpfx)check-execstack: check-execstack.c $(objpfx)check-execstack.h
-	$(native-compile)
-$(objpfx)check-execstack.h: $(first-word $(wildcard $(sysdirs:%=%/stackinfo.h)))
-	$(make-target-directory)
-	{ echo '#include <stackinfo.h>'; echo '@@@DEFAULT_STACK_PERMS@@@'; } | \
-	$(CC) $(CFLAGS) $(CPPFLAGS) -E -x c-header - | \
-	sed -n -e 's/^@@@\(.*\)@@@/#define DEFAULT_STACK_PERMS \1/p' > $@T
-	mv -f $@T $@
-generated += check-execstack.h
-
 check-localplt-CFLAGS = -O -Wall -D_GNU_SOURCE -std=gnu99
 $(objpfx)check-localplt: check-localplt.c
 	$(native-compile)
@@ -909,9 +897,32 @@ $(objpfx)check-textrel.out: $(..)scripts/check-textrel.awk \
 	LC_ALL=C $(AWK) -f $^ > $@
 generated += check-textrel.out
 
-$(objpfx)check-execstack.out: $(objpfx)check-execstack $(all-built-dso)
-	$(dir $<)$(notdir $<) $(filter-out $<, $^) > $@
-generated += check-execstack check-execstack.out
+$(objpfx)execstack-default: $(first-word $(wildcard $(sysdirs:%=%/stackinfo.h)))
+	$(make-target-directory)
+	{ echo '#include <elf.h>'; \
+	  echo '#include <stackinfo.h>'; \
+	  echo '#if (DEFAULT_STACK_PERMS & PF_X) == 0'; \
+	  echo '@@@execstack-no@@@'; \
+	  echo '#else'; \
+	  echo '@@@execstack-yes@@@'; \
+	  echo '#endif'; } | \
+	$(CC) $(CFLAGS) $(CPPFLAGS) -E -x c-header - | \
+	sed -n -e 's/^@@@\(.*\)@@@/\1/p' > $@T
+	mv -f $@T $@
+generated += execstack-default
+
+$(all-built-dso:=.phdr): %.phdr: %
+	@rm -f $@T
+	LC_ALL=C $(READELF) -W -l $< > $@T
+	test -s $@T
+	mv -f $@T $@
+generated += $(all-built-dso:=.phdr)
+
+$(objpfx)check-execstack.out: $(..)scripts/check-execstack.awk \
+			      $(objpfx)execstack-default \
+			      $(all-built-dso:=.phdr)
+	LC_ALL=C $(AWK) -f $^ > $@
+generated += check-execstack.out
 
 $(objpfx)tst-dlmodcount: $(libdl)
 $(objpfx)tst-dlmodcount.out: $(test-modules)
diff --git a/elf/check-execstack.c b/elf/check-execstack.c
deleted file mode 100644
index 6a5c4d9..0000000
--- a/elf/check-execstack.c
+++ /dev/null
@@ -1,162 +0,0 @@
-/* Check for executable stacks in DSOs.
-   Copyright (C) 2009, 2010 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contribute by Ulrich Drepper <drepper@redhat.com>. 2009.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library 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
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <byteswap.h>
-#include <elf.h>
-#include <endian.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include "check-execstack.h"
-
-
-#ifdef BITS
-
-# define AB(name) _AB (name, BITS)
-# define _AB(name, bits) __AB (name, bits)
-# define __AB(name, bits) name##bits
-# define E(name) _E (name, BITS)
-# define _E(name, bits) __E (name, bits)
-# define __E(name, bits) Elf##bits##_##name
-# define SWAP(val) \
-  ({ __typeof (val) __res;						      \
-     if (((ehdr.e_ident[EI_DATA] == ELFDATA2MSB				      \
-	   && BYTE_ORDER == LITTLE_ENDIAN)				      \
-	  || (ehdr.e_ident[EI_DATA] == ELFDATA2LSB			      \
-	      && BYTE_ORDER == BIG_ENDIAN))				      \
-	 && sizeof (val) != 1)						      \
-       {								      \
-	 if (sizeof (val) == 2)						      \
-	   __res = bswap_16 (val);					      \
-	 else if (sizeof (val) == 4)					      \
-	   __res = bswap_32 (val);					      \
-	 else								      \
-	   __res = bswap_64 (val);					      \
-       }								      \
-     else								      \
-       __res = (val);							      \
-     __res; })
-
-
-static int
-AB(handle_file) (const char *fname, int fd)
-{
-  E(Ehdr) ehdr;
-
-  if (pread (fd, &ehdr, sizeof (ehdr), 0) != sizeof (ehdr))
-    {
-    read_error:
-      printf ("%s: read error: %m\n", fname);
-      return 1;
-    }
-
-  const size_t phnum = SWAP (ehdr.e_phnum);
-  const size_t phentsize = SWAP (ehdr.e_phentsize);
-
-  /* Read the program header.  */
-  E(Phdr) *phdr = alloca (phentsize * phnum);
-  if (pread (fd, phdr, phentsize * phnum, SWAP (ehdr.e_phoff))
-      != phentsize * phnum)
-    goto read_error;
-
-  /* Search for the PT_GNU_STACK entry.  */
-  for (size_t cnt = 0; cnt < phnum; ++cnt)
-    if (SWAP (phdr[cnt].p_type) == PT_GNU_STACK)
-      {
-	unsigned int flags = SWAP(phdr[cnt].p_flags);
-	if (flags & PF_X)
-	  {
-	    printf ("%s: executable stack signaled\n", fname);
-	    return 1;
-	  }
-
-	return 0;
-      }
-
-  if (DEFAULT_STACK_PERMS & PF_X)
-    {
-      printf ("%s: no PT_GNU_STACK entry\n", fname);
-      return 1;
-    }
-
-  return 0;
-}
-
-# undef BITS
-#else
-
-# define BITS 32
-# include "check-execstack.c"
-
-# define BITS 64
-# include "check-execstack.c"
-
-
-static int
-handle_file (const char *fname)
-{
-  int fd = open (fname, O_RDONLY);
-  if (fd == -1)
-    {
-      printf ("cannot open %s: %m\n", fname);
-      return 1;
-    }
-
-  /* Read was is supposed to be the ELF header.  Read the initial
-     bytes to determine whether this is a 32 or 64 bit file.  */
-  char ident[EI_NIDENT];
-  if (read (fd, ident, EI_NIDENT) != EI_NIDENT)
-    {
-      printf ("%s: read error: %m\n", fname);
-      close (fd);
-      return 1;
-    }
-
-  if (memcmp (&ident[EI_MAG0], ELFMAG, SELFMAG) != 0)
-    {
-      printf ("%s: not an ELF file\n", fname);
-      close (fd);
-      return 1;
-    }
-
-  int result;
-  if (ident[EI_CLASS] == ELFCLASS64)
-    result = handle_file64 (fname, fd);
-  else
-    result = handle_file32 (fname, fd);
-
-  close (fd);
-
-  return result;
-}
-
-
-int
-main (int argc, char *argv[])
-{
-  int cnt;
-  int result = 0;
-
-  for (cnt = 1; cnt < argc; ++cnt)
-    result |= handle_file (argv[cnt]);
-  return result;
-}
-#endif
diff --git a/scripts/check-execstack.awk b/scripts/check-execstack.awk
new file mode 100644
index 0000000..21d37e9
--- /dev/null
+++ b/scripts/check-execstack.awk
@@ -0,0 +1,52 @@
+# This awk script expects to get command-line files that are each
+# the output of 'readelf -l' on a single shared object.
+# But the first file should contain just "execstack-no" or "execstack-yes",
+# indicating what the default is in the absence of PT_GNU_STACK.
+# It exits successfully (0) if none indicated executable stack.
+# It fails (1) if any did indicate executable stack.
+# It fails (2) if the input did not take the expected form.
+
+BEGIN { result = sanity = 0; default_exec = -1 }
+
+/^execstack-no$/ { default_exec = 0; next }
+/^execstack-yes$/ { default_exec = 1; next }
+
+function check_one(name) {
+  if (default_exec == -1) {
+    print "*** missing execstack-default file?";
+    result = 2;
+  }
+
+  if (!sanity) {
+    print name ": *** input did not look like readelf -l output";
+    result = 2;
+  } else if (stack_line) {
+    if (stack_line ~ /^.*RW .*$/) {
+      print name ": OK";
+    } else if (stack_line ~ /^.*E.*$/) {
+      print name ": *** executable stack signaled";
+      result = result ? result : 1;
+    }
+  } else if (default_exec) {
+    print name ": *** no PT_GNU_STACK entry";
+    result = result ? result : 1;
+  } else {
+    print name ": no PT_GNU_STACK but default is OK";
+  }
+
+  sanity = 0;
+}
+
+FILENAME != lastfile {
+  if (lastfile)
+    check_one(lastfile);
+  lastfile = FILENAME;
+}
+
+$1 == "Type" && $7 == "Flg" { sanity = 1; stack_line = "" }
+$1 == "GNU_STACK" { stack_line = $0 }
+
+END {
+  check_one(lastfile);
+  exit(result);
+}

http://sources.redhat.com/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=82a79e7d1843f9d90075a0bf2f04557040829bb0

commit 82a79e7d1843f9d90075a0bf2f04557040829bb0
Author: Roland McGrath <roland@hack.frob.com>
Date:   Mon Apr 30 15:00:14 2012 -0700

    Do check-textrel test using readelf rather than a build-time C program.

diff --git a/ChangeLog b/ChangeLog
index fcd2bca..e486924 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2012-05-01  Roland McGrath  <roland@hack.frob.com>
+
+	* scripts/check-textrel.awk: New file.
+	* elf/Makefile ($(objpfx)check-textrel): Target removed.
+	(check-textrel-CFLAGS): Variable removed.
+	(all-built-dso): Use := to define.o
+	($(all-built-dso:=.dyn)): New static pattern rule.
+	(generated): Add those targets.
+	($(objpfx)check-textrel.out): Use the script on the .dyn files.
+	* config.make.in (READELF): New substituted variable.
+	* elf/check-textrel.c: File removed.
+
 2012-05-01  Joseph Myers  <joseph@codesourcery.com>
 
 	* conform/data/assert.h-data [ISO || ISO99 || ISO11] (*_t): Do not
diff --git a/config.make.in b/config.make.in
index 1f4185b..5f6f9e2 100644
--- a/config.make.in
+++ b/config.make.in
@@ -112,6 +112,7 @@ BISON = @BISON@
 AUTOCONF = @AUTOCONF@
 OBJDUMP = @OBJDUMP@
 OBJCOPY = @OBJCOPY@
+READELF = @READELF@
 
 # Installation tools.
 INSTALL = @INSTALL@
diff --git a/elf/Makefile b/elf/Makefile
index 32d113e..50934be 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -872,10 +872,6 @@ CFLAGS-tst-pie1.c += $(pie-ccflag)
 
 $(objpfx)tst-pie1: $(objpfx)tst-piemod1.so
 
-check-textrel-CFLAGS = -O -Wall -D_XOPEN_SOURCE=600 -D_BSD_SOURCE
-$(objpfx)check-textrel: check-textrel.c
-	$(native-compile)
-
 check-execstack-CFLAGS = -O -Wall -D_XOPEN_SOURCE=600 -D_BSD_SOURCE -std=gnu99 \
 			 $(objpfx:%/=-I%)
 $(objpfx)check-execstack: check-execstack.c $(objpfx)check-execstack.h
@@ -895,14 +891,23 @@ $(objpfx)check-localplt: check-localplt.c
 ifeq (yes,$(build-shared))
 tests: $(objpfx)check-textrel.out $(objpfx)check-execstack.out
 
-all-built-dso = $(common-objpfx)libc.so \
-		$(filter-out $(common-objpfx)linkobj/libc.so, \
-			     $(sort $(wildcard $(common-objpfx)*/lib*.so \
-					       $(common-objpfx)iconvdata/*.so)))
+all-built-dso := $(common-objpfx)libc.so \
+		 $(filter-out $(common-objpfx)linkobj/libc.so, \
+			      $(sort $(wildcard $(addprefix $(common-objpfx), \
+							    */lib*.so \
+							    iconvdata/*.so))))
 
-$(objpfx)check-textrel.out: $(objpfx)check-textrel $(all-built-dso)
-	$(dir $<)$(notdir $<) $(filter-out $<, $^) > $@
-generated += check-textrel check-textrel.out
+$(all-built-dso:=.dyn): %.dyn: %
+	@rm -f $@T
+	LC_ALL=C $(READELF) -W -d $< > $@T
+	test -s $@T
+	mv -f $@T $@
+generated += $(all-built-dso:=.dyn)
+
+$(objpfx)check-textrel.out: $(..)scripts/check-textrel.awk \
+			    $(all-built-dso:=.dyn)
+	LC_ALL=C $(AWK) -f $^ > $@
+generated += check-textrel.out
 
 $(objpfx)check-execstack.out: $(objpfx)check-execstack $(all-built-dso)
 	$(dir $<)$(notdir $<) $(filter-out $<, $^) > $@
diff --git a/elf/check-textrel.c b/elf/check-textrel.c
deleted file mode 100644
index 6372019..0000000
--- a/elf/check-textrel.c
+++ /dev/null
@@ -1,198 +0,0 @@
-/* Check for text relocations in DSOs.
-   Copyright (C) 2002, 2003, 2006 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contribute by Ulrich Drepper <drepper@redhat.com>. 2002.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library 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
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <byteswap.h>
-#include <elf.h>
-#include <endian.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-
-#ifdef BITS
-
-# define AB(name) _AB (name, BITS)
-# define _AB(name, bits) __AB (name, bits)
-# define __AB(name, bits) name##bits
-# define E(name) _E (name, BITS)
-# define _E(name, bits) __E (name, bits)
-# define __E(name, bits) Elf##bits##_##name
-# define SWAP(val) \
-  ({ __typeof (val) __res;						      \
-     if (((ehdr.e_ident[EI_DATA] == ELFDATA2MSB				      \
-	   && BYTE_ORDER == LITTLE_ENDIAN)				      \
-	  || (ehdr.e_ident[EI_DATA] == ELFDATA2LSB			      \
-	      && BYTE_ORDER == BIG_ENDIAN))				      \
-	 && sizeof (val) != 1)						      \
-       {								      \
-	 if (sizeof (val) == 2)						      \
-	   __res = bswap_16 (val);					      \
-	 else if (sizeof (val) == 4)					      \
-	   __res = bswap_32 (val);					      \
-	 else								      \
-	   __res = bswap_64 (val);					      \
-       }								      \
-     else								      \
-       __res = (val);							      \
-     __res; })
-
-
-static int
-AB(handle_file) (const char *fname, int fd)
-{
-  E(Ehdr) ehdr;
-
-  if (pread (fd, &ehdr, sizeof (ehdr), 0) != sizeof (ehdr))
-    {
-    read_error:
-      printf ("%s: read error: %m\n", fname);
-      return 1;
-    }
-
-  const size_t phnum = SWAP (ehdr.e_phnum);
-  const size_t phentsize = SWAP (ehdr.e_phentsize);
-
-  /* Read the program header.  */
-  E(Phdr) *phdr = alloca (phentsize * phnum);
-  if (pread (fd, phdr, phentsize * phnum, SWAP (ehdr.e_phoff))
-      != phentsize * phnum)
-    goto read_error;
-
-  /* Search for the PT_DYNAMIC entry.  */
-  size_t cnt;
-  E(Phdr) *dynphdr = NULL;
-  for (cnt = 0; cnt < phnum; ++cnt)
-    if (SWAP (phdr[cnt].p_type) == PT_DYNAMIC)
-      dynphdr = &phdr[cnt];
-    else if (SWAP (phdr[cnt].p_type) == PT_LOAD
-	     && (SWAP (phdr[cnt].p_flags) & (PF_X | PF_W)) == (PF_X | PF_W))
-      {
-	printf ("%s: segment %zu is executable and writable\n",
-		fname, cnt);
-#if !defined __sparc__ \
-    && !defined __alpha__ \
-    && (!defined __powerpc__ || defined __powerpc64__ || defined HAVE_PPC_SECURE_PLT)
-	/* sparc, sparc64, alpha and powerpc32 (the last one only when using
-	   -mbss-plt) are expected to have PF_X | PF_W segment containing .plt
-	   section, it is part of their ABI.  It is bad security wise, nevertheless
-	   this test shouldn't fail because of this.  */
-	return 1;
-#endif
-      }
-
-  if (dynphdr == NULL)
-    {
-      printf ("%s: no DYNAMIC segment found\n", fname);
-      return 1;
-    }
-
-  /* Read the dynamic segment.  */
-  size_t pmemsz = SWAP(dynphdr->p_memsz);
-  E(Dyn) *dyn = alloca (pmemsz);
-  if (pread (fd, dyn, pmemsz, SWAP(dynphdr->p_offset)) != pmemsz)
-    goto read_error;
-
-  /* Search for an DT_TEXTREL entry of DT_FLAGS with the DF_TEXTREL
-     bit set.  */
-  for (cnt = 0; (cnt + 1) * sizeof (E(Dyn)) - 1 < pmemsz; ++cnt)
-    {
-      unsigned int tag = SWAP (dyn[cnt].d_tag);
-
-      if (tag == DT_NULL)
-	/* We reached the end.  */
-	break;
-
-      if (tag == DT_TEXTREL
-	  || (tag == DT_FLAGS
-	      && (SWAP (dyn[cnt].d_un.d_val) & DF_TEXTREL) != 0))
-	{
-	  /* Urgh!  The DSO has text relocations.  */
-	  printf ("%s: text relocations used\n", fname);
-	  return 1;
-	}
-    }
-
-  printf ("%s: OK\n", fname);
-
-  return 0;
-}
-
-# undef BITS
-#else
-
-# define BITS 32
-# include "check-textrel.c"
-
-# define BITS 64
-# include "check-textrel.c"
-
-
-static int
-handle_file (const char *fname)
-{
-  int fd = open (fname, O_RDONLY);
-  if (fd == -1)
-    {
-      printf ("cannot open %s: %m\n", fname);
-      return 1;
-    }
-
-  /* Read was is supposed to be the ELF header.  Read the initial
-     bytes to determine whether this is a 32 or 64 bit file.  */
-  char ident[EI_NIDENT];
-  if (read (fd, ident, EI_NIDENT) != EI_NIDENT)
-    {
-      printf ("%s: read error: %m\n", fname);
-      close (fd);
-      return 1;
-    }
-
-  if (memcmp (&ident[EI_MAG0], ELFMAG, SELFMAG) != 0)
-    {
-      printf ("%s: not an ELF file\n", fname);
-      close (fd);
-      return 1;
-    }
-
-  int result;
-  if (ident[EI_CLASS] == ELFCLASS64)
-    result = handle_file64 (fname, fd);
-  else
-    result = handle_file32 (fname, fd);
-
-  close (fd);
-
-  return result;
-}
-
-
-int
-main (int argc, char *argv[])
-{
-  int cnt;
-  int result = 0;
-
-  for (cnt = 1; cnt < argc; ++cnt)
-    result |= handle_file (argv[cnt]);
-
-  return result;
-}
-#endif
diff --git a/scripts/check-textrel.awk b/scripts/check-textrel.awk
new file mode 100644
index 0000000..e7f2d70
--- /dev/null
+++ b/scripts/check-textrel.awk
@@ -0,0 +1,41 @@
+# This awk script expects to get command-line files that are each
+# the output of 'readelf -d' on a single shared object.
+# It exits successfully (0) if none contained any TEXTREL markers.
+# It fails (1) if any did contain a TEXTREL marker.
+# It fails (2) if the input did not take the expected form.
+
+BEGIN { result = textrel = sanity = 0 }
+
+function check_one(name) {
+  if (!sanity) {
+    print name ": *** input did not look like readelf -d output";
+    result = 2;
+  } else if (textrel) {
+    print name ": *** text relocations used";
+    result = result ? result : 1;
+  } else {
+    print name ": OK";
+  }
+
+  textrel = sanity = 0;
+}
+
+FILENAME != lastfile {
+  if (lastfile)
+    check_one(lastfile);
+  lastfile = FILENAME;
+}
+
+$1 == "Tag" && $2 == "Type" { sanity = 1 }
+$2 == "(TEXTREL)" { textrel = 1 }
+$2 == "(FLAGS)" {
+  for (i = 3; i <= NF; ++i) {
+    if ($i == "TEXTREL")
+      textrel = 1;
+  }
+}
+
+END {
+  check_one(lastfile);
+  exit(result);
+}

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog                   |   35 +++++
 config.make.in              |    1 +
 elf/Makefile                |  104 +++++++++------
 elf/check-execstack.c       |  162 -----------------------
 elf/check-localplt.c        |  298 -------------------------------------------
 elf/check-textrel.c         |  198 ----------------------------
 scripts/check-execstack.awk |   52 ++++++++
 scripts/check-textrel.awk   |   41 ++++++
 scripts/localplt.awk        |   59 +++++++++
 9 files changed, 252 insertions(+), 698 deletions(-)
 delete mode 100644 elf/check-execstack.c
 delete mode 100644 elf/check-localplt.c
 delete mode 100644 elf/check-textrel.c
 create mode 100644 scripts/check-execstack.awk
 create mode 100644 scripts/check-textrel.awk
 create mode 100644 scripts/localplt.awk


hooks/post-receive
-- 
GNU C Library master sources


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]