This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


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

[patch][gold] Add a tool for dumping incremental linking information


The attached patch adds a simple tool that dumps the incremental
linking information. I intend to use it for testing. I should have a
patch that actually uses it tomorrow or the day after.

Once incremental linking is more mature, I will port this into
readelf. For now it is a standalone tool and I have used some gold
classes for convenience. Let me know if you would like it to be fully
independent from the start.

I have also included a small fix. The file elfcpp_file.h uses the
definition of Elf_sizes, so it should include elfcpp.h to get it.
	
elfcpp/
2009-11-23  Rafael Avila de Espindola  <espindola@google.com>

	* elfcpp_file.h: Include elfcpp.h.

gold/
2009-11-23  Rafael Avila de Espindola  <espindola@google.com>

	* Makefile.am: Build incremental-dump
	* Makefile.in: Regenerate.
	* incremental-dump.cc: New.

Cheers,
-- 
Rafael Ãvila de EspÃndola
diff --git a/elfcpp/elfcpp_file.h b/elfcpp/elfcpp_file.h
index cc61622..39347ae 100644
--- a/elfcpp/elfcpp_file.h
+++ b/elfcpp/elfcpp_file.h
@@ -60,6 +60,8 @@
 #include <cstdio>
 #include <cstring>
 
+#include "elfcpp.h" //for Elf_sizes
+
 namespace elfcpp
 {
 
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/incremental-dump.cc b/gold/incremental-dump.cc
new file mode 100644
index 0000000..e65cb70
--- /dev/null
+++ b/gold/incremental-dump.cc
@@ -0,0 +1,200 @@
+// 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 <stdio.h>
+#include "gold.h"
+#include "incremental.h"
+
+namespace gold
+{
+  class Output_file;
+}
+
+using namespace gold;
+
+// 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;
+};
+
+int
+main(int argc, char** argv)
+{
+  if (argc != 2)
+    {
+      fprintf(stderr, "usage: incremental-dump <file>\n");
+      return 1;
+    }
+  const char* filename = argv[1];
+
+  Output_file* file = new Output_file(filename);
+
+  bool t = file->open_for_modification();
+  if (!t)
+    {
+      fprintf(stderr, "failed to open file %s\n", filename);
+      return 1;
+    }
+
+  Incremental_binary* inc = open_incremental_binary(file);
+
+  if (inc == NULL)
+    {
+      fprintf(stderr, "Failed to open file %s\n", filename);
+      return 1;
+    }
+
+  unsigned int strtab_shndx;
+  Incremental_binary::Location location;
+
+  t = inc->find_incremental_inputs_section(&location, &strtab_shndx);
+  if (!t)
+    {
+      fprintf(stderr, "File has no .gnu_incremental_inputs section\n");
+      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, "unknown version %d\n", 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, "invalid string table section\n");
+      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, "Failed to get the link command line\n");
+      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, "Failed to get the name of an object file\n");
+          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("object\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, "Unknown file type\n");
+        return 1;
+      }
+    }
+
+  return 0;
+}

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