summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--elfcpp/ChangeLog4
-rw-r--r--elfcpp/elfcpp_file.h2
-rw-r--r--gold/ChangeLog10
-rw-r--r--gold/Makefile.am6
-rw-r--r--gold/Makefile.in27
-rw-r--r--gold/incremental-dump.cc178
-rw-r--r--gold/incremental.cc59
-rw-r--r--gold/incremental.h39
8 files changed, 264 insertions, 61 deletions
diff --git a/elfcpp/ChangeLog b/elfcpp/ChangeLog
index d48dcfb621..508b2cac67 100644
--- a/elfcpp/ChangeLog
+++ b/elfcpp/ChangeLog
@@ -1,3 +1,7 @@
+2009-11-24 Rafael Avila de Espindola <espindola@google.com>
+
+ * elfcpp_file.h: Include elfcpp.h.
+
2009-11-03 Ian Lance Taylor <iant@google.com>
* elfcpp.h: Remove trailing commas from enum definitions.
diff --git a/elfcpp/elfcpp_file.h b/elfcpp/elfcpp_file.h
index cc61622692..8dd7ad5cca 100644
--- a/elfcpp/elfcpp_file.h
+++ b/elfcpp/elfcpp_file.h
@@ -60,6 +60,8 @@
#include <cstdio>
#include <cstring>
+#include "elfcpp.h"
+
namespace elfcpp
{
diff --git a/gold/ChangeLog b/gold/ChangeLog
index a0d854ed24..daa729eef7 100644
--- a/gold/ChangeLog
+++ b/gold/ChangeLog
@@ -1,5 +1,15 @@
2009-11-24 Rafael Avila de Espindola <espindola@google.com>
+ * Makefile.am: Build incremental-dump
+ * Makefile.in: Regenerate.
+ * incremental-dump.cc: New.
+ * incremental.cc (Incremental_inputs_header_data,
+ Incremental_inputs_entry_data): Move to incremental.h
+ * incremental.h: (Incremental_inputs_header_data,
+ Incremental_inputs_entry_data): Move from incremental.cc
+
+2009-11-24 Rafael Avila de Espindola <espindola@google.com>
+
* incremental.cc (Incremental_inputs_header,
Incremental_inputs_header_write, Incremental_inputs_entry,
Incremental_inputs_entry_write): Add a typedef with the data type.
diff --git a/gold/Makefile.am b/gold/Makefile.am
index 8d8b617b4b..175bd2361b 100644
--- a/gold/Makefile.am
+++ b/gold/Makefile.am
@@ -34,7 +34,7 @@ AM_YFLAGS = -d
am__skiplex =
am__skipyacc =
-noinst_PROGRAMS = ld-new
+noinst_PROGRAMS = ld-new incremental-dump
noinst_LIBRARIES = libgold.a
CCFILES = \
@@ -151,6 +151,10 @@ ld_new_LDADD = $(ldadd_var)
EXTRA_ld_new_SOURCES = $(TARGETSOURCES)
+incremental_dump_SOURCES = incremental-dump.cc
+incremental_dump_DEPENDENCIES = $(TARGETOBJS) libgold.a $(LIBIBERTY)
+incremental_dump_LDADD = $(TARGETOBJS) libgold.a $(LIBIBERTY)
+
# Use an explicit dependency for the bison generated header file.
expression.$(OBJEXT): yyscript.h
script-sections.$(OBJEXT): yyscript.h
diff --git a/gold/Makefile.in b/gold/Makefile.in
index d4c689b2f5..d317e91f36 100644
--- a/gold/Makefile.in
+++ b/gold/Makefile.in
@@ -38,7 +38,7 @@ POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
target_triplet = @target@
-noinst_PROGRAMS = ld-new$(EXEEXT)
+noinst_PROGRAMS = ld-new$(EXEEXT) incremental-dump$(EXEEXT)
@GCC_TRUE@@NATIVE_LINKER_TRUE@check_PROGRAMS = ld1$(EXEEXT) \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ ld2$(EXEEXT) ld1-r$(EXEEXT) \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ ld2-r$(EXEEXT)
@@ -94,10 +94,12 @@ am_libgold_a_OBJECTS = $(am__objects_1) $(am__objects_2) \
$(am__objects_3)
libgold_a_OBJECTS = $(am_libgold_a_OBJECTS)
PROGRAMS = $(noinst_PROGRAMS)
+am_incremental_dump_OBJECTS = incremental-dump.$(OBJEXT)
+incremental_dump_OBJECTS = $(am_incremental_dump_OBJECTS)
+am__DEPENDENCIES_1 =
am__objects_4 = main.$(OBJEXT)
am_ld_new_OBJECTS = $(am__objects_4)
ld_new_OBJECTS = $(am_ld_new_OBJECTS)
-am__DEPENDENCIES_1 =
am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) libgold.a $(LIBIBERTY) \
$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
$(am__DEPENDENCIES_1)
@@ -137,13 +139,13 @@ CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \
@MAINTAINER_MODE_FALSE@am__skipyacc = test -f $@ ||
YACCCOMPILE = $(YACC) $(YFLAGS) $(AM_YFLAGS)
YLWRAP = $(top_srcdir)/../ylwrap
-SOURCES = $(libgold_a_SOURCES) $(ld_new_SOURCES) \
- $(EXTRA_ld_new_SOURCES) $(ld1_SOURCES) $(ld1_r_SOURCES) \
- $(ld2_SOURCES) $(ld2_r_SOURCES)
-DIST_SOURCES = $(libgold_a_SOURCES) $(ld_new_SOURCES) \
- $(EXTRA_ld_new_SOURCES) $(am__ld1_SOURCES_DIST) \
- $(am__ld1_r_SOURCES_DIST) $(am__ld2_SOURCES_DIST) \
- $(am__ld2_r_SOURCES_DIST)
+SOURCES = $(libgold_a_SOURCES) $(incremental_dump_SOURCES) \
+ $(ld_new_SOURCES) $(EXTRA_ld_new_SOURCES) $(ld1_SOURCES) \
+ $(ld1_r_SOURCES) $(ld2_SOURCES) $(ld2_r_SOURCES)
+DIST_SOURCES = $(libgold_a_SOURCES) $(incremental_dump_SOURCES) \
+ $(ld_new_SOURCES) $(EXTRA_ld_new_SOURCES) \
+ $(am__ld1_SOURCES_DIST) $(am__ld1_r_SOURCES_DIST) \
+ $(am__ld2_SOURCES_DIST) $(am__ld2_r_SOURCES_DIST)
RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
html-recursive info-recursive install-data-recursive \
install-dvi-recursive install-exec-recursive \
@@ -458,6 +460,9 @@ ld_new_SOURCES = $(sources_var)
ld_new_DEPENDENCIES = $(deps_var)
ld_new_LDADD = $(ldadd_var)
EXTRA_ld_new_SOURCES = $(TARGETSOURCES)
+incremental_dump_SOURCES = incremental-dump.cc
+incremental_dump_DEPENDENCIES = $(TARGETOBJS) libgold.a $(LIBIBERTY)
+incremental_dump_LDADD = $(TARGETOBJS) libgold.a $(LIBIBERTY)
POTFILES = $(CCFILES) $(HFILES) $(TARGETSOURCES)
@GCC_TRUE@@NATIVE_LINKER_TRUE@ld1_SOURCES = $(sources_var)
@GCC_TRUE@@NATIVE_LINKER_TRUE@ld1_DEPENDENCIES = $(deps_var) gcctestdir1/ld
@@ -552,6 +557,9 @@ clean-checkPROGRAMS:
clean-noinstPROGRAMS:
-test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS)
+incremental-dump$(EXEEXT): $(incremental_dump_OBJECTS) $(incremental_dump_DEPENDENCIES)
+ @rm -f incremental-dump$(EXEEXT)
+ $(CXXLINK) $(incremental_dump_OBJECTS) $(incremental_dump_LDADD) $(LIBS)
ld-new$(EXEEXT): $(ld_new_OBJECTS) $(ld_new_DEPENDENCIES)
@rm -f ld-new$(EXEEXT)
$(CXXLINK) $(ld_new_OBJECTS) $(ld_new_LDADD) $(LIBS)
@@ -599,6 +607,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)/icf.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/incremental-dump.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/incremental.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@
diff --git a/gold/incremental-dump.cc b/gold/incremental-dump.cc
new file mode 100644
index 0000000000..a250068ab1
--- /dev/null
+++ b/gold/incremental-dump.cc
@@ -0,0 +1,178 @@
+// inremental.cc -- incremental linking test/deubg tool
+
+// Copyright 2009 Free Software Foundation, Inc.
+// Written by Rafael Avila de Espindola <rafael.espindola@gmail.com>
+
+// This file is part of gold.
+
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+
+// This program 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 for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+// MA 02110-1301, USA.
+
+
+// This file is a (still incomplete) test/debug tool that should display
+// all information available in the incremental linking sections in a
+// format that is easy to read.
+// Once the format is a bit more stable, this should probably be moved to
+// readelf. Because of that, the use of gold's data structures and functions
+// is just a short term convenience and not a design decision.
+
+#include "gold.h"
+
+#include <stdio.h>
+#include <errno.h>
+
+#include "incremental.h"
+
+namespace gold
+{
+ class Output_file;
+}
+
+using namespace gold;
+
+int
+main(int argc, char** argv)
+{
+ if (argc != 2)
+ {
+ fprintf(stderr, "Usage: %s <file>\n", argv[0]);
+ return 1;
+ }
+ const char* filename = argv[1];
+
+ Output_file* file = new Output_file(filename);
+
+ bool t = file->open_for_modification();
+ if (!t)
+ {
+ fprintf(stderr, "%s: open_for_modification(%s): %s\n", argv[0], filename,
+ strerror(errno));
+ return 1;
+ }
+
+ Incremental_binary* inc = open_incremental_binary(file);
+
+ if (inc == NULL)
+ {
+ fprintf(stderr, "%s: open_incremental_binary(%s): %s\n", argv[0],
+ filename, strerror(errno));
+ return 1;
+ }
+
+ unsigned int strtab_shndx;
+ Incremental_binary::Location location;
+
+ t = inc->find_incremental_inputs_section(&location, &strtab_shndx);
+ if (!t)
+ {
+ fprintf(stderr, "%s: %s: no .gnu_incremental_inputs section\n", argv[0],
+ filename);
+ return 1;
+ }
+
+ Incremental_binary::View inputs_view(inc->view(location));
+ const unsigned char *p = inputs_view.data();
+
+ const Incremental_inputs_header_data* incremental_header =
+ reinterpret_cast<const Incremental_inputs_header_data*> (p);
+
+ const Incremental_inputs_entry_data* incremental_inputs =
+ reinterpret_cast<const Incremental_inputs_entry_data*>
+ (p + sizeof(Incremental_inputs_header_data));
+
+ if (incremental_header->version != 1)
+ {
+ fprintf(stderr, "%s: %s: unknown incremestal version %d\n", argv[0],
+ filename, incremental_header->version);
+ return 1;
+ }
+
+ elfcpp::Elf_file<64, false, Incremental_binary> elf_file(inc);
+
+ if (elf_file.section_type(strtab_shndx) != elfcpp::SHT_STRTAB)
+ {
+ fprintf(stderr,
+ "%s: %s: invalid string table section %u (type %d != %d)\n",
+ argv[0], filename, strtab_shndx,
+ elf_file.section_type(strtab_shndx), elfcpp::SHT_STRTAB);
+ return 1;
+ }
+
+ Incremental_binary::Location
+ strtab_location(elf_file.section_contents(strtab_shndx));
+
+ Incremental_binary::View strtab_view(inc->view(strtab_location));
+ p = strtab_view.data();
+
+ elfcpp::Elf_strtab strtab(strtab_view.data(), strtab_location.data_size);
+ const char* command_line;
+ t = strtab.get_c_string(incremental_header->command_line_offset,
+ &command_line);
+
+ if (!t)
+ {
+ fprintf(stderr,
+ "%s: %s: failed to get link command line: %zu out of range\n",
+ argv[0], filename,
+ static_cast<size_t>(incremental_header->command_line_offset));
+ return 1;
+ }
+
+ printf("Link command line: %s\n", command_line);
+
+ printf("Input files:\n");
+ for (unsigned i = 0; i < incremental_header->input_file_count; ++i)
+ {
+ const Incremental_inputs_entry_data* input =
+ &incremental_inputs[i];
+ const char *objname;
+
+ t = strtab.get_c_string(input->filename_offset, &objname);
+ if (!t)
+ {
+ fprintf(stderr,"%s: %s: failed to get file name for object %u:"
+ " %zu out of range\n", argv[0], filename, i,
+ static_cast<size_t>(input->filename_offset));
+ return 1;
+ }
+ printf(" %s\n", objname);
+ printf(" Timestamp sec = %ld\n", input->timestamp_sec);
+ printf(" Timestamp nsec = %d\n", input->timestamp_nsec);
+ printf(" Type = ");
+ // TODO: print the data at input->data_offset once we have it.
+ switch (input->input_type)
+ {
+ case INCREMENTAL_INPUT_OBJECT:
+ printf("Abject\n");
+ break;
+ case INCREMENTAL_INPUT_ARCHIVE:
+ printf("Archive\n");
+ break;
+ case INCREMENTAL_INPUT_SHARED_LIBRARY:
+ printf("Shared library\n");
+ break;
+ case INCREMENTAL_INPUT_SCRIPT:
+ printf("Linker script\n");
+ break;
+ case INCREMENTAL_INPUT_INVALID:
+ default:
+ fprintf(stderr, "%s: invalid file type for object %u: %d\n",
+ argv[0], i, input->input_type);
+ return 1;
+ }
+ }
+
+ return 0;
+}
diff --git a/gold/incremental.cc b/gold/incremental.cc
index b5bfac55e6..97b3eea43d 100644
--- a/gold/incremental.cc
+++ b/gold/incremental.cc
@@ -39,59 +39,16 @@ namespace gold {
// we could think about backward (and forward?) compatibility.
const unsigned int INCREMENTAL_LINK_VERSION = 1;
-namespace internal {
-
-// Header of the .gnu_incremental_input section.
-struct Incremental_inputs_header_data
-{
- // Incremental linker version.
- elfcpp::Elf_Word version;
-
- // Numer of input files in the link.
- elfcpp::Elf_Word input_file_count;
-
- // Offset of command line options in .gnu_incremental_strtab.
- elfcpp::Elf_Word command_line_offset;
-
- // Padding.
- elfcpp::Elf_Word reserved;
-};
-
-// Data stored in .gnu_incremental_input after the header for each of the
-// Incremental_input_header_data::input_file_count input entries.
-struct Incremental_inputs_entry_data
-{
- // Offset of file name in .gnu_incremental_strtab section.
- elfcpp::Elf_Word filename_offset;
-
- // Offset of data in .gnu_incremental_input.
- elfcpp::Elf_Word data_offset;
-
- // Timestamp (in seconds).
- elfcpp::Elf_Xword timestamp_sec;
-
- // Nano-second part of timestamp (if supported).
- elfcpp::Elf_Word timestamp_nsec;
-
- // Type of the input entry.
- elfcpp::Elf_Half input_type;
-
- // Padding.
- elfcpp::Elf_Half reserved;
-};
-
-}
-
// Accessors.
// Reader class for .gnu_incremental_inputs header. See
-// internal::Incremental_inputs_header_data for fields descriptions.
+// Incremental_inputs_header_data for fields descriptions.
template<int size, bool big_endian>
class Incremental_inputs_header
{
private:
- typedef internal::Incremental_inputs_header_data Data_type;
+ typedef Incremental_inputs_header_data Data_type;
public:
Incremental_inputs_header(const unsigned char *p)
@@ -121,13 +78,13 @@ class Incremental_inputs_header
};
// Writer class for .gnu_incremental_inputs header. See
-// internal::Incremental_inputs_header_data for fields descriptions.
+// Incremental_inputs_header_data for fields descriptions.
template<int size, bool big_endian>
class Incremental_inputs_header_write
{
private:
- typedef internal::Incremental_inputs_header_data Data_type;
+ typedef Incremental_inputs_header_data Data_type;
public:
Incremental_inputs_header_write(unsigned char *p)
@@ -157,12 +114,12 @@ class Incremental_inputs_header_write
};
// Reader class for an .gnu_incremental_inputs entry. See
-// internal::Incremental_inputs_entry_data for fields descriptions.
+// Incremental_inputs_entry_data for fields descriptions.
template<int size, bool big_endian>
class Incremental_inputs_entry
{
private:
- typedef internal::Incremental_inputs_entry_data Data_type;
+ typedef Incremental_inputs_entry_data Data_type;
public:
Incremental_inputs_entry(const unsigned char *p)
@@ -200,12 +157,12 @@ class Incremental_inputs_entry
};
// Writer class for an .gnu_incremental_inputs entry. See
-// internal::Incremental_inputs_entry_data for fields descriptions.
+// Incremental_inputs_entry_data for fields descriptions.
template<int size, bool big_endian>
class Incremental_inputs_entry_write
{
private:
- typedef internal::Incremental_inputs_entry_data Data_type;
+ typedef Incremental_inputs_entry_data Data_type;
public:
Incremental_inputs_entry_write(unsigned char *p)
diff --git a/gold/incremental.h b/gold/incremental.h
index b53f6c1cc3..f6e36faba8 100644
--- a/gold/incremental.h
+++ b/gold/incremental.h
@@ -52,6 +52,45 @@ enum Incremental_input_type
INCREMENTAL_INPUT_SCRIPT = 4
};
+// Header of the .gnu_incremental_input section.
+struct Incremental_inputs_header_data
+{
+ // Incremental linker version.
+ elfcpp::Elf_Word version;
+
+ // Numer of input files in the link.
+ elfcpp::Elf_Word input_file_count;
+
+ // Offset of command line options in .gnu_incremental_strtab.
+ elfcpp::Elf_Word command_line_offset;
+
+ // Padding.
+ elfcpp::Elf_Word reserved;
+};
+
+// Data stored in .gnu_incremental_input after the header for each of the
+// Incremental_input_header_data::input_file_count input entries.
+struct Incremental_inputs_entry_data
+{
+ // Offset of file name in .gnu_incremental_strtab section.
+ elfcpp::Elf_Word filename_offset;
+
+ // Offset of data in .gnu_incremental_input.
+ elfcpp::Elf_Word data_offset;
+
+ // Timestamp (in seconds).
+ elfcpp::Elf_Xword timestamp_sec;
+
+ // Nano-second part of timestamp (if supported).
+ elfcpp::Elf_Word timestamp_nsec;
+
+ // Type of the input entry.
+ elfcpp::Elf_Half input_type;
+
+ // Padding.
+ elfcpp::Elf_Half reserved;
+};
+
// An object representing the ELF file we edit during an incremental build.
// Similar to Object or Dynobj, but operates on Output_file and contains
// method specific to file edition (TBD). This is the abstract parent class