# HG changeset patch # User dcubed # Date 1337889421 25200 # Node ID fb8f9ab27c14301bf7ce272ede5fb69b38db3fba # Parent df84b4a3ebcb3347038c6dc2c790cc6985ff7e89# Parent 9c1709c4c80c91590f345aee5dcbacc6c7c193b0 Merge diff -r df84b4a3ebcb -r fb8f9ab27c14 make/solaris/makefiles/defs.make --- a/make/solaris/makefiles/defs.make Thu May 24 13:37:47 2012 +0200 +++ b/make/solaris/makefiles/defs.make Thu May 24 12:57:01 2012 -0700 @@ -123,25 +123,10 @@ ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) # Default OBJCOPY comes from the SUNWbinutils package: DEF_OBJCOPY=/usr/sfw/bin/gobjcopy - ifeq ($(VM_PLATFORM),solaris_amd64) - # On Solaris AMD64/X64, gobjcopy is not happy and fails: - # - # usr/sfw/bin/gobjcopy --add-gnu-debuglink=.debuginfo .so - # BFD: stKPaiop: Not enough room for program headers, try linking with -N - # /usr/sfw/bin/gobjcopy: stKPaiop: Bad value - # BFD: stKPaiop: Not enough room for program headers, try linking with -N - # /usr/sfw/bin/gobjcopy: libsaproc.debuginfo: Bad value - # BFD: stKPaiop: Not enough room for program headers, try linking with -N - # /usr/sfw/bin/gobjcopy: stKPaiop: Bad value - _JUNK_ := $(shell \ - echo >&2 "INFO: $(DEF_OBJCOPY) is not working on Solaris AMD64/X64") - OBJCOPY= - else - OBJCOPY=$(shell test -x $(DEF_OBJCOPY) && echo $(DEF_OBJCOPY)) - ifneq ($(ALT_OBJCOPY),) - _JUNK_ := $(shell echo >&2 "INFO: ALT_OBJCOPY=$(ALT_OBJCOPY)") - OBJCOPY=$(shell test -x $(ALT_OBJCOPY) && echo $(ALT_OBJCOPY)) - endif + OBJCOPY=$(shell test -x $(DEF_OBJCOPY) && echo $(DEF_OBJCOPY)) + ifneq ($(ALT_OBJCOPY),) + _JUNK_ := $(shell echo >&2 "INFO: ALT_OBJCOPY=$(ALT_OBJCOPY)") + OBJCOPY=$(shell test -x $(ALT_OBJCOPY) && echo $(ALT_OBJCOPY)) endif else OBJCOPY= diff -r df84b4a3ebcb -r fb8f9ab27c14 make/solaris/makefiles/dtrace.make --- a/make/solaris/makefiles/dtrace.make Thu May 24 13:37:47 2012 +0200 +++ b/make/solaris/makefiles/dtrace.make Thu May 24 12:57:01 2012 -0700 @@ -108,15 +108,24 @@ XLIBJVM_DTRACE_G_DEBUGINFO = 64/$(LIBJVM_DTRACE_G_DEBUGINFO) XLIBJVM_DTRACE_G_DIZ = 64/$(LIBJVM_DTRACE_G_DIZ) -$(XLIBJVM_DB): $(DTRACE_SRCDIR)/$(JVM_DB).c $(JVMOFFS).h $(LIBJVM_DB_MAPFILE) +$(XLIBJVM_DB): $(ADD_GNU_DEBUGLINK) $(FIX_EMPTY_SEC_HDR_FLAGS) $(DTRACE_SRCDIR)/$(JVM_DB).c $(JVMOFFS).h $(LIBJVM_DB_MAPFILE) @echo Making $@ $(QUIETLY) mkdir -p 64/ ; \ $(CC) $(SYMFLAG) $(ARCHFLAG/$(ISA)) -D$(TYPE) -I. -I$(GENERATED) \ $(SHARED_FLAG) $(LFLAGS_JVM_DB) -o $@ $(DTRACE_SRCDIR)/$(JVM_DB).c -lc [ -f $(XLIBJVM_DB_G) ] || { ln -s $(LIBJVM_DB) $(XLIBJVM_DB_G); } ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) +# gobjcopy crashes on "empty" section headers with the SHF_ALLOC flag set. +# Clear the SHF_ALLOC flag (if set) from empty section headers. +# An empty section header has sh_addr == 0 and sh_size == 0. +# This problem has only been seen on Solaris X64, but we call this tool +# on all Solaris builds just in case. + $(QUIETLY) $(FIX_EMPTY_SEC_HDR_FLAGS) $@ $(QUIETLY) $(OBJCOPY) --only-keep-debug $@ $(XLIBJVM_DB_DEBUGINFO) - $(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(XLIBJVM_DB_DEBUGINFO) $@ +# $(OBJCOPY) --add-gnu-debuglink=... corrupts SUNW_* sections. +# Use $(ADD_GNU_DEBUGLINK) until a fixed $(OBJCOPY) is available. +# $(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(XLIBJVM_DB_DEBUGINFO) $@ + $(QUIETLY) $(ADD_GNU_DEBUGLINK) $(XLIBJVM_DB_DEBUGINFO) $@ ifeq ($(STRIP_POLICY),all_strip) $(QUIETLY) $(STRIP) $@ else @@ -133,15 +142,19 @@ endif endif -$(XLIBJVM_DTRACE): $(DTRACE_SRCDIR)/$(JVM_DTRACE).c $(DTRACE_SRCDIR)/$(JVM_DTRACE).h $(LIBJVM_DTRACE_MAPFILE) +$(XLIBJVM_DTRACE): $(ADD_GNU_DEBUGLINK) $(FIX_EMPTY_SEC_HDR_FLAGS) $(DTRACE_SRCDIR)/$(JVM_DTRACE).c $(DTRACE_SRCDIR)/$(JVM_DTRACE).h $(LIBJVM_DTRACE_MAPFILE) @echo Making $@ $(QUIETLY) mkdir -p 64/ ; \ $(CC) $(SYMFLAG) $(ARCHFLAG/$(ISA)) -D$(TYPE) -I. \ $(SHARED_FLAG) $(LFLAGS_JVM_DTRACE) -o $@ $(DTRACE_SRCDIR)/$(JVM_DTRACE).c -lc -lthread -ldoor [ -f $(XLIBJVM_DTRACE_G) ] || { ln -s $(LIBJVM_DTRACE) $(XLIBJVM_DTRACE_G); } ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) +# Clear the SHF_ALLOC flag (if set) from empty section headers. + $(QUIETLY) $(FIX_EMPTY_SEC_HDR_FLAGS) $@ $(QUIETLY) $(OBJCOPY) --only-keep-debug $@ $(XLIBJVM_DTRACE_DEBUGINFO) - $(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(XLIBJVM_DTRACE_DEBUGINFO) $@ +# $(OBJCOPY) --add-gnu-debuglink=... corrupts SUNW_* sections. +# $(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(XLIBJVM_DTRACE_DEBUGINFO) $@ + $(QUIETLY) $(ADD_GNU_DEBUGLINK) $(XLIBJVM_DTRACE_DEBUGINFO) $@ ifeq ($(STRIP_POLICY),all_strip) $(QUIETLY) $(STRIP) $@ else @@ -198,14 +211,18 @@ $(JVMOFFS.o): $(JVMOFFS).h $(JVMOFFS).cpp $(QUIETLY) $(CXX) -c -I. -o $@ $(ARCHFLAG) -D$(TYPE) $(JVMOFFS).cpp -$(LIBJVM_DB): $(DTRACE_SRCDIR)/$(JVM_DB).c $(JVMOFFS.o) $(XLIBJVM_DB) $(LIBJVM_DB_MAPFILE) +$(LIBJVM_DB): $(ADD_GNU_DEBUGLINK) $(FIX_EMPTY_SEC_HDR_FLAGS) $(DTRACE_SRCDIR)/$(JVM_DB).c $(JVMOFFS.o) $(XLIBJVM_DB) $(LIBJVM_DB_MAPFILE) @echo Making $@ $(QUIETLY) $(CC) $(SYMFLAG) $(ARCHFLAG) -D$(TYPE) -I. -I$(GENERATED) \ $(SHARED_FLAG) $(LFLAGS_JVM_DB) -o $@ $(DTRACE_SRCDIR)/$(JVM_DB).c -lc [ -f $(LIBJVM_DB_G) ] || { ln -s $@ $(LIBJVM_DB_G); } ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) +# Clear the SHF_ALLOC flag (if set) from empty section headers. + $(QUIETLY) $(FIX_EMPTY_SEC_HDR_FLAGS) $@ $(QUIETLY) $(OBJCOPY) --only-keep-debug $@ $(LIBJVM_DB_DEBUGINFO) - $(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBJVM_DB_DEBUGINFO) $@ +# $(OBJCOPY) --add-gnu-debuglink=... corrupts SUNW_* sections. +# $(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBJVM_DB_DEBUGINFO) $@ + $(QUIETLY) $(ADD_GNU_DEBUGLINK) $(LIBJVM_DB_DEBUGINFO) $@ ifeq ($(STRIP_POLICY),all_strip) $(QUIETLY) $(STRIP) $@ else @@ -222,14 +239,18 @@ endif endif -$(LIBJVM_DTRACE): $(DTRACE_SRCDIR)/$(JVM_DTRACE).c $(XLIBJVM_DTRACE) $(DTRACE_SRCDIR)/$(JVM_DTRACE).h $(LIBJVM_DTRACE_MAPFILE) +$(LIBJVM_DTRACE): $(ADD_GNU_DEBUGLINK) $(FIX_EMPTY_SEC_HDR_FLAGS) $(DTRACE_SRCDIR)/$(JVM_DTRACE).c $(XLIBJVM_DTRACE) $(DTRACE_SRCDIR)/$(JVM_DTRACE).h $(LIBJVM_DTRACE_MAPFILE) @echo Making $@ $(QUIETLY) $(CC) $(SYMFLAG) $(ARCHFLAG) -D$(TYPE) -I. \ $(SHARED_FLAG) $(LFLAGS_JVM_DTRACE) -o $@ $(DTRACE_SRCDIR)/$(JVM_DTRACE).c -lc -lthread -ldoor [ -f $(LIBJVM_DTRACE_G) ] || { ln -s $@ $(LIBJVM_DTRACE_G); } ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) +# Clear the SHF_ALLOC flag (if set) from empty section headers. + $(QUIETLY) $(FIX_EMPTY_SEC_HDR_FLAGS) $@ $(QUIETLY) $(OBJCOPY) --only-keep-debug $@ $(LIBJVM_DTRACE_DEBUGINFO) - $(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBJVM_DTRACE_DEBUGINFO) $@ +# $(OBJCOPY) --add-gnu-debuglink=... corrupts SUNW_* sections. +# $(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBJVM_DTRACE_DEBUGINFO) $@ + $(QUIETLY) $(ADD_GNU_DEBUGLINK) $(LIBJVM_DTRACE_DEBUGINFO) $@ ifeq ($(STRIP_POLICY),all_strip) $(QUIETLY) $(STRIP) $@ else diff -r df84b4a3ebcb -r fb8f9ab27c14 make/solaris/makefiles/fix_empty_sec_hdr_flags.make --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/make/solaris/makefiles/fix_empty_sec_hdr_flags.make Thu May 24 12:57:01 2012 -0700 @@ -0,0 +1,51 @@ +# +# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# + +# Rules to build fix_empty_sec_hdr_flags, used by vm.make on Solaris + +GENERATED = ../generated +FIX_EMPTY_SEC_HDR_FLAGS = $(GENERATED)/fix_empty_sec_hdr_flags + +FIX_EMPTY_SEC_HDR_FLAGS_DIR = $(GAMMADIR)/src/os/solaris/fix_empty_sec_hdr_flags +FIX_EMPTY_SEC_HDR_FLAGS_SRC = $(FIX_EMPTY_SEC_HDR_FLAGS_DIR)/fix_empty_sec_hdr_flags.c +FIX_EMPTY_SEC_HDR_FLAGS_FLAGS = +LIBS_FIX_EMPTY_SEC_HDR_FLAGS += -lelf + +ifeq ("${Platform_compiler}", "sparcWorks") +# Enable the following FIX_EMPTY_SEC_HDR_FLAGS_FLAGS addition if you need to +# compare the built ELF objects. +# +# The -g option makes static data global and the "-W0,-noglobal" +# option tells the compiler to not globalize static data using a unique +# globalization prefix. Instead force the use of a static globalization +# prefix based on the source filepath so the objects from two identical +# compilations are the same. +# +# Note: The blog says to use "-W0,-xglobalstatic", but that doesn't +# seem to work. I got "-W0,-noglobal" from Kelly and that works. +#FIX_EMPTY_SEC_HDR_FLAGS_FLAGS += -W0,-noglobal +endif # Platform_compiler == sparcWorks + +$(FIX_EMPTY_SEC_HDR_FLAGS): $(FIX_EMPTY_SEC_HDR_FLAGS_SRC) + $(CC) -g -o $@ $< $(FIX_EMPTY_SEC_HDR_FLAGS_FLAGS) $(LIBS_FIX_EMPTY_SEC_HDR_FLAGS) diff -r df84b4a3ebcb -r fb8f9ab27c14 make/solaris/makefiles/jsig.make --- a/make/solaris/makefiles/jsig.make Thu May 24 13:37:47 2012 +0200 +++ b/make/solaris/makefiles/jsig.make Thu May 24 12:57:01 2012 -0700 @@ -52,14 +52,23 @@ LFLAGS_JSIG += -mt -xnolib endif -$(LIBJSIG): $(JSIGSRCDIR)/jsig.c $(LIBJSIG_MAPFILE) +$(LIBJSIG): $(ADD_GNU_DEBUGLINK) $(FIX_EMPTY_SEC_HDR_FLAGS) $(JSIGSRCDIR)/jsig.c $(LIBJSIG_MAPFILE) @echo Making signal interposition lib... $(QUIETLY) $(CC) $(SYMFLAG) $(ARCHFLAG) $(SHARED_FLAG) $(PICFLAG) \ - $(LFLAGS_JSIG) -o $@ $< -ldl + $(LFLAGS_JSIG) -o $@ $(JSIGSRCDIR)/jsig.c -ldl [ -f $(LIBJSIG_G) ] || { ln -s $@ $(LIBJSIG_G); } ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) +# gobjcopy crashes on "empty" section headers with the SHF_ALLOC flag set. +# Clear the SHF_ALLOC flag (if set) from empty section headers. +# An empty section header has sh_addr == 0 and sh_size == 0. +# This problem has only been seen on Solaris X64, but we call this tool +# on all Solaris builds just in case. + $(QUIETLY) $(FIX_EMPTY_SEC_HDR_FLAGS) $@ $(QUIETLY) $(OBJCOPY) --only-keep-debug $@ $(LIBJSIG_DEBUGINFO) - $(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBJSIG_DEBUGINFO) $@ +# $(OBJCOPY) --add-gnu-debuglink=... corrupts SUNW_* sections. +# Use $(ADD_GNU_DEBUGLINK) until a fixed $(OBJCOPY) is available. +# $(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBJSIG_DEBUGINFO) $@ + $(QUIETLY) $(ADD_GNU_DEBUGLINK) $(LIBJSIG_DEBUGINFO) $@ ifeq ($(STRIP_POLICY),all_strip) $(QUIETLY) $(STRIP) $@ else diff -r df84b4a3ebcb -r fb8f9ab27c14 make/solaris/makefiles/saproc.make --- a/make/solaris/makefiles/saproc.make Thu May 24 13:37:47 2012 +0200 +++ b/make/solaris/makefiles/saproc.make Thu May 24 12:57:01 2012 -0700 @@ -90,7 +90,7 @@ # when actually building on Nevada-B158 or earlier: #SOLARIS_11_B159_OR_LATER=-DSOLARIS_11_B159_OR_LATER -$(LIBSAPROC): $(SASRCFILES) $(SAMAPFILE) +$(LIBSAPROC): $(ADD_GNU_DEBUGLINK) $(FIX_EMPTY_SEC_HDR_FLAGS) $(SASRCFILES) $(SAMAPFILE) $(QUIETLY) if [ "$(BOOT_JAVA_HOME)" = "" ]; then \ echo "ALT_BOOTDIR, BOOTDIR or JAVA_HOME needs to be defined to build SA"; \ exit 1; \ @@ -109,8 +109,17 @@ -ldl -ldemangle -lthread -lc [ -f $(LIBSAPROC_G) ] || { ln -s $@ $(LIBSAPROC_G); } ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) +# gobjcopy crashes on "empty" section headers with the SHF_ALLOC flag set. +# Clear the SHF_ALLOC flag (if set) from empty section headers. +# An empty section header has sh_addr == 0 and sh_size == 0. +# This problem has only been seen on Solaris X64, but we call this tool +# on all Solaris builds just in case. + $(QUIETLY) $(FIX_EMPTY_SEC_HDR_FLAGS) $@ $(QUIETLY) $(OBJCOPY) --only-keep-debug $@ $(LIBSAPROC_DEBUGINFO) - $(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBSAPROC_DEBUGINFO) $@ +# $(OBJCOPY) --add-gnu-debuglink=... corrupts SUNW_* sections. +# Use $(ADD_GNU_DEBUGLINK) until a fixed $(OBJCOPY) is available. +# $(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBSAPROC_DEBUGINFO) $@ + $(QUIETLY) $(ADD_GNU_DEBUGLINK) $(LIBSAPROC_DEBUGINFO) $@ ifeq ($(STRIP_POLICY),all_strip) $(QUIETLY) $(STRIP) $@ else diff -r df84b4a3ebcb -r fb8f9ab27c14 make/solaris/makefiles/vm.make --- a/make/solaris/makefiles/vm.make Thu May 24 13:37:47 2012 +0200 +++ b/make/solaris/makefiles/vm.make Thu May 24 12:57:01 2012 -0700 @@ -149,6 +149,10 @@ include $(MAKEFILES_DIR)/add_gnu_debuglink.make #---------------------------------------------------------------------- +# fix_empty_sec_hdr_flags tool +include $(MAKEFILES_DIR)/fix_empty_sec_hdr_flags.make + +#---------------------------------------------------------------------- # JVM JVM = jvm @@ -280,7 +284,7 @@ LINK_VM = $(LINK_LIB.CXX) endif # making the library: -$(LIBJVM): $(ADD_GNU_DEBUGLINK) $(LIBJVM.o) $(LIBJVM_MAPFILE) +$(LIBJVM): $(ADD_GNU_DEBUGLINK) $(FIX_EMPTY_SEC_HDR_FLAGS) $(LIBJVM.o) $(LIBJVM_MAPFILE) ifeq ($(filter -sbfast -xsbfast, $(CFLAGS_BROWSE)),) @echo Linking vm... $(QUIETLY) $(LINK_LIB.CXX/PRE_HOOK) @@ -290,10 +294,15 @@ $(QUIETLY) [ -f $(LIBJVM_G) ] || ln -s $@ $(LIBJVM_G) $(QUIETLY) [ -f $(LIBJVM_G).1 ] || ln -s $@.1 $(LIBJVM_G).1 ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) +# gobjcopy crashes on "empty" section headers with the SHF_ALLOC flag set. +# Clear the SHF_ALLOC flag (if set) from empty section headers. +# An empty section header has sh_addr == 0 and sh_size == 0. +# This problem has only been seen on Solaris X64, but we call this tool +# on all Solaris builds just in case. + $(QUIETLY) $(FIX_EMPTY_SEC_HDR_FLAGS) $@ $(QUIETLY) $(OBJCOPY) --only-keep-debug $@ $(LIBJVM_DEBUGINFO) -# $(OBJCOPY) --add-gnu-debuglink=... corrupts the SUNW_dof section -# in libjvm.so. Use $(ADD_GNU_DEBUGLINK) until a fixed $(OBJCOPY) -# is available. +# $(OBJCOPY) --add-gnu-debuglink=... corrupts SUNW_* sections. +# Use $(ADD_GNU_DEBUGLINK) until a fixed $(OBJCOPY) is available. # $(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBJVM_DEBUGINFO) $@ $(QUIETLY) $(ADD_GNU_DEBUGLINK) $(LIBJVM_DEBUGINFO) $@ ifeq ($(STRIP_POLICY),all_strip) diff -r df84b4a3ebcb -r fb8f9ab27c14 make/windows/makefiles/defs.make --- a/make/windows/makefiles/defs.make Thu May 24 13:37:47 2012 +0200 +++ b/make/windows/makefiles/defs.make Thu May 24 12:57:01 2012 -0700 @@ -143,14 +143,7 @@ MAKE_ARGS += ENABLE_FULL_DEBUG_SYMBOLS=$(ENABLE_FULL_DEBUG_SYMBOLS) ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) - # Disable ZIP_DEBUGINFO_FILES by default because various tests are - # failing in nightly when the debug info files are ZIP'ed. - #ZIP_DEBUGINFO_FILES ?= 0 - # The above conditional setting logic is unreliable on Windows for - # unknown reasons. We force ZIP_DEBUGINFO_FILES to be disabled on - # Windows until we figure out why the various tests are failing - # AND why the conditional setting logic is unreliable. - ZIP_DEBUGINFO_FILES=0 + ZIP_DEBUGINFO_FILES ?= 1 else ZIP_DEBUGINFO_FILES=0 endif diff -r df84b4a3ebcb -r fb8f9ab27c14 src/os/solaris/fix_empty_sec_hdr_flags/fix_empty_sec_hdr_flags.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/os/solaris/fix_empty_sec_hdr_flags/fix_empty_sec_hdr_flags.c Thu May 24 12:57:01 2012 -0700 @@ -0,0 +1,181 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +/* + * Name: fix_empty_sec_hdr_flags.c + * + * Description: Remove the SHF_ALLOC flag from "empty" section headers. + * An "empty" section header has sh_addr == 0 and sh_size == 0. + * + * This program is adapted from the example program shown on the + * elf(3elf) man page and from code from the Solaris compiler + * driver. + */ + +#include +#include +#include +#include +#include +#include + +static void failure(void); + +void +main(int argc, char ** argv) { + void * ehdr; /* ELF header */ + unsigned int i; /* section counter */ + int fd; /* descriptor for file */ + Elf * elf; /* ELF descriptor */ + char * elf_ident; /* ELF identity string */ + char * elf_obj; /* elf_obj file */ + int fix_count; /* number of flags fixed */ + int is_elfclass64; /* is an ELFCLASS64 file? */ + Elf_Scn * scn; /* ELF section descriptor */ + void * shdr; /* ELF section header */ + Elf_Data * shstrtab; /* ELF section header string table */ + + if (argc != 2) { + (void) fprintf(stderr, "Usage: %s elf_obj\n", argv[0]); + exit(2); + } + + /* open the elf_obj */ + elf_obj = argv[1]; + if ((fd = open(elf_obj, O_RDWR)) == -1) { + (void) fprintf(stderr, "%s: cannot open file.\n", elf_obj); + exit(3); + } + + (void) printf("Opening '%s' for update\n", elf_obj); + (void) fflush(stdout); + (void) elf_version(EV_CURRENT); /* coordinate ELF versions */ + + /* obtain the ELF descriptors from the input file */ + if ((elf = elf_begin(fd, ELF_C_RDWR, NULL)) == NULL) { + failure(); + } + + /* determine if ELFCLASS64 or not? */ + elf_ident = elf_getident(elf, NULL); + is_elfclass64 = (elf_ident[EI_CLASS] == ELFCLASS64); + + /* get the ELF header */ + if (is_elfclass64) { + ehdr = elf64_getehdr(elf); + } else { + ehdr = elf32_getehdr(elf); + } + if (ehdr == NULL) { + failure(); + } + + /* get the ELF section descriptor */ + if (is_elfclass64) { + scn = elf_getscn(elf, ((Elf64_Ehdr *) ehdr)->e_shstrndx); + } else { + scn = elf_getscn(elf, ((Elf32_Ehdr *) ehdr)->e_shstrndx); + } + if (scn == NULL) { + failure(); + } + + /* get the section header string table */ + shstrtab = elf_getdata(scn, NULL); + if (shstrtab == NULL) { + failure(); + } + + fix_count = 0; + + /* traverse the sections of the input file */ + for (i = 1, scn = NULL; scn = elf_nextscn(elf, scn); i++) { + int has_flag_set; /* is SHF_ALLOC flag set? */ + int is_empty; /* is section empty? */ + char * name; /* short hand pointer */ + + /* get the section header */ + if (is_elfclass64) { + shdr = elf64_getshdr(scn); + } else { + shdr = elf32_getshdr(scn); + } + if (shdr == NULL) { + failure(); + } + + if (is_elfclass64) { + name = (char *)shstrtab->d_buf + ((Elf64_Shdr *) shdr)->sh_name; + } else { + name = (char *)shstrtab->d_buf + ((Elf32_Shdr *) shdr)->sh_name; + } + + if (is_elfclass64) { + has_flag_set = ((Elf64_Shdr *) shdr)->sh_flags & SHF_ALLOC; + is_empty = ((Elf64_Shdr *) shdr)->sh_addr == 0 && + ((Elf64_Shdr *) shdr)->sh_size == 0; + } else { + has_flag_set = ((Elf32_Shdr *) shdr)->sh_flags & SHF_ALLOC; + is_empty = ((Elf32_Shdr *) shdr)->sh_addr == 0 && + ((Elf32_Shdr *) shdr)->sh_size == 0; + } + + if (is_empty && has_flag_set) { + (void) printf("section[%u] '%s' is empty, " + "but SHF_ALLOC flag is set.\n", i, name); + (void) printf("Clearing the SHF_ALLOC flag.\n"); + + if (is_elfclass64) { + ((Elf64_Shdr *) shdr)->sh_flags &= ~SHF_ALLOC; + } else { + ((Elf32_Shdr *) shdr)->sh_flags &= ~SHF_ALLOC; + } + fix_count++; + } + } /* end for each ELF section */ + + if (fix_count > 0) { + (void) printf("Saving %d updates to '%s'\n", fix_count, elf_obj); + (void) fflush(stdout); + (void) elf_update(elf, ELF_C_NULL); /* recalc ELF memory structures */ + (void) elf_update(elf, ELF_C_WRITE); /* write out changes to ELF obj */ + } else { + (void) printf("No SHF_ALLOC flags needed to be cleared.\n"); + } + + (void) elf_end(elf); /* done with ELF obj */ + (void) close(fd); + + (void) printf("Done %s '%s'\n", + (fix_count > 0) ? "updating" : "with", elf_obj); + (void) fflush(stdout); + exit(0); +} /* end main */ + + +static void +failure() { + (void) fprintf(stderr, "%s\n", elf_errmsg(elf_errno())); + exit(6); +}