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]

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


> This patch is OK with changes along those lines.

An updated patch is attached. One thing I was not sure was if I should
keep the "internal" namespace when moving the structs to the header
file. I kept it. Let me know if you think I should remove 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.
	* 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

> Thanks.
>
> Ian
>

Thanks,
-- 
Rafael Ãvila de EspÃndola
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/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..5e62cf2
--- /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 internal::Incremental_inputs_header_data* incremental_header =
+    reinterpret_cast<const internal::Incremental_inputs_header_data*> (p);
+
+  const internal::Incremental_inputs_entry_data* incremental_inputs =
+    reinterpret_cast<const internal::Incremental_inputs_entry_data*>
+    (p + sizeof(internal::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 internal::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 71ffd02..4c65668 100644
--- a/gold/incremental.cc
+++ b/gold/incremental.cc
@@ -39,49 +39,6 @@ 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
diff --git a/gold/incremental.h b/gold/incremental.h
index b53f6c1..0fe3308 100644
--- a/gold/incremental.h
+++ b/gold/incremental.h
@@ -52,6 +52,49 @@ enum Incremental_input_type
   INCREMENTAL_INPUT_SCRIPT = 4
 };
 
+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;
+};
+
+}
+
 // 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

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