Added a testsuite. More support for COPY relocations.

This commit is contained in:
Ian Lance Taylor 2006-11-30 23:52:50 +00:00
parent 2621033b5d
commit 5a6f7e2db5
27 changed files with 1990 additions and 242 deletions

View File

@ -2,7 +2,7 @@
AUTOMAKE_OPTIONS =
SUBDIRS = po
SUBDIRS = po testsuite
tooldir = $(exec_prefix)/$(target_alias)
@ -18,6 +18,7 @@ INCLUDES = -D_GNU_SOURCE \
YFLAGS = -d
noinst_PROGRAMS = ld-new
noinst_LIBRARIES = libgold.a
CCFILES = \
archive.cc \
@ -74,19 +75,18 @@ YFILES = \
EXTRA_DIST = yyscript.c yyscript.h
POTFILES= $(CCFILES) $(HFILES) $(TARGETFILES)
libgold_a_SOURCES = $(CCFILES) $(HFILES) $(YFILES)
po/POTFILES.in: @MAINT@ Makefile
for f in $(POTFILES); do echo $$f; done | LC_COLLATE= sort > tmp \
&& mv tmp $(srcdir)/po/POTFILES.in
ld_new_SOURCES = $(CCFILES) $(HFILES) $(TARGETFILES) $(YFILES)
ld_new_DEPENDENCIES = $(LIBINTL_DEP)
ld_new_LDADD = $(LIBINTL)
ld_new_SOURCES = main.cc $(TARGETFILES)
ld_new_DEPENDENCIES = libgold.a $(LIBINTL_DEP)
ld_new_LDADD = libgold.a $(LIBINTL)
# Use an explicit dependency for the bison generated header file.
script.$(OBJEXT): yyscript.h
# We have to build libgold.a before we run the tests.
check: libgold.a
.PHONY: install-exec-local
install-exec-local: ld-new$(EXEEXT)
@ -102,3 +102,9 @@ install-exec-local: ld-new$(EXEEXT)
# We want install to imply install-info as per GNU standards, despite
# the cygnus option.
install-data-local: install-info
POTFILES= $(CCFILES) $(HFILES) $(TARGETFILES)
po/POTFILES.in: @MAINT@ Makefile
for f in $(POTFILES); do echo $$f; done | LC_COLLATE= sort > tmp \
&& mv tmp $(srcdir)/po/POTFILES.in

View File

@ -16,6 +16,7 @@
# Process this file with automake to generate Makefile.in
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
@ -62,7 +63,11 @@ am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs
CONFIG_HEADER = config.h
CONFIG_CLEAN_FILES = po/Makefile.in
PROGRAMS = $(noinst_PROGRAMS)
LIBRARIES = $(noinst_LIBRARIES)
AR = ar
ARFLAGS = cru
libgold_a_AR = $(AR) $(ARFLAGS)
libgold_a_LIBADD =
am__objects_1 = archive.$(OBJEXT) common.$(OBJEXT) defstd.$(OBJEXT) \
dirsearch.$(OBJEXT) dynobj.$(OBJEXT) fileread.$(OBJEXT) \
gold.$(OBJEXT) gold-threads.$(OBJEXT) layout.$(OBJEXT) \
@ -71,10 +76,13 @@ am__objects_1 = archive.$(OBJEXT) common.$(OBJEXT) defstd.$(OBJEXT) \
script.$(OBJEXT) symtab.$(OBJEXT) stringpool.$(OBJEXT) \
target-select.$(OBJEXT) workqueue.$(OBJEXT)
am__objects_2 =
am__objects_3 = i386.$(OBJEXT)
am__objects_4 = yyscript.$(OBJEXT)
am_ld_new_OBJECTS = $(am__objects_1) $(am__objects_2) $(am__objects_3) \
$(am__objects_4)
am__objects_3 = yyscript.$(OBJEXT)
am_libgold_a_OBJECTS = $(am__objects_1) $(am__objects_2) \
$(am__objects_3)
libgold_a_OBJECTS = $(am_libgold_a_OBJECTS)
PROGRAMS = $(noinst_PROGRAMS)
am__objects_4 = i386.$(OBJEXT)
am_ld_new_OBJECTS = main.$(OBJEXT) $(am__objects_4)
ld_new_OBJECTS = $(am_ld_new_OBJECTS)
am__DEPENDENCIES_1 =
DEFAULT_INCLUDES = -I. -I$(srcdir) -I.
@ -90,8 +98,8 @@ CXXLD = $(CXX)
CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \
-o $@
YACCCOMPILE = $(YACC) $(YFLAGS) $(AM_YFLAGS)
SOURCES = $(ld_new_SOURCES)
DIST_SOURCES = $(ld_new_SOURCES)
SOURCES = $(libgold_a_SOURCES) $(ld_new_SOURCES)
DIST_SOURCES = $(libgold_a_SOURCES) $(ld_new_SOURCES)
RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
html-recursive info-recursive install-data-recursive \
install-exec-recursive install-info-recursive \
@ -171,6 +179,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
POSUB = @POSUB@
RANLIB = @RANLIB@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
@ -182,6 +191,7 @@ XGETTEXT = @XGETTEXT@
YACC = @YACC@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_RANLIB = @ac_ct_RANLIB@
ac_ct_STRIP = @ac_ct_STRIP@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
@ -225,7 +235,7 @@ target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
AUTOMAKE_OPTIONS =
SUBDIRS = po
SUBDIRS = po testsuite
tooldir = $(exec_prefix)/$(target_alias)
ACLOCAL_AMFLAGS = -I ../bfd -I ../config
AM_CXXFLAGS = $(WARN_CXXFLAGS) $(LFS_CXXFLAGS)
@ -235,6 +245,7 @@ INCLUDES = -D_GNU_SOURCE \
@INCINTL@
YFLAGS = -d
noinst_LIBRARIES = libgold.a
CCFILES = \
archive.cc \
common.cc \
@ -289,10 +300,11 @@ YFILES = \
yyscript.y
EXTRA_DIST = yyscript.c yyscript.h
libgold_a_SOURCES = $(CCFILES) $(HFILES) $(YFILES)
ld_new_SOURCES = main.cc $(TARGETFILES)
ld_new_DEPENDENCIES = libgold.a $(LIBINTL_DEP)
ld_new_LDADD = libgold.a $(LIBINTL)
POTFILES = $(CCFILES) $(HFILES) $(TARGETFILES)
ld_new_SOURCES = $(CCFILES) $(HFILES) $(TARGETFILES) $(YFILES)
ld_new_DEPENDENCIES = $(LIBINTL_DEP)
ld_new_LDADD = $(LIBINTL)
all: config.h
$(MAKE) $(AM_MAKEFLAGS) all-recursive
@ -351,13 +363,20 @@ distclean-hdr:
po/Makefile.in: $(top_builddir)/config.status $(top_srcdir)/po/Make-in
cd $(top_builddir) && $(SHELL) ./config.status $@
clean-noinstPROGRAMS:
-test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS)
clean-noinstLIBRARIES:
-test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
yyscript.h: yyscript.c
@if test ! -f $@; then \
rm -f yyscript.c; \
$(MAKE) yyscript.c; \
else :; fi
libgold.a: $(libgold_a_OBJECTS) $(libgold_a_DEPENDENCIES)
-rm -f libgold.a
$(libgold_a_AR) libgold.a $(libgold_a_OBJECTS) $(libgold_a_LIBADD)
$(RANLIB) libgold.a
clean-noinstPROGRAMS:
-test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS)
ld-new$(EXEEXT): $(ld_new_OBJECTS) $(ld_new_DEPENDENCIES)
@rm -f ld-new$(EXEEXT)
$(CXXLINK) $(ld_new_LDFLAGS) $(ld_new_OBJECTS) $(ld_new_LDADD) $(LIBS)
@ -378,6 +397,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gold.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/i386.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/layout.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/object.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/options.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/output.Po@am__quote@
@ -717,7 +737,7 @@ distcleancheck: distclean
exit 1; } >&2
check-am: all-am
check: check-recursive
all-am: Makefile $(PROGRAMS) config.h
all-am: Makefile $(LIBRARIES) $(PROGRAMS) config.h
installdirs: installdirs-recursive
installdirs-am:
install: install-recursive
@ -748,7 +768,8 @@ maintainer-clean-generic:
-rm -f yyscript.h
clean: clean-recursive
clean-am: clean-generic clean-noinstPROGRAMS mostlyclean-am
clean-am: clean-generic clean-noinstLIBRARIES clean-noinstPROGRAMS \
mostlyclean-am
distclean: distclean-recursive
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
@ -801,29 +822,29 @@ uninstall-am: uninstall-info-am
uninstall-info: uninstall-info-recursive
.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am am--refresh check \
check-am clean clean-generic clean-noinstPROGRAMS \
clean-recursive ctags ctags-recursive dist dist-all dist-bzip2 \
dist-gzip dist-shar dist-tarZ dist-zip distcheck distclean \
distclean-compile distclean-generic distclean-hdr \
distclean-recursive distclean-tags distcleancheck distdir \
distuninstallcheck dvi dvi-am html html-am info info-am \
install install-am install-data install-data-am \
install-data-local install-exec install-exec-am \
install-exec-local install-info install-info-am install-man \
install-strip installcheck installcheck-am installdirs \
installdirs-am maintainer-clean maintainer-clean-generic \
maintainer-clean-recursive mostlyclean mostlyclean-compile \
mostlyclean-generic mostlyclean-recursive pdf pdf-am ps ps-am \
tags tags-recursive uninstall uninstall-am uninstall-info-am
check-am clean clean-generic clean-noinstLIBRARIES \
clean-noinstPROGRAMS clean-recursive ctags ctags-recursive \
dist dist-all dist-bzip2 dist-gzip dist-shar dist-tarZ \
dist-zip distcheck distclean distclean-compile \
distclean-generic distclean-hdr distclean-recursive \
distclean-tags distcleancheck distdir distuninstallcheck dvi \
dvi-am html html-am info info-am install install-am \
install-data install-data-am install-data-local install-exec \
install-exec-am install-exec-local install-info \
install-info-am install-man install-strip installcheck \
installcheck-am installdirs installdirs-am maintainer-clean \
maintainer-clean-generic maintainer-clean-recursive \
mostlyclean mostlyclean-compile mostlyclean-generic \
mostlyclean-recursive pdf pdf-am ps ps-am tags tags-recursive \
uninstall uninstall-am uninstall-info-am
po/POTFILES.in: @MAINT@ Makefile
for f in $(POTFILES); do echo $$f; done | LC_COLLATE= sort > tmp \
&& mv tmp $(srcdir)/po/POTFILES.in
# Use an explicit dependency for the bison generated header file.
script.$(OBJEXT): yyscript.h
# We have to build libgold.a before we run the tests.
check: libgold.a
.PHONY: install-exec-local
install-exec-local: ld-new$(EXEEXT)
@ -839,6 +860,10 @@ install-exec-local: ld-new$(EXEEXT)
# We want install to imply install-info as per GNU standards, despite
# the cygnus option.
install-data-local: install-info
po/POTFILES.in: @MAINT@ Makefile
for f in $(POTFILES); do echo $$f; done | LC_COLLATE= sort > tmp \
&& mv tmp $(srcdir)/po/POTFILES.in
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

87
gold/configure vendored
View File

@ -309,7 +309,7 @@ ac_includes_default="\
# include <unistd.h>
#endif"
ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CXX CXXFLAGS ac_ct_CXX CXXDEPMODE am__fastdepCXX_TRUE am__fastdepCXX_FALSE YACC USE_NLS LIBINTL LIBINTL_DEP INCINTL XGETTEXT GMSGFMT POSUB CATALOGS DATADIRNAME INSTOBJEXT GENCAT CATOBJEXT MKINSTALLDIRS MSGFMT MSGMERGE WARN_CFLAGS NO_WERROR WARN_CXXFLAGS LFS_CXXFLAGS CXXCPP EGREP MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT LIBOBJS LTLIBOBJS'
ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CXX CXXFLAGS ac_ct_CXX CXXDEPMODE am__fastdepCXX_TRUE am__fastdepCXX_FALSE YACC RANLIB ac_ct_RANLIB USE_NLS LIBINTL LIBINTL_DEP INCINTL XGETTEXT GMSGFMT POSUB CATALOGS DATADIRNAME INSTOBJEXT GENCAT CATOBJEXT MKINSTALLDIRS MSGFMT MSGMERGE WARN_CFLAGS NO_WERROR WARN_CXXFLAGS LFS_CXXFLAGS CXXCPP EGREP MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT LIBOBJS LTLIBOBJS'
ac_subst_files=''
# Initialize some variables set by options.
@ -3450,6 +3450,86 @@ fi
done
test -n "$YACC" || YACC="yacc"
if test -n "$ac_tool_prefix"; then
# Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
set dummy ${ac_tool_prefix}ranlib; ac_word=$2
echo "$as_me:$LINENO: checking for $ac_word" >&5
echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
if test "${ac_cv_prog_RANLIB+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
if test -n "$RANLIB"; then
ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
fi
fi
RANLIB=$ac_cv_prog_RANLIB
if test -n "$RANLIB"; then
echo "$as_me:$LINENO: result: $RANLIB" >&5
echo "${ECHO_T}$RANLIB" >&6
else
echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi
fi
if test -z "$ac_cv_prog_RANLIB"; then
ac_ct_RANLIB=$RANLIB
# Extract the first word of "ranlib", so it can be a program name with args.
set dummy ranlib; ac_word=$2
echo "$as_me:$LINENO: checking for $ac_word" >&5
echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
if test -n "$ac_ct_RANLIB"; then
ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_RANLIB="ranlib"
echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":"
fi
fi
ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
if test -n "$ac_ct_RANLIB"; then
echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5
echo "${ECHO_T}$ac_ct_RANLIB" >&6
else
echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi
RANLIB=$ac_ct_RANLIB
else
RANLIB="$ac_cv_prog_RANLIB"
fi
# Find a good install program. We prefer a C program (faster),
# so one script is as good as another. But avoid the broken or
# incompatible versions:
@ -5070,7 +5150,7 @@ fi
ac_config_files="$ac_config_files Makefile po/Makefile.in:po/Make-in"
ac_config_files="$ac_config_files Makefile testsuite/Makefile po/Makefile.in:po/Make-in"
cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure
# tests run on this system so they can be shared between configure
@ -5642,6 +5722,7 @@ do
case "$ac_config_target" in
# Handling of arguments.
"Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
"testsuite/Makefile" ) CONFIG_FILES="$CONFIG_FILES testsuite/Makefile" ;;
"po/Makefile.in" ) CONFIG_FILES="$CONFIG_FILES po/Makefile.in:po/Make-in" ;;
"depfiles" ) CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
"default-1" ) CONFIG_COMMANDS="$CONFIG_COMMANDS default-1" ;;
@ -5788,6 +5869,8 @@ s,@CXXDEPMODE@,$CXXDEPMODE,;t t
s,@am__fastdepCXX_TRUE@,$am__fastdepCXX_TRUE,;t t
s,@am__fastdepCXX_FALSE@,$am__fastdepCXX_FALSE,;t t
s,@YACC@,$YACC,;t t
s,@RANLIB@,$RANLIB,;t t
s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t
s,@USE_NLS@,$USE_NLS,;t t
s,@LIBINTL@,$LIBINTL,;t t
s,@LIBINTL_DEP@,$LIBINTL_DEP,;t t

View File

@ -13,6 +13,7 @@ AM_CONFIG_HEADER(config.h:config.in)
AC_PROG_CC
AC_PROG_CXX
AC_PROG_YACC
AC_PROG_RANLIB
AC_PROG_INSTALL
ZW_GNU_GETTEXT_SISTER_DIR
AM_PO_SUBDIRS
@ -48,4 +49,4 @@ AC_LANG_POP(C++)
AM_MAINTAINER_MODE
AC_OUTPUT(Makefile po/Makefile.in:po/Make-in)
AC_OUTPUT(Makefile testsuite/Makefile po/Makefile.in:po/Make-in)

View File

@ -60,6 +60,8 @@ File_read::~File_read()
this->clear_views(true);
}
// Open the file.
bool
File_read::open(const std::string& name)
{
@ -72,11 +74,20 @@ File_read::open(const std::string& name)
return this->descriptor_ >= 0;
}
int
File_read::get_descriptor()
// Open the file for testing purposes.
bool
File_read::open(const std::string& name, const unsigned char* contents,
off_t contents_size)
{
gold_assert(this->lock_count_ > 0);
return this->descriptor_;
gold_assert(this->lock_count_ == 0
&& this->descriptor_ < 0
&& this->name_.empty());
this->name_ = name;
this->contents_ = contents;
this->contents_size_ = contents_size;
++this->lock_count_;
return true;
}
void
@ -121,23 +132,37 @@ off_t
File_read::do_read(off_t start, off_t size, void* p, off_t* pbytes)
{
gold_assert(this->lock_count_ > 0);
int o = this->descriptor_;
if (lseek(o, start, SEEK_SET) < 0)
off_t bytes;
if (this->contents_ == NULL)
{
fprintf(stderr, _("%s: %s: lseek to %lld failed: %s"),
program_name, this->filename().c_str(),
static_cast<long long>(start),
strerror(errno));
gold_exit(false);
int o = this->descriptor_;
if (lseek(o, start, SEEK_SET) < 0)
{
fprintf(stderr, _("%s: %s: lseek to %lld failed: %s"),
program_name, this->filename().c_str(),
static_cast<long long>(start),
strerror(errno));
gold_exit(false);
}
bytes = ::read(o, p, size);
if (bytes < 0)
{
fprintf(stderr, _("%s: %s: read failed: %s\n"),
program_name, this->filename().c_str(), strerror(errno));
gold_exit(false);
}
}
off_t bytes = ::read(o, p, size);
if (bytes < 0)
else
{
fprintf(stderr, _("%s: %s: read failed: %s\n"),
program_name, this->filename().c_str(), strerror(errno));
gold_exit(false);
bytes = this->contents_size_ - start;
if (bytes < 0)
bytes = 0;
else if (bytes > size)
bytes = size;
memcpy(p, this->contents_ + start, bytes);
}
if (pbytes != NULL)
@ -302,16 +327,30 @@ File_view::~File_view()
// Class Input_file.
// Create a file for testing.
Input_file::Input_file(const char* name, const unsigned char* contents,
off_t size)
: file_()
{
this->input_argument_ =
new Input_file_argument(name, false, Position_dependent_options());
bool ok = file_.open(name, contents, size);
gold_assert(ok);
}
// Open the file.
void
Input_file::open(const General_options& options, const Dirsearch& dirpath)
{
std::string name;
if (!this->input_argument_.is_lib())
name = this->input_argument_.name();
if (!this->input_argument_->is_lib())
name = this->input_argument_->name();
else
{
std::string n1("lib");
n1 += this->input_argument_.name();
n1 += this->input_argument_->name();
std::string n2;
if (options.is_static())
n1 += ".a";
@ -324,7 +363,7 @@ Input_file::open(const General_options& options, const Dirsearch& dirpath)
if (name.empty())
{
fprintf(stderr, _("%s: cannot find %s\n"), program_name,
this->input_argument_.name());
this->input_argument_->name());
gold_exit(false);
}
}

View File

@ -25,23 +25,27 @@ class File_read
{
public:
File_read()
: name_(), descriptor_(-1), lock_count_(0)
: name_(), descriptor_(-1), lock_count_(0), views_(),
saved_views_(), contents_(NULL), contents_size_(0)
{ }
~File_read();
// Open a file.
bool
open(const std::string& name);
// Pretend to open the file, but provide the file contents. No
// actual file system activity will occur. This is used for
// testing.
bool
open(const std::string& name, const unsigned char* contents, off_t size);
// Return the file name.
const std::string&
filename() const
{ return this->name_; }
// Return the file descriptor.
int
get_descriptor();
// Lock the file for access within a particular Task::run execution.
// This means that the descriptor can not be closed. This routine
// may only be called from the main thread.
@ -169,6 +173,10 @@ class File_read
// List of views which were locked but had to be removed from views_
// because they were not large enough.
Saved_views saved_views_;
// Specified file contents. Used only for testing purposes.
const unsigned char* contents_;
// Specified file size. Used only for testing purposes.
off_t contents_size_;
};
// A view of file data that persists even when the file is unlocked.
@ -209,17 +217,23 @@ class File_view
class Input_file
{
public:
Input_file(const Input_file_argument& input_argument)
: input_argument_(input_argument)
Input_file(const Input_file_argument* input_argument)
: input_argument_(input_argument), file_()
{ }
// Create an input file with the contents already provided. This is
// only used for testing. With this path, don't call the open
// method.
Input_file(const char* name, const unsigned char* contents, off_t size);
// Open the file.
void
open(const General_options&, const Dirsearch&);
// Return the name given by the user.
const char*
name() const
{ return this->input_argument_.name(); }
{ return this->input_argument_->name(); }
// Return the file name.
const std::string&
@ -234,7 +248,7 @@ class Input_file
Input_file(const Input_file&);
Input_file& operator=(const Input_file&);
const Input_file_argument& input_argument_;
const Input_file_argument* input_argument_;
File_read file_;
};

View File

@ -1,4 +1,4 @@
// ld.c -- linker main function
// gold.cc -- main linker functions
#include "gold.h"
@ -234,50 +234,3 @@ queue_final_tasks(const General_options& options,
}
} // End namespace gold.
using namespace gold;
int
main(int argc, char** argv)
{
#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
setlocale (LC_MESSAGES, "");
#endif
#if defined (HAVE_SETLOCALE)
setlocale (LC_CTYPE, "");
#endif
bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE);
gold::program_name = argv[0];
// Handle the command line options.
gold::Command_line command_line;
command_line.process(argc - 1, argv + 1);
// The work queue.
gold::Workqueue workqueue(command_line.options());
// The list of input objects.
Input_objects input_objects;
// The symbol table.
Symbol_table symtab;
// The layout object.
Layout layout(command_line.options());
// Get the search path from the -L options.
Dirsearch search_path;
search_path.add(&workqueue, command_line.options().search_path());
// Queue up the first set of tasks.
queue_initial_tasks(command_line.options(), search_path,
command_line, &workqueue, &input_objects,
&symtab, &layout);
// Run the main task processing loop.
workqueue.process();
gold::gold_exit(true);
}

View File

@ -137,6 +137,7 @@ namespace gold
{
class General_options;
class Command_line;
class Input_argument_list;
class Dirsearch;
class Input_objects;
@ -180,7 +181,7 @@ extern void do_gold_unreachable(const char*, int, const char*)
extern void
queue_initial_tasks(const General_options&,
const Dirsearch&,
const Input_argument_list&,
const Command_line&,
Workqueue*,
Input_objects*,
Symbol_table*,

View File

@ -27,9 +27,12 @@ class Output_data_plt_i386;
class Target_i386 : public Sized_target<32, false>
{
public:
typedef Output_data_reloc<elfcpp::SHT_REL, true, 32, false> Reloc_section;
Target_i386()
: Sized_target<32, false>(&i386_info),
got_(NULL), plt_(NULL), got_plt_(NULL)
got_(NULL), plt_(NULL), got_plt_(NULL), rel_dyn_(NULL),
copy_relocs_(NULL), dynbss_(NULL)
{ }
// Scan the relocations to look for symbol adjustments.
@ -46,6 +49,10 @@ class Target_i386 : public Sized_target<32, false>
const unsigned char* plocal_symbols,
Symbol** global_symbols);
// Finalize the sections.
void
do_finalize_sections(Layout*);
// Relocate a section.
void
relocate_section(const Relocate_info<32, false>*,
@ -170,9 +177,14 @@ class Target_i386 : public Sized_target<32, false>
return this->plt_;
}
// Get the dynamic reloc section, creating it if necessary.
Reloc_section*
rel_dyn_section(Layout*);
// Copy a relocation against a global symbol.
void
copy_reloc(const General_options*, Sized_relobj<32, false>*, unsigned int,
copy_reloc(const General_options*, Symbol_table*, Layout*,
Sized_relobj<32, false>*, unsigned int,
Symbol*, const elfcpp::Rel<32, false>&);
// Information about this specific target which we pass to the
@ -185,6 +197,12 @@ class Target_i386 : public Sized_target<32, false>
Output_data_plt_i386* plt_;
// The GOT PLT section.
Output_data_space* got_plt_;
// The dynamic reloc section.
Reloc_section* rel_dyn_;
// Relocs saved to avoid a COPY reloc.
Copy_relocs<32, false>* copy_relocs_;
// Space for variables copied with a COPY reloc.
Output_data_space* dynbss_;
};
const Target::Target_info Target_i386::i386_info =
@ -238,6 +256,21 @@ Target_i386::got_section(const General_options* options, Symbol_table* symtab,
return this->got_;
}
// Get the dynamic reloc section, creating it if necessary.
Target_i386::Reloc_section*
Target_i386::rel_dyn_section(Layout* layout)
{
if (this->rel_dyn_ == NULL)
{
gold_assert(layout != NULL);
this->rel_dyn_ = new Reloc_section();
layout->add_output_section_data(".rel.dyn", elfcpp::SHT_REL,
elfcpp::SHF_ALLOC, this->rel_dyn_);
}
return this->rel_dyn_;
}
// A class to handle the PLT data.
class Output_data_plt_i386 : public Output_section_data
@ -493,18 +526,70 @@ Target_i386::make_plt_entry(const General_options* options,
void
Target_i386::copy_reloc(const General_options* options,
Symbol_table* symtab,
Layout* layout,
Sized_relobj<32, false>* object,
unsigned int data_shndx, Symbol* gsym,
const elfcpp::Rel<32, false>&)
const elfcpp::Rel<32, false>& rel)
{
if (!Relocate_functions<32, false>::need_copy_reloc(options, object,
data_shndx, gsym))
Sized_symbol<32>* ssym;
ssym = symtab->get_sized_symbol SELECT_SIZE_NAME(32) (gsym
SELECT_SIZE(32));
if (!Copy_relocs<32, false>::need_copy_reloc(options, object,
data_shndx, ssym))
{
// So far we do not need a COPY reloc. Save this relocation.
// If it turns out that we never a COPY reloc for this symbol,
// then we emit the relocation.
// If it turns out that we never need a COPY reloc for this
// symbol, then we will emit the relocation.
if (this->copy_relocs_ == NULL)
this->copy_relocs_ = new Copy_relocs<32, false>();
this->copy_relocs_->save(ssym, object, data_shndx, rel);
}
else
{
// Allocate space for this symbol in the .bss section.
elfcpp::Elf_types<32>::Elf_WXword symsize = ssym->symsize();
// There is no defined way to determine the required alignment
// of the symbol. We pick the alignment based on the size. We
// set an arbitrary maximum of 256.
unsigned int align;
for (align = 1; align < 512; align <<= 1)
if ((symsize & align) != 0)
break;
if (this->dynbss_ == NULL)
{
this->dynbss_ = new Output_data_space(align);
layout->add_output_section_data(".bss",
elfcpp::SHT_NOBITS,
(elfcpp::SHF_ALLOC
| elfcpp::SHF_WRITE),
this->dynbss_);
}
Output_data_space* dynbss = this->dynbss_;
if (align > dynbss->addralign())
dynbss->set_space_alignment(align);
off_t dynbss_size = dynbss->data_size();
dynbss_size = align_address(dynbss_size, align);
off_t offset = dynbss_size;
dynbss->set_space_size(dynbss_size + symsize);
// Define the symbol in the .dynbss section.
symtab->define_in_output_data(this, ssym->name(), dynbss, offset,
symsize, ssym->type(), ssym->binding(),
ssym->visibility(), ssym->nonvis(),
false, false);
// Add the COPY reloc.
Reloc_section* rel_dyn = this->rel_dyn_section(layout);
rel_dyn->add_global(ssym, elfcpp::R_386_COPY, dynbss, offset);
}
}
// Optimize the TLS relocation type based on what we know about the
@ -715,7 +800,8 @@ Target_i386::Scan::global(const General_options& options,
if (gsym->type() == elfcpp::STT_FUNC)
target->make_plt_entry(&options, symtab, layout, gsym);
else
target->copy_reloc(&options, object, data_shndx, gsym, reloc);
target->copy_reloc(&options, symtab, layout, object, data_shndx,
gsym, reloc);
}
break;
@ -854,6 +940,23 @@ Target_i386::scan_relocs(const General_options& options,
global_symbols);
}
// Finalize the sections. This is where we emit any relocs we saved
// in an attempt to avoid generating extra COPY relocs.
void
Target_i386::do_finalize_sections(Layout* layout)
{
if (this->copy_relocs_ == NULL)
return;
if (this->copy_relocs_->any_to_emit())
{
Reloc_section* rel_dyn = this->rel_dyn_section(layout);
this->copy_relocs_->emit(rel_dyn);
}
delete this->copy_relocs_;
this->copy_relocs_ = NULL;
}
// Perform a relocation.
inline bool

View File

@ -383,9 +383,11 @@ Layout::find_first_load_seg()
off_t
Layout::finalize(const Input_objects* input_objects, Symbol_table* symtab)
{
const Target* const target = input_objects->target();
Target* const target = input_objects->target();
const int size = target->get_size();
target->finalize_sections(this);
Output_segment* phdr_seg = NULL;
if (input_objects->any_dynamic())
{

57
gold/main.cc Normal file
View File

@ -0,0 +1,57 @@
// main.cc -- gold main function.
#include "gold.h"
#include "options.h"
#include "dirsearch.h"
#include "workqueue.h"
#include "object.h"
#include "symtab.h"
#include "layout.h"
using namespace gold;
int
main(int argc, char** argv)
{
#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
setlocale (LC_MESSAGES, "");
#endif
#if defined (HAVE_SETLOCALE)
setlocale (LC_CTYPE, "");
#endif
bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE);
program_name = argv[0];
// Handle the command line options.
Command_line command_line;
command_line.process(argc - 1, argv + 1);
// The work queue.
Workqueue workqueue(command_line.options());
// The list of input objects.
Input_objects input_objects;
// The symbol table.
Symbol_table symtab;
// The layout object.
Layout layout(command_line.options());
// Get the search path from the -L options.
Dirsearch search_path;
search_path.add(&workqueue, command_line.options().search_path());
// Queue up the first set of tasks.
queue_initial_tasks(command_line.options(), search_path,
command_line, &workqueue, &input_objects,
&symtab, &layout);
// Run the main task processing loop.
workqueue.process();
gold_exit(true);
}

View File

@ -140,22 +140,10 @@ class Object
Sized_target<size, big_endian>*
sized_target(ACCEPT_SIZE_ENDIAN_ONLY);
// Read the symbol information.
void
read_symbols(Read_symbols_data* sd)
{ return this->do_read_symbols(sd); }
// Pass sections which should be included in the link to the Layout
// object, and record where the sections go in the output file.
void
layout(const General_options& options, Symbol_table* symtab,
Layout* layout, Read_symbols_data* sd)
{ this->do_layout(options, symtab, layout, sd); }
// Add symbol information to the global symbol table.
void
add_symbols(Symbol_table* symtab, Read_symbols_data* sd)
{ this->do_add_symbols(symtab, sd); }
// Get the number of sections.
unsigned int
shnum() const
{ return this->shnum_; }
// Return a view of the contents of a section. Set *PLEN to the
// size.
@ -173,6 +161,23 @@ class Object
section_flags(unsigned int shndx)
{ return this->do_section_flags(shndx); }
// Read the symbol information.
void
read_symbols(Read_symbols_data* sd)
{ return this->do_read_symbols(sd); }
// Pass sections which should be included in the link to the Layout
// object, and record where the sections go in the output file.
void
layout(const General_options& options, Symbol_table* symtab,
Layout* layout, Read_symbols_data* sd)
{ this->do_layout(options, symtab, layout, sd); }
// Add symbol information to the global symbol table.
void
add_symbols(Symbol_table* symtab, Read_symbols_data* sd)
{ this->do_add_symbols(symtab, sd); }
// Functions and types for the elfcpp::Elf_file interface. This
// permit us to use Object as the File template parameter for
// elfcpp::Elf_file.
@ -280,11 +285,6 @@ class Object
set_target(int machine, int size, bool big_endian, int osabi,
int abiversion);
// Get the number of sections.
unsigned int
shnum() const
{ return this->shnum_; }
// Set the number of sections.
void
set_shnum(int shnum)
@ -373,17 +373,17 @@ class Relobj : public Object
// Return whether an input section is being included in the link.
bool
is_section_included(unsigned int shnum) const
is_section_included(unsigned int shndx) const
{
gold_assert(shnum < this->map_to_output_.size());
return this->map_to_output_[shnum].output_section != NULL;
gold_assert(shndx < this->map_to_output_.size());
return this->map_to_output_[shndx].output_section != NULL;
}
// Given a section index, return the corresponding Output_section
// (which will be NULL if the section is not included in the link)
// and set *POFF to the offset within that section.
inline Output_section*
output_section(unsigned int shnum, off_t* poff);
output_section(unsigned int shndx, off_t* poff);
// Set the offset of an input section within its output section.
void
@ -437,10 +437,10 @@ class Relobj : public Object
// Implement Object::output_section inline for efficiency.
inline Output_section*
Relobj::output_section(unsigned int shnum, off_t* poff)
Relobj::output_section(unsigned int shndx, off_t* poff)
{
gold_assert(shnum < this->map_to_output_.size());
const Map_to_output& mo(this->map_to_output_[shnum]);
gold_assert(shndx < this->map_to_output_.size());
const Map_to_output& mo(this->map_to_output_[shndx]);
*poff = mo.offset;
return mo.output_section;
}

View File

@ -415,19 +415,19 @@ Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::get_symbol_index()
gold_unreachable();
case GSYM_CODE:
if (this->u_.gsym == NULL)
if (this->u1_.gsym == NULL)
index = 0;
else if (dynamic)
index = this->u_.gsym->dynsym_index();
index = this->u1_.gsym->dynsym_index();
else
index = this->u_.gsym->symtab_index();
index = this->u1_.gsym->symtab_index();
break;
case SECTION_CODE:
if (dynamic)
index = this->u_.os->dynsym_index();
index = this->u1_.os->dynsym_index();
else
index = this->u_.os->symtab_index();
index = this->u1_.os->symtab_index();
break;
default:
@ -439,7 +439,7 @@ Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::get_symbol_index()
gold_unreachable();
}
else
index = this->u_.object->symtab_index(this->local_sym_index_);
index = this->u1_.relobj->symtab_index(this->local_sym_index_);
break;
}
gold_assert(index != -1U);
@ -456,8 +456,16 @@ Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::write_rel(
Write_rel* wr) const
{
Address address = this->address_;
if (this->od_ != NULL)
address += this->od_->address();
if (this->shndx_ != INVALID_CODE)
{
off_t off;
Output_section* os = this->u2_.relobj->output_section(this->shndx_,
&off);
gold_assert(os != NULL);
address += os->address() + off;
}
else if (this->u2_.od != NULL)
address += this->u2_.od->address();
wr->put_r_offset(address);
wr->put_r_info(elfcpp::elf_r_info<size>(this->get_symbol_index(),
this->type_));

View File

@ -323,6 +323,11 @@ class Output_section_data : public Output_data
unsigned int
do_out_shndx() const;
// Set the alignment.
void
set_addralign(uint64_t addralign)
{ this->addralign_ = addralign; }
private:
// The output section for this section.
const Output_section* output_section_;
@ -402,6 +407,11 @@ class Output_data_space : public Output_section_data
set_space_size(off_t space_size)
{ this->set_data_size(space_size); }
// Set the alignment.
void
set_space_alignment(uint64_t align)
{ this->set_addralign(align); }
// Write out the data--this must be handled elsewhere.
void
do_write(Output_file*)
@ -457,30 +467,77 @@ class Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>
{ }
// A reloc against a global symbol.
Output_reloc(Symbol* gsym, unsigned int type, Output_data* od,
Address address)
: local_sym_index_(GSYM_CODE), type_(type), od_(od), address_(address)
{ this->u_.gsym = gsym; }
: address_(address), local_sym_index_(GSYM_CODE), type_(type),
shndx_(INVALID_CODE)
{
this->u1_.gsym = gsym;
this->u2_.od = od;
}
Output_reloc(Symbol* gsym, unsigned int type, Relobj* relobj,
unsigned int shndx, Address address)
: address_(address), local_sym_index_(GSYM_CODE), type_(type),
shndx_(shndx)
{
gold_assert(shndx != INVALID_CODE);
this->u1_.gsym = gsym;
this->u2_.relobj = relobj;
}
// A reloc against a local symbol.
Output_reloc(Sized_relobj<size, big_endian>* object,
Output_reloc(Sized_relobj<size, big_endian>* relobj,
unsigned int local_sym_index,
unsigned int type,
Output_data* od,
Address address)
: local_sym_index_(local_sym_index), type_(type), od_(od),
address_(address)
: address_(address), local_sym_index_(local_sym_index), type_(type),
shndx_(INVALID_CODE)
{
gold_assert(local_sym_index != GSYM_CODE
&& local_sym_index != INVALID_CODE);
this->u_.object = object;
this->u1_.relobj = relobj;
this->u2_.od = od;
}
Output_reloc(Sized_relobj<size, big_endian>* relobj,
unsigned int local_sym_index,
unsigned int type,
unsigned int shndx,
Address address)
: address_(address), local_sym_index_(local_sym_index), type_(type),
shndx_(shndx)
{
gold_assert(local_sym_index != GSYM_CODE
&& local_sym_index != INVALID_CODE);
gold_assert(shndx != INVALID_CODE);
this->u1_.relobj = relobj;
this->u2_.relobj = relobj;
}
// A reloc against the STT_SECTION symbol of an output section.
Output_reloc(Output_section* os, unsigned int type, Output_data* od,
Address address)
: local_sym_index_(SECTION_CODE), type_(type), od_(od), address_(address)
{ this->u_.os = os; }
: address_(address), local_sym_index_(SECTION_CODE), type_(type),
shndx_(INVALID_CODE)
{
this->u1_.os = os;
this->u2_.od = od;
}
Output_reloc(Output_section* os, unsigned int type, Relobj* relobj,
unsigned int shndx, Address address)
: address_(address), local_sym_index_(SECTION_CODE), type_(type),
shndx_(shndx)
{
gold_assert(shndx != INVALID_CODE);
this->u1_.os = os;
this->u2_.relobj = relobj;
}
// Write the reloc entry to an output view.
void
@ -513,24 +570,34 @@ class Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>
// relocation against a local symbol in a dynamic object; that
// doesn't make sense. And our callers will always be
// templatized, so we use Sized_relobj here.
Sized_relobj<size, big_endian>* object;
Sized_relobj<size, big_endian>* relobj;
// For a global symbol, the symbol. If this is NULL, it indicates
// a relocation against the undefined 0 symbol.
Symbol* gsym;
// For a relocation against an output section, the output section.
Output_section* os;
} u_;
} u1_;
union
{
// If shndx_ is not INVALID CODE, the object which holds the input
// section being used to specify the reloc address.
Relobj* relobj;
// If shndx_ is INVALID_CODE, the output data being used to
// specify the reloc address. This may be NULL if the reloc
// address is absolute.
Output_data* od;
} u2_;
// The address offset within the input section or the Output_data.
Address address_;
// For a local symbol, the local symbol index. This is GSYM_CODE
// for a global symbol, or INVALID_CODE for an uninitialized value.
unsigned int local_sym_index_;
// The reloc type--a processor specific code.
unsigned int type_;
// If this is not NULL, then the relocation is against the contents
// of this output data.
Output_data* od_;
// The reloc address--if od_ is not NULL, this is the offset from
// the start of od_.
Address address_;
// If the reloc address is an input section in an object, the
// section index. This is INVALID_CODE if the reloc address is
// specified in some other way.
unsigned int shndx_;
};
// The SHT_RELA version of Output_reloc<>. This is just derived from
@ -549,25 +616,48 @@ class Output_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian>
{ }
// A reloc against a global symbol.
Output_reloc(Symbol* gsym, unsigned int type, Output_data* od,
Address address, Addend addend)
: rel_(gsym, type, od, address), addend_(addend)
{ }
Output_reloc(Symbol* gsym, unsigned int type, Relobj* relobj,
unsigned int shndx, Address address, Addend addend)
: rel_(gsym, type, relobj, shndx, address), addend_(addend)
{ }
// A reloc against a local symbol.
Output_reloc(Sized_relobj<size, big_endian>* object,
Output_reloc(Sized_relobj<size, big_endian>* relobj,
unsigned int local_sym_index,
unsigned int type, Output_data* od, Address address,
Addend addend)
: rel_(object, local_sym_index, type, od, address), addend_(addend)
: rel_(relobj, local_sym_index, type, od, address), addend_(addend)
{ }
Output_reloc(Sized_relobj<size, big_endian>* relobj,
unsigned int local_sym_index,
unsigned int type,
unsigned int shndx,
Address address,
Addend addend)
: rel_(relobj, local_sym_index, type, shndx, address),
addend_(addend)
{ }
// A reloc against the STT_SECTION symbol of an output section.
Output_reloc(Output_section* os, unsigned int type, Output_data* od,
Address address, Addend addend)
: rel_(os, type, od, address), addend_(addend)
{ }
Output_reloc(Output_section* os, unsigned int type, Relobj* relobj,
unsigned int shndx, Address address, Addend addend)
: rel_(os, type, relobj, shndx, address), addend_(addend)
{ }
// Write the reloc entry to an output view.
void
write(unsigned char* pov) const;
@ -643,22 +733,43 @@ class Output_data_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>
{ }
// Add a reloc against a global symbol.
void
add_global(Symbol* gsym, unsigned int type, Output_data* od, Address address)
{ this->add(Output_reloc_type(gsym, type, od, address)); }
// Add a reloc against a local symbol.
void
add_local(Sized_relobj<size, big_endian>* object,
add_global(Symbol* gsym, unsigned int type, Relobj* relobj,
unsigned int shndx, Address address)
{ this->add(Output_reloc_type(gsym, type, relobj, shndx, address)); }
// Add a reloc against a local symbol.
void
add_local(Sized_relobj<size, big_endian>* relobj,
unsigned int local_sym_index, unsigned int type,
Output_data* od, Address address)
{ this->add(Output_reloc_type(object, local_sym_index, type, od, address)); }
{ this->add(Output_reloc_type(relobj, local_sym_index, type, od, address)); }
void
add_local(Sized_relobj<size, big_endian>* relobj,
unsigned int local_sym_index, unsigned int type,
unsigned int shndx, Address address)
{ this->add(Output_reloc_type(relobj, local_sym_index, type, shndx,
address)); }
// A reloc against the STT_SECTION symbol of an output section.
void
add_output_section(Output_section* os, unsigned int type,
Output_data* od, Address address)
{ this->add(Output_reloc_type(os, type, od, address)); }
void
add_output_section(Output_section* os, unsigned int type,
Relobj* relobj, unsigned int shndx, Address address)
{ this->add(Output_reloc_type(os, type, relobj, shndx, address)); }
};
// The SHT_RELA version of Output_data_reloc.
@ -681,26 +792,48 @@ class Output_data_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian>
{ }
// Add a reloc against a global symbol.
void
add_global(Symbol* gsym, unsigned int type, Output_data* od,
Address address, Addend addend)
{ this->add(Output_reloc_type(gsym, type, od, address, addend)); }
// Add a reloc against a local symbol.
void
add_local(Sized_relobj<size, big_endian>* object,
add_global(Symbol* gsym, unsigned int type, Relobj* relobj,
unsigned int shndx, Address address, Addend addend)
{ this->add(Output_reloc_type(gsym, type, relobj, shndx, address, addend)); }
// Add a reloc against a local symbol.
void
add_local(Sized_relobj<size, big_endian>* relobj,
unsigned int local_sym_index, unsigned int type,
Output_data* od, Address address, Addend addend)
{
this->add(Output_reloc_type(object, local_sym_index, type, od, address,
this->add(Output_reloc_type(relobj, local_sym_index, type, od, address,
addend));
}
void
add_local(Sized_relobj<size, big_endian>* relobj,
unsigned int local_sym_index, unsigned int type,
unsigned int shndx, Address address, Addend addend)
{
this->add(Output_reloc_type(relobj, local_sym_index, type, shndx, address,
addend));
}
// A reloc against the STT_SECTION symbol of an output section.
void
add_output_section(Output_section* os, unsigned int type, Output_data* od,
Address address, Addend addend)
{ this->add(Output_reloc_type(os, type, od, address, addend)); }
void
add_output_section(Output_section* os, unsigned int type, Relobj* relobj,
unsigned int shndx, Address address, Addend addend)
{ this->add(Output_reloc_type(os, type, relobj, shndx, address, addend)); }
};
// Output_data_got is used to manage a GOT. Each entry in the GOT is

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2006-11-29 09:53-0800\n"
"POT-Creation-Date: 2006-11-30 15:37-0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -161,27 +161,27 @@ msgstr ""
msgid "%s: warning: close(%s) failed: %s"
msgstr ""
#: fileread.cc:128
#: fileread.cc:143
#, c-format
msgid "%s: %s: lseek to %lld failed: %s"
msgstr ""
#: fileread.cc:138
#: fileread.cc:153
#, c-format
msgid "%s: %s: read failed: %s\n"
msgstr ""
#: fileread.cc:148 fileread.cc:231
#: fileread.cc:173 fileread.cc:256
#, c-format
msgid "%s: %s: file too short: read only %lld of %lld bytes at %lld\n"
msgstr ""
#: fileread.cc:326
#: fileread.cc:365
#, c-format
msgid "%s: cannot find %s\n"
msgstr ""
#: fileread.cc:334
#: fileread.cc:373
#, c-format
msgid "%s: cannot open %s: %s\n"
msgstr ""
@ -235,57 +235,57 @@ msgid "pthread_cond_signal failed"
msgstr ""
#. FIXME: This needs to specify the location somehow.
#: i386.cc:93
#: i386.cc:100
#, c-format
msgid "%s: missing expected TLS relocation\n"
msgstr ""
#: i386.cc:617 i386.cc:757 i386.cc:961
#: i386.cc:702 i386.cc:843 i386.cc:1064
#, c-format
msgid "%s: %s: unexpected reloc %u in object file\n"
msgstr ""
#: i386.cc:653 i386.cc:672
#: i386.cc:738 i386.cc:757
#, c-format
msgid "%s: %s: unsupported reloc %u against local symbol\n"
msgstr ""
#: i386.cc:793 i386.cc:814
#: i386.cc:879 i386.cc:900
#, c-format
msgid "%s: %s: unsupported reloc %u against global symbol %s\n"
msgstr ""
#: i386.cc:837
#: i386.cc:923
#, c-format
msgid "%s: %s: unsupported RELA reloc section\n"
msgstr ""
#: i386.cc:877
#: i386.cc:980
#, c-format
msgid "%s: %s: missing expected TLS relocation\n"
msgstr ""
#: i386.cc:993 i386.cc:1068 i386.cc:1079
#: i386.cc:1096 i386.cc:1171 i386.cc:1182
#, c-format
msgid "%s: %s: unsupported reloc %u\n"
msgstr ""
#: i386.cc:1020
#: i386.cc:1123
#, c-format
msgid "%s: %s: TLS reloc but no TLS segment\n"
msgstr ""
#: i386.cc:1053
#: i386.cc:1156
#, c-format
msgid "%s: %s: unsupported reloc type %u\n"
msgstr ""
#: i386.cc:1262
#: i386.cc:1365
#, c-format
msgid "%s: %s: TLS relocation out of range\n"
msgstr ""
#: i386.cc:1280
#: i386.cc:1383
#, c-format
msgid "%s: %s: TLS relocation against invalid instruction\n"
msgstr ""
@ -496,37 +496,37 @@ msgstr ""
msgid "%s: -%c: %s\n"
msgstr ""
#: output.cc:809
#: output.cc:817
#, c-format
msgid "%s: %s: invalid alignment %lu for section \"%s\"\n"
msgstr ""
#: output.cc:1308
#: output.cc:1316
#, c-format
msgid "%s: %s: open: %s\n"
msgstr ""
#: output.cc:1317
#: output.cc:1325
#, c-format
msgid "%s: %s: lseek: %s\n"
msgstr ""
#: output.cc:1324
#: output.cc:1332
#, c-format
msgid "%s: %s: write: %s\n"
msgstr ""
#: output.cc:1334
#: output.cc:1342
#, c-format
msgid "%s: %s: mmap: %s\n"
msgstr ""
#: output.cc:1348
#: output.cc:1356
#, c-format
msgid "%s: %s: munmap: %s\n"
msgstr ""
#: output.cc:1356
#: output.cc:1364
#, c-format
msgid "%s: %s: close: %s\n"
msgstr ""
@ -547,22 +547,22 @@ msgstr ""
msgid "%s: %s: not an object or archive\n"
msgstr ""
#: reloc.cc:168 reloc.cc:409
#: reloc.cc:169 reloc.cc:410
#, c-format
msgid "%s: %s: relocation section %u has bad info %u\n"
msgstr ""
#: reloc.cc:187 reloc.cc:426
#: reloc.cc:188 reloc.cc:427
#, c-format
msgid "%s: %s: relocation section %u uses unexpected symbol table %u\n"
msgstr ""
#: reloc.cc:203 reloc.cc:445
#: reloc.cc:204 reloc.cc:446
#, c-format
msgid "%s: %s: unexpected entsize for reloc section %u: %lu != %u"
msgstr ""
#: reloc.cc:214 reloc.cc:456
#: reloc.cc:215 reloc.cc:457
#, c-format
msgid "%s: %s: reloc section %u size %lu uneven"
msgstr ""

View File

@ -61,7 +61,7 @@ Read_symbols::run(Workqueue* workqueue)
return;
}
Input_file* input_file = new Input_file(this->input_argument_->file());
Input_file* input_file = new Input_file(&this->input_argument_->file());
input_file->open(this->options_, this->dirpath_);
// Read enough of the file to pick up the entire ELF header.

View File

@ -4,6 +4,7 @@
#include "workqueue.h"
#include "object.h"
#include "symtab.h"
#include "output.h"
#include "reloc.h"
@ -471,21 +472,64 @@ Sized_relobj<size, big_endian>::relocate_sections(
}
}
// Relocate_functions functions.
// Copy_relocs::Copy_reloc_entry methods.
// Return whether we should emit this reloc. We should emit it if the
// symbol is still defined in a dynamic object. If we should not emit
// it, we clear it, to save ourselves the test next time.
template<int size, bool big_endian>
bool
Copy_relocs<size, big_endian>::Copy_reloc_entry::should_emit()
{
if (this->sym_ == NULL)
return false;
if (this->sym_->is_defined_in_dynobj())
return true;
this->sym_ = NULL;
return false;
}
// Emit a reloc into a SHT_REL section.
template<int size, bool big_endian>
void
Copy_relocs<size, big_endian>::Copy_reloc_entry::emit(
Output_data_reloc<elfcpp::SHT_REL, true, size, big_endian>* reloc_data)
{
reloc_data->add_global(this->sym_, this->reloc_type_, this->relobj_,
this->shndx_, this->address_);
}
// Emit a reloc into a SHT_RELA section.
template<int size, bool big_endian>
void
Copy_relocs<size, big_endian>::Copy_reloc_entry::emit(
Output_data_reloc<elfcpp::SHT_RELA, true, size, big_endian>* reloc_data)
{
reloc_data->add_global(this->sym_, this->reloc_type_, this->relobj_,
this->shndx_, this->address_, this->addend_);
}
// Copy_relocs methods.
// Return whether we need a COPY reloc for a relocation against GSYM.
// The relocation is being applied to section SHNDX in OBJECT.
template<int size, bool big_endian>
bool
Relocate_functions<size, big_endian>::need_copy_reloc(
Copy_relocs<size, big_endian>::need_copy_reloc(
const General_options*,
Relobj* object,
unsigned int shndx,
Symbol*)
Sized_symbol<size>* sym)
{
// FIXME: Handle -z nocopyrelocs.
if (sym->symsize() == 0)
return false;
// If this is a readonly section, then we need a COPY reloc.
// Otherwise we can use a dynamic reloc.
if ((object->section_flags(shndx) & elfcpp::SHF_WRITE) == 0)
@ -494,6 +538,71 @@ Relocate_functions<size, big_endian>::need_copy_reloc(
return false;
}
// Save a Rel reloc.
template<int size, bool big_endian>
void
Copy_relocs<size, big_endian>::save(
Symbol* sym,
Relobj* relobj,
unsigned int shndx,
const elfcpp::Rel<size, big_endian>& rel)
{
unsigned int reloc_type = elfcpp::elf_r_type<size>(rel.get_r_info());
this->entries_.push_back(Copy_reloc_entry(sym, reloc_type, relobj, shndx,
rel.get_r_offset(), 0));
}
// Save a Rela reloc.
template<int size, bool big_endian>
void
Copy_relocs<size, big_endian>::save(
Symbol* sym,
Relobj* relobj,
unsigned int shndx,
const elfcpp::Rela<size, big_endian>& rela)
{
unsigned int reloc_type = elfcpp::elf_r_type<size>(rela.get_r_info());
this->entries_.push_back(Copy_reloc_entry(sym, reloc_type, relobj, shndx,
rela.get_r_offset(),
rela.get_r_addend()));
}
// Return whether there are any relocs to emit. We don't want to emit
// a reloc if the symbol is no longer defined in a dynamic object.
template<int size, bool big_endian>
bool
Copy_relocs<size, big_endian>::any_to_emit()
{
for (typename Copy_reloc_entries::iterator p = this->entries_.begin();
p != this->entries_.end();
++p)
{
if (p->should_emit())
return true;
}
return false;
}
// Emit relocs.
template<int size, bool big_endian>
template<int sh_type>
void
Copy_relocs<size, big_endian>::emit(
Output_data_reloc<sh_type, true, size, big_endian>* reloc_data)
{
for (typename Copy_reloc_entries::iterator p = this->entries_.begin();
p != this->entries_.end();
++p)
{
if (p->should_emit())
p->emit(reloc_data);
}
}
// Instantiate the templates we need. We could use the configure
// script to restrict this to only the ones for implemented targets.
@ -570,27 +679,55 @@ Sized_relobj<64, true>::do_relocate(const General_options& options,
Output_file* of);
template
bool
Relocate_functions<32, false>::need_copy_reloc(const General_options*,
Relobj*, unsigned int,
Symbol*);
class Copy_relocs<32, false>;
template
bool
Relocate_functions<32, true>::need_copy_reloc(const General_options*,
Relobj*, unsigned int,
Symbol*);
class Copy_relocs<32, true>;
template
bool
Relocate_functions<64, false>::need_copy_reloc(const General_options*,
Relobj*, unsigned int,
Symbol*);
class Copy_relocs<64, false>;
template
bool
Relocate_functions<64, true>::need_copy_reloc(const General_options*,
Relobj*, unsigned int,
Symbol*);
class Copy_relocs<64, true>;
template
void
Copy_relocs<32, false>::emit<elfcpp::SHT_REL>(
Output_data_reloc<elfcpp::SHT_REL, true, 32, false>*);
template
void
Copy_relocs<32, true>::emit<elfcpp::SHT_REL>(
Output_data_reloc<elfcpp::SHT_REL, true, 32, true>*);
template
void
Copy_relocs<64, false>::emit<elfcpp::SHT_REL>(
Output_data_reloc<elfcpp::SHT_REL, true, 64, false>*);
template
void
Copy_relocs<64, true>::emit<elfcpp::SHT_REL>(
Output_data_reloc<elfcpp::SHT_REL, true, 64, true>*);
template
void
Copy_relocs<32, false>::emit<elfcpp::SHT_RELA>(
Output_data_reloc<elfcpp::SHT_RELA , true, 32, false>*);
template
void
Copy_relocs<32, true>::emit<elfcpp::SHT_RELA>(
Output_data_reloc<elfcpp::SHT_RELA, true, 32, true>*);
template
void
Copy_relocs<64, false>::emit<elfcpp::SHT_RELA>(
Output_data_reloc<elfcpp::SHT_RELA, true, 64, false>*);
template
void
Copy_relocs<64, true>::emit<elfcpp::SHT_RELA>(
Output_data_reloc<elfcpp::SHT_RELA, true, 64, true>*);
} // End namespace gold.

View File

@ -17,6 +17,12 @@ class Stringpool;
class Symbol;
class Layout;
template<int size>
class Sized_symbol;
template<int sh_type, bool dynamic, int size, bool big_endian>
class Output_data_reloc;
// A class to read the relocations for an object file, and then queue
// up a task to see if they require any GOT/PLT/COPY relocations in
// the symbol table.
@ -229,12 +235,99 @@ public:
{
This::template pcrel<64>(view, value, address);
}
};
// We try to avoid COPY relocations when possible. A COPY relocation
// may be required when an executable refers to a variable defined in
// a shared library. COPY relocations are problematic because they
// tie the executable to the exact size of the variable in the shared
// library. We can avoid them if all the references to the variable
// are in a writeable section. In that case we can simply use dynamic
// relocations. However, when scanning relocs, we don't know when we
// see the relocation whether we will be forced to use a COPY
// relocation or not. So we have to save the relocation during the
// reloc scanning, and then emit it as a dynamic relocation if
// necessary. This class implements that. It is used by the target
// specific code.
template<int size, bool big_endian>
class Copy_relocs
{
public:
Copy_relocs()
: entries_()
{ }
// Return whether we need a COPY reloc for a reloc against GSYM,
// which is being applied to section SHNDX in OBJECT.
static bool
need_copy_reloc(const General_options*, Relobj* object, unsigned int shndx,
Symbol* gsym);
Sized_symbol<size>* gsym);
// Save a Rel against SYM for possible emission later. SHNDX is the
// index of the section to which the reloc is being applied.
void
save(Symbol* sym, Relobj*, unsigned int shndx,
const elfcpp::Rel<size, big_endian>&);
// Save a Rela against SYM for possible emission later.
void
save(Symbol* sym, Relobj*, unsigned int shndx,
const elfcpp::Rela<size, big_endian>&);
// Return whether there are any relocs to emit. This also discards
// entries which need not be emitted.
bool
any_to_emit();
// Emit relocs for each symbol which did not get a COPY reloc (i.e.,
// is still defined in the dynamic object).
template<int sh_type>
void
emit(Output_data_reloc<sh_type, true, size, big_endian>*);
private:
typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
typedef typename elfcpp::Elf_types<size>::Elf_Addr Addend;
// This POD class holds the entries we are saving.
class Copy_reloc_entry
{
public:
Copy_reloc_entry(Symbol* sym, unsigned int reloc_type,
Relobj* relobj, unsigned int shndx,
Address address, Addend addend)
: sym_(sym), reloc_type_(reloc_type), relobj_(relobj),
shndx_(shndx), address_(address), addend_(addend)
{ }
// Return whether we should emit this reloc. If we should not
// emit, we clear it.
bool
should_emit();
// Emit this reloc.
void
emit(Output_data_reloc<elfcpp::SHT_REL, true, size, big_endian>*);
void
emit(Output_data_reloc<elfcpp::SHT_RELA, true, size, big_endian>*);
private:
Symbol* sym_;
unsigned int reloc_type_;
Relobj* relobj_;
unsigned int shndx_;
Address address_;
Addend addend_;
};
// A list of relocs to be saved.
typedef std::vector<Copy_reloc_entry> Copy_reloc_entries;
// The list of relocs we are saving.
Copy_reloc_entries entries_;
};
} // End namespace gold.

View File

@ -83,6 +83,12 @@ class Target
common_pagesize() const
{ return this->pti_->common_pagesize; }
// This is called to tell the target to complete any sections it is
// handling. After this all sections must have their final size.
void
finalize_sections(Layout* layout)
{ return this->do_finalize_sections(layout); }
protected:
// This struct holds the constant information for a child class. We
// use a struct to avoid the overhead of virtual function calls for
@ -113,6 +119,11 @@ class Target
: pti_(pti)
{ }
// Virtual function which may be implemented by the child class.
virtual void
do_finalize_sections(Layout*)
{ }
private:
Target(const Target&);
Target& operator=(const Target&);

View File

@ -0,0 +1,22 @@
# Process this file with automake to generate Makefile.in
AUTOMAKE_OPTIONS =
AM_CXXFLAGS = $(WARN_CXXFLAGS) $(LFS_CXXFLAGS)
INCLUDES = -D_GNU_SOURCE \
-I$(srcdir) -I$(srcdir)/.. -I$(srcdir)/../../include \
-I$(srcdir)/../../elfcpp \
-DLOCALEDIR="\"$(datadir)/locale\"" \
@INCINTL@
TESTS = object_unittest
check_LIBRARIES = libgoldtest.a
libgoldtest_a_SOURCES = test.cc testmain.cc testfile.cc
LDADD = libgoldtest.a ../libgold.a
check_PROGRAMS = object_unittest
object_unittest_SOURCES = object_unittest.cc

521
gold/testsuite/Makefile.in Normal file
View File

@ -0,0 +1,521 @@
# Makefile.in generated by automake 1.9.6 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
# Process this file with automake to generate Makefile.in
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
target_triplet = @target@
check_PROGRAMS = object_unittest$(EXEEXT)
subdir = testsuite
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/../config/depstand.m4 \
$(top_srcdir)/../config/lead-dot.m4 \
$(top_srcdir)/../config/progtest.m4 \
$(top_srcdir)/../config/po.m4 $(top_srcdir)/../config/nls.m4 \
$(top_srcdir)/../config/gettext-sister.m4 \
$(top_srcdir)/../bfd/warning.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
AR = ar
ARFLAGS = cru
libgoldtest_a_AR = $(AR) $(ARFLAGS)
libgoldtest_a_LIBADD =
am_libgoldtest_a_OBJECTS = test.$(OBJEXT) testmain.$(OBJEXT) \
testfile.$(OBJEXT)
libgoldtest_a_OBJECTS = $(am_libgoldtest_a_OBJECTS)
am_object_unittest_OBJECTS = object_unittest.$(OBJEXT)
object_unittest_OBJECTS = $(am_object_unittest_OBJECTS)
object_unittest_LDADD = $(LDADD)
object_unittest_DEPENDENCIES = libgoldtest.a ../libgold.a
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/../depcomp
am__depfiles_maybe = depfiles
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
CXXLD = $(CXX)
CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \
-o $@
SOURCES = $(libgoldtest_a_SOURCES) $(object_unittest_SOURCES)
DIST_SOURCES = $(libgoldtest_a_SOURCES) $(object_unittest_SOURCES)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
AMTAR = @AMTAR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CATALOGS = @CATALOGS@
CATOBJEXT = @CATOBJEXT@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DATADIRNAME = @DATADIRNAME@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
GENCAT = @GENCAT@
GMSGFMT = @GMSGFMT@
INCINTL = @INCINTL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
INSTOBJEXT = @INSTOBJEXT@
LDFLAGS = @LDFLAGS@
LFS_CXXFLAGS = @LFS_CXXFLAGS@
LIBINTL = @LIBINTL@
LIBINTL_DEP = @LIBINTL_DEP@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
MAKEINFO = @MAKEINFO@
MKINSTALLDIRS = @MKINSTALLDIRS@
MSGFMT = @MSGFMT@
MSGMERGE = @MSGMERGE@
NO_WERROR = @NO_WERROR@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
POSUB = @POSUB@
RANLIB = @RANLIB@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
USE_NLS = @USE_NLS@
VERSION = @VERSION@
WARN_CFLAGS = @WARN_CFLAGS@
WARN_CXXFLAGS = @WARN_CXXFLAGS@
XGETTEXT = @XGETTEXT@
YACC = @YACC@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_RANLIB = @ac_ct_RANLIB@
ac_ct_STRIP = @ac_ct_STRIP@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
datadir = @datadir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
prefix = @prefix@
program_transform_name = @program_transform_name@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target = @target@
target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
AUTOMAKE_OPTIONS =
AM_CXXFLAGS = $(WARN_CXXFLAGS) $(LFS_CXXFLAGS)
INCLUDES = -D_GNU_SOURCE \
-I$(srcdir) -I$(srcdir)/.. -I$(srcdir)/../../include \
-I$(srcdir)/../../elfcpp \
-DLOCALEDIR="\"$(datadir)/locale\"" \
@INCINTL@
TESTS = object_unittest
check_LIBRARIES = libgoldtest.a
libgoldtest_a_SOURCES = test.cc testmain.cc testfile.cc
LDADD = libgoldtest.a ../libgold.a
object_unittest_SOURCES = object_unittest.cc
all: all-am
.SUFFIXES:
.SUFFIXES: .cc .o .obj
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign testsuite/Makefile'; \
cd $(top_srcdir) && \
$(AUTOMAKE) --foreign testsuite/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
clean-checkLIBRARIES:
-test -z "$(check_LIBRARIES)" || rm -f $(check_LIBRARIES)
libgoldtest.a: $(libgoldtest_a_OBJECTS) $(libgoldtest_a_DEPENDENCIES)
-rm -f libgoldtest.a
$(libgoldtest_a_AR) libgoldtest.a $(libgoldtest_a_OBJECTS) $(libgoldtest_a_LIBADD)
$(RANLIB) libgoldtest.a
clean-checkPROGRAMS:
-test -z "$(check_PROGRAMS)" || rm -f $(check_PROGRAMS)
object_unittest$(EXEEXT): $(object_unittest_OBJECTS) $(object_unittest_DEPENDENCIES)
@rm -f object_unittest$(EXEEXT)
$(CXXLINK) $(object_unittest_LDFLAGS) $(object_unittest_OBJECTS) $(object_unittest_LDADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/object_unittest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testfile.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testmain.Po@am__quote@
.cc.o:
@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $<
.cc.obj:
@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
uninstall-info-am:
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
mkid -fID $$unique
tags: TAGS
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique; \
fi
ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(CTAGS_ARGS)$$tags$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$tags $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& cd $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) $$here
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
check-TESTS: $(TESTS)
@failed=0; all=0; xfail=0; xpass=0; skip=0; \
srcdir=$(srcdir); export srcdir; \
list='$(TESTS)'; \
if test -n "$$list"; then \
for tst in $$list; do \
if test -f ./$$tst; then dir=./; \
elif test -f $$tst; then dir=; \
else dir="$(srcdir)/"; fi; \
if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \
all=`expr $$all + 1`; \
case " $(XFAIL_TESTS) " in \
*" $$tst "*) \
xpass=`expr $$xpass + 1`; \
failed=`expr $$failed + 1`; \
echo "XPASS: $$tst"; \
;; \
*) \
echo "PASS: $$tst"; \
;; \
esac; \
elif test $$? -ne 77; then \
all=`expr $$all + 1`; \
case " $(XFAIL_TESTS) " in \
*" $$tst "*) \
xfail=`expr $$xfail + 1`; \
echo "XFAIL: $$tst"; \
;; \
*) \
failed=`expr $$failed + 1`; \
echo "FAIL: $$tst"; \
;; \
esac; \
else \
skip=`expr $$skip + 1`; \
echo "SKIP: $$tst"; \
fi; \
done; \
if test "$$failed" -eq 0; then \
if test "$$xfail" -eq 0; then \
banner="All $$all tests passed"; \
else \
banner="All $$all tests behaved as expected ($$xfail expected failures)"; \
fi; \
else \
if test "$$xpass" -eq 0; then \
banner="$$failed of $$all tests failed"; \
else \
banner="$$failed of $$all tests did not behave as expected ($$xpass unexpected passes)"; \
fi; \
fi; \
dashes="$$banner"; \
skipped=""; \
if test "$$skip" -ne 0; then \
skipped="($$skip tests were not run)"; \
test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \
dashes="$$skipped"; \
fi; \
report=""; \
if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \
report="Please report to $(PACKAGE_BUGREPORT)"; \
test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \
dashes="$$report"; \
fi; \
dashes=`echo "$$dashes" | sed s/./=/g`; \
echo "$$dashes"; \
echo "$$banner"; \
test -z "$$skipped" || echo "$$skipped"; \
test -z "$$report" || echo "$$report"; \
echo "$$dashes"; \
test "$$failed" -eq 0; \
else :; fi
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkdir_p) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
check-am: all-am
$(MAKE) $(AM_MAKEFLAGS) $(check_LIBRARIES) $(check_PROGRAMS)
$(MAKE) $(AM_MAKEFLAGS) check-TESTS
check: check-am
all-am: Makefile
installdirs:
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-checkLIBRARIES clean-checkPROGRAMS clean-generic \
mostlyclean-am
distclean: distclean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
info: info-am
info-am:
install-data-am:
install-exec-am:
install-info: install-info-am
install-man:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-info-am
.PHONY: CTAGS GTAGS all all-am check check-TESTS check-am clean \
clean-checkLIBRARIES clean-checkPROGRAMS clean-generic ctags \
distclean distclean-compile distclean-generic distclean-tags \
distdir dvi dvi-am html html-am info info-am install \
install-am install-data install-data-am install-exec \
install-exec-am install-info install-info-am install-man \
install-strip installcheck installcheck-am installdirs \
maintainer-clean maintainer-clean-generic mostlyclean \
mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \
tags uninstall uninstall-am uninstall-info-am
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

View File

@ -0,0 +1,41 @@
// object_unittest.cc -- test Object, Relobj, etc.
#include "gold.h"
#include "object.h"
#include "test.h"
#include "testfile.h"
namespace gold_testsuite
{
using namespace gold;
// Test basic Object functionality.
bool
Object_test(Test_report*)
{
Input_file input_file("test.o", test_file_1, test_file_1_size);
Object* object = make_elf_object("test.o", &input_file, 0,
test_file_1, test_file_1_size);
CHECK(object->name() == "test.o");
CHECK(!object->is_dynamic());
CHECK(object->target() == target_test_pointer);
CHECK(object->is_locked());
object->unlock();
CHECK(!object->is_locked());
object->lock();
CHECK(object->shnum() == 5);
CHECK(object->section_name(0).empty());
CHECK(object->section_name(1) == ".test");
CHECK(object->section_flags(0) == 0);
CHECK(object->section_flags(1) == elfcpp::SHF_ALLOC);
object->unlock();
return true;
}
Register_test object_register("Object", Object_test);
} // End namespace gold_testsuite.

78
gold/testsuite/test.cc Normal file
View File

@ -0,0 +1,78 @@
// test.cc -- simplistic test framework for gold.
#include "gold.h"
#include <cstdio>
#include "test.h"
namespace gold_testsuite
{
// Test_framework methods.
// The current test being run.
Test_report* Test_framework::current_report;
// Run a test.
void
Test_framework::run(const char *name, bool (*pfn)(Test_report*))
{
this->testname_ = name;
this->current_fail_ = false;
Test_report tr(this);
Test_framework::current_report = &tr;
if ((*pfn)(&tr) && !this->current_fail_)
{
printf("PASS: %s\n", name);
++this->passes_;
}
else
{
printf("FAIL: %s\n", name);
++this->failures_;
}
Test_framework::current_report = NULL;
this->testname_ = NULL;
}
// Let a test report an error.
void
Test_framework::error(const char* message)
{
printf("ERROR: %s: %s\n", this->testname_, message);
this->fail();
}
// Register_test methods.
// Linked list of all registered tests.
Register_test* Register_test::all_tests;
// Register a test.
Register_test::Register_test(const char* name, bool (*pfn)(Test_report*))
: name_(name), pfn_(pfn), next_(Register_test::all_tests)
{
Register_test::all_tests = this;
}
// Run all registered tests.
void
Register_test::run_tests(Test_framework* tf)
{
for (Register_test* p = Register_test::all_tests;
p != NULL;
p = p->next_)
tf->run(p->name_, p->pfn_);
}
} // End namespace gold_testsuite.

121
gold/testsuite/test.h Normal file
View File

@ -0,0 +1,121 @@
// test.h -- simplistic test framework for gold unittests -*- C++ -*-
#ifndef GOLD_TESTSUITE_TEST_H
#define GOLD_TESTSUITE_TEST_H
namespace gold_testsuite
{
class Test_report;
// This class handles basic test framework functionality.
class Test_framework
{
public:
Test_framework()
: testname_(NULL), current_fail_(0), passes_(0), failures_(0)
{ }
// Return number of failures.
unsigned int
failures() const
{ return this->failures_; }
// Run a test.
void
run(const char* name, bool (*pfn)(Test_report*));
// Get the current Test_report. This is used by the test support
// macros.
static Test_report*
report()
{ return Test_framework::current_report; }
private:
friend class Test_report;
// Cause the current test to fail.
void
fail()
{ ++this->current_fail_ = true; }
// Report an error from the current test.
void
error(const char* message);
// Current Test_report. This is a static variable valid while a
// test is being run.
static Test_report* current_report;
// Current test being run.
const char* testname_;
// Whether the current test is failing.
bool current_fail_;
// Total number of passeed tests.
unsigned int passes_;
// Total number of failed tests.
unsigned int failures_;
};
// An instance of this class is passed to each test function.
class Test_report
{
public:
Test_report(Test_framework* tf)
: tf_(tf)
{ }
// Mark the test as failing.
void
fail()
{ this->tf_->fail(); }
// Report an error.
void
error(const char* message)
{ this->tf_->error(message); }
private:
Test_framework* tf_;
};
// This class registers a test function so that the testsuite runs it.
class Register_test
{
public:
Register_test(const char* name, bool (*pfn)(Test_report*));
// Run all registered tests.
static void
run_tests(Test_framework*);
private:
// Linked list of all tests.
static Register_test* all_tests;
// Test name.
const char* name_;
// Function to call. It should return true if the test passes,
// false if it fails.
bool (*pfn_)(Test_report*);
// Next test in linked list.
Register_test* next_;
};
} // End namespace gold_testsuite.
// These macros are for convenient use in tests.
// Check that a condition is true. If it is false, report a failure.
#define CHECK(cond) \
((cond) ? 0 : (::gold_testsuite::Test_framework::report()->fail(), 0))
// Report an error during a test.
#define ERROR(msg) (::gold_testsuite::Test_framework::report()->error(msg))
#endif // !defined(GOLD_TESTSUITE_TEST_H)

261
gold/testsuite/testfile.cc Normal file
View File

@ -0,0 +1,261 @@
// testfile.cc -- Dummy ELF objects for testing purposes.
#include "gold.h"
#include "target.h"
#include "target-select.h"
#include "test.h"
#include "testfile.h"
namespace gold_testsuite
{
using namespace gold;
// A Target used for testing purposes.
class Target_test : public Sized_target<32, false>
{
public:
Target_test()
: Sized_target<32, false>(&test_target_info)
{ }
void
scan_relocs(const General_options&, Symbol_table*, Layout*,
Sized_relobj<32, false>*, unsigned int, unsigned int,
const unsigned char*, size_t, size_t, const unsigned char*,
Symbol**)
{ ERROR("call to Target_test::scan_relocs"); }
void
relocate_section(const Relocate_info<32, false>*, unsigned int,
const unsigned char*, size_t, unsigned char*,
elfcpp::Elf_types<32>::Elf_Addr, off_t)
{ ERROR("call to Target_test::relocate_section"); }
static const Target::Target_info test_target_info;
};
const Target::Target_info Target_test::test_target_info =
{
32, // size
false, // is_big_endian
static_cast<elfcpp::EM>(0xffff), // machine_code
false, // has_make_symbol
false, // has_resolve
"/dummy", // dynamic_linker
0x08000000, // text_segment_address
0x1000, // abi_pagesize
0x1000 // common_pagesize
};
// The single test target.
Target_test target_test;
// A pointer to the test target. This is used in CHECKs.
Target* target_test_pointer = &target_test;
// Select the test target.
class Target_selector_test : public Target_selector
{
public:
Target_selector_test()
: Target_selector(0xffff, 32, false)
{ }
Target*
recognize(int, int, int)
{ return &target_test; }
};
// Register the test target selector.
Target_selector_test target_selector_test;
// A simple ELF object with one empty section, named ".test" and one
// globally visible symbol named "test".
const unsigned char test_file_1[] =
{
// Ehdr
// EI_MAG[0-3]
0x7f, 'E', 'L', 'F',
// EI_CLASS: 32 bit.
1,
// EI_DATA: little endian
1,
// EI_VERSION
1,
// EI_OSABI
0,
// EI_ABIVERSION
0,
// EI_PAD
0, 0, 0, 0, 0, 0, 0,
// e_type: ET_REL
1, 0,
// e_machine: a magic value used for testing.
0xff, 0xff,
// e_version
1, 0, 0, 0,
// e_entry
0, 0, 0, 0,
// e_phoff
0, 0, 0, 0,
// e_shoff: starts right after file header
52, 0, 0, 0,
// e_flags
0, 0, 0, 0,
// e_ehsize
52, 0,
// e_phentsize
32, 0,
// e_phnum
0, 0,
// e_shentsize
40, 0,
// e_shnum: dummy, .test, .symtab, .strtab, .shstrtab
5, 0,
// e_shstrndx
4, 0,
// Offset 52
// Shdr 0: dummy entry
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
// Offset 92
// Shdr 1: .test
// sh_name: after initial null
1, 0, 0, 0,
// sh_type: SHT_PROGBITS
1, 0, 0, 0,
// sh_flags: SHF_ALLOC
2, 0, 0, 0,
// sh_addr
0, 0, 0, 0,
// sh_offset: after file header + 5 section headers
252, 0, 0, 0,
// sh_size
0, 0, 0, 0,
// sh_link
0, 0, 0, 0,
// sh_info
0, 0, 0, 0,
// sh_addralign
1, 0, 0, 0,
// sh_entsize
0, 0, 0, 0,
// Offset 132
// Shdr 2: .symtab
// sh_name: 1 null byte + ".test\0"
7, 0, 0, 0,
// sh_type: SHT_SYMTAB
2, 0, 0, 0,
// sh_flags
0, 0, 0, 0,
// sh_addr
0, 0, 0, 0,
// sh_offset: after file header + 5 section headers + empty section
252, 0, 0, 0,
// sh_size: two symbols: dummy symbol + test symbol
32, 0, 0, 0,
// sh_link: to .strtab
3, 0, 0, 0,
// sh_info: one local symbol, the dummy symbol
1, 0, 0, 0,
// sh_addralign
4, 0, 0, 0,
// sh_entsize: size of symbol
16, 0, 0, 0,
// Offset 172
// Shdr 3: .strtab
// sh_name: 1 null byte + ".test\0" + ".symtab\0"
15, 0, 0, 0,
// sh_type: SHT_STRTAB
3, 0, 0, 0,
// sh_flags
0, 0, 0, 0,
// sh_addr
0, 0, 0, 0,
// sh_offset: after .symtab section. 284 == 0x11c
0x1c, 0x1, 0, 0,
// sh_size: 1 null byte + "test\0"
6, 0, 0, 0,
// sh_link
0, 0, 0, 0,
// sh_info
0, 0, 0, 0,
// sh_addralign
1, 0, 0, 0,
// sh_entsize
0, 0, 0, 0,
// Offset 212
// Shdr 4: .shstrtab
// sh_name: 1 null byte + ".test\0" + ".symtab\0" + ".strtab\0"
23, 0, 0, 0,
// sh_type: SHT_STRTAB
3, 0, 0, 0,
// sh_flags
0, 0, 0, 0,
// sh_addr
0, 0, 0, 0,
// sh_offset: after .strtab section. 290 == 0x122
0x22, 0x1, 0, 0,
// sh_size: all section names
33, 0, 0, 0,
// sh_link
0, 0, 0, 0,
// sh_info
0, 0, 0, 0,
// sh_addralign
1, 0, 0, 0,
// sh_entsize
0, 0, 0, 0,
// Offset 252
// Contents of .symtab section
// Symbol 0
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// Offset 268
// Symbol 1
// st_name
1, 0, 0, 0,
// st_value
0, 0, 0, 0,
// st_size
0, 0, 0, 0,
// st_info: STT_NOTYPE, STB_GLOBAL
0x10,
// st_other
0,
// st_shndx: In .test
1, 0,
// Offset 284
// Contents of .strtab section
'\0',
't', 'e', 's', 't', '\0',
// Offset 290
// Contents of .shstrtab section
'\0',
'.', 't', 'e', 's', 't', '\0',
'.', 's', 'y', 'm', 't', 'a', 'b', '\0',
'.', 's', 't', 'r', 't', 'a', 'b', '\0',
'.', 's', 'h', 's', 't', 'r', 't', 'a', 'b', '\0'
};
const unsigned int test_file_1_size = sizeof test_file_1;
} // End namespace gold_testsuite.

20
gold/testsuite/testfile.h Normal file
View File

@ -0,0 +1,20 @@
// testfile.h -- test input files -*- C++ -*-
#ifndef GOLD_TESTSUITE_TESTFILE_H
#define GOLD_TESTSUITE_TESTFILE_H
namespace gold
{
class Target;
}
namespace gold_testsuite
{
extern gold::Target* target_test_pointer;
extern const unsigned char test_file_1[];
extern const unsigned int test_file_1_size;
}; // End namespace gold_testsuite.
#endif // !defined(GOLD_TESTSUITE_TESTFILE_H)

View File

@ -0,0 +1,18 @@
// testmain.cc -- main function for simplisitic gold test framework.
#include "gold.h"
#include "test.h"
using namespace gold_testsuite;
int
main(int, char** argv)
{
gold::program_name = argv[0];
Test_framework tf;
Register_test::run_tests(&tf);
exit(tf.failures());
}