diff options
-rw-r--r-- | elfcpp/ChangeLog | 4 | ||||
-rw-r--r-- | elfcpp/elfcpp_file.h | 2 | ||||
-rw-r--r-- | gold/ChangeLog | 10 | ||||
-rw-r--r-- | gold/Makefile.am | 6 | ||||
-rw-r--r-- | gold/Makefile.in | 27 | ||||
-rw-r--r-- | gold/incremental-dump.cc | 178 | ||||
-rw-r--r-- | gold/incremental.cc | 59 | ||||
-rw-r--r-- | gold/incremental.h | 39 |
8 files changed, 264 insertions, 61 deletions
diff --git a/elfcpp/ChangeLog b/elfcpp/ChangeLog index d48dcfb..508b2ca 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 cc61622..8dd7ad5 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 a0d854e..daa729e 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 8d8b617..175bd23 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 d4c689b..d317e91 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 0000000..a250068 --- /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 b5bfac5..97b3eea 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 b53f6c1..f6e36fa 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 |