2010-08-12 Daniel Jacobowitz <dan@codesourcery.com>
[deliverable/binutils-gdb.git] / gold / incremental-dump.cc
CommitLineData
e2b8f3c4
RÁE
1// inremental.cc -- incremental linking test/deubg tool
2
3// Copyright 2009 Free Software Foundation, Inc.
4// Written by Rafael Avila de Espindola <rafael.espindola@gmail.com>
5
6// This file is part of gold.
7
8// This program is free software; you can redistribute it and/or modify
9// it under the terms of the GNU General Public License as published by
10// the Free Software Foundation; either version 3 of the License, or
11// (at your option) any later version.
12
13// This program is distributed in the hope that it will be useful,
14// but WITHOUT ANY WARRANTY; without even the implied warranty of
15// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16// GNU General Public License for more details.
17
18// You should have received a copy of the GNU General Public License
19// along with this program; if not, write to the Free Software
20// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21// MA 02110-1301, USA.
22
23
24// This file is a (still incomplete) test/debug tool that should display
25// all information available in the incremental linking sections in a
26// format that is easy to read.
27// Once the format is a bit more stable, this should probably be moved to
28// readelf. Because of that, the use of gold's data structures and functions
29// is just a short term convenience and not a design decision.
30
31#include "gold.h"
32
33#include <stdio.h>
34#include <errno.h>
35
36#include "incremental.h"
37
38namespace gold
39{
40 class Output_file;
41}
42
43using namespace gold;
44
20b52f1a
RÁE
45template<int size, bool big_endian>
46static void
47dump_incremental_inputs(const char* argv0,
48 const char* filename, Incremental_binary* inc)
e2b8f3c4 49{
20b52f1a 50 bool t;
e2b8f3c4
RÁE
51 unsigned int strtab_shndx;
52 Incremental_binary::Location location;
53
54 t = inc->find_incremental_inputs_section(&location, &strtab_shndx);
55 if (!t)
56 {
20b52f1a 57 fprintf(stderr, "%s: %s: no .gnu_incremental_inputs section\n", argv0,
e2b8f3c4 58 filename);
20b52f1a 59 exit (1);
e2b8f3c4
RÁE
60 }
61
62 Incremental_binary::View inputs_view(inc->view(location));
20b52f1a 63 const unsigned char* p = inputs_view.data();
e2b8f3c4 64
20b52f1a 65 Incremental_inputs_header<size, big_endian> incremental_header(p);
e2b8f3c4 66
20b52f1a 67 const unsigned char* incremental_inputs_base =
e2b8f3c4
RÁE
68 (p + sizeof(Incremental_inputs_header_data));
69
20b52f1a 70 if (incremental_header.get_version() != 1)
e2b8f3c4 71 {
20b52f1a
RÁE
72 fprintf(stderr, "%s: %s: unknown incremental version %d\n", argv0,
73 filename, incremental_header.get_version());
74 exit(1);
e2b8f3c4
RÁE
75 }
76
20b52f1a 77 elfcpp::Elf_file<size, big_endian, Incremental_binary> elf_file(inc);
e2b8f3c4
RÁE
78
79 if (elf_file.section_type(strtab_shndx) != elfcpp::SHT_STRTAB)
80 {
81 fprintf(stderr,
82 "%s: %s: invalid string table section %u (type %d != %d)\n",
20b52f1a 83 argv0, filename, strtab_shndx,
e2b8f3c4 84 elf_file.section_type(strtab_shndx), elfcpp::SHT_STRTAB);
20b52f1a 85 exit(1);
e2b8f3c4
RÁE
86 }
87
88 Incremental_binary::Location
89 strtab_location(elf_file.section_contents(strtab_shndx));
90
91 Incremental_binary::View strtab_view(inc->view(strtab_location));
92 p = strtab_view.data();
93
94 elfcpp::Elf_strtab strtab(strtab_view.data(), strtab_location.data_size);
95 const char* command_line;
20b52f1a
RÁE
96 elfcpp::Elf_Word command_line_offset =
97 incremental_header.get_command_line_offset();
98 t = strtab.get_c_string(command_line_offset, &command_line);
e2b8f3c4
RÁE
99
100 if (!t)
101 {
102 fprintf(stderr,
103 "%s: %s: failed to get link command line: %zu out of range\n",
20b52f1a
RÁE
104 argv0, filename,
105 static_cast<size_t>(command_line_offset));
106 exit(1);
e2b8f3c4
RÁE
107 }
108
109 printf("Link command line: %s\n", command_line);
110
111 printf("Input files:\n");
20b52f1a 112 for (unsigned i = 0; i < incremental_header.get_input_file_count(); ++i)
e2b8f3c4 113 {
20b52f1a
RÁE
114 const unsigned char* input_p = incremental_inputs_base +
115 i * sizeof(Incremental_inputs_entry_data);
116 Incremental_inputs_entry<size, big_endian> input(input_p);
117 const char* objname;
e2b8f3c4 118
20b52f1a 119 t = strtab.get_c_string(input.get_filename_offset(), &objname);
e2b8f3c4
RÁE
120 if (!t)
121 {
122 fprintf(stderr,"%s: %s: failed to get file name for object %u:"
20b52f1a
RÁE
123 " %zu out of range\n", argv0, filename, i,
124 static_cast<size_t>(input.get_filename_offset()));
125 exit(1);
e2b8f3c4
RÁE
126 }
127 printf(" %s\n", objname);
f8086623 128 printf(" Timestamp sec = %llu\n",
20b52f1a
RÁE
129 static_cast<unsigned long long>(input.get_timestamp_sec()));
130 printf(" Timestamp nsec = %d\n", input.get_timestamp_nsec());
e2b8f3c4
RÁE
131 printf(" Type = ");
132 // TODO: print the data at input->data_offset once we have it.
20b52f1a
RÁE
133 elfcpp::Elf_Word input_type = input.get_input_type();
134 switch (input_type)
e2b8f3c4
RÁE
135 {
136 case INCREMENTAL_INPUT_OBJECT:
954c3e2e 137 printf("Object\n");
e2b8f3c4
RÁE
138 break;
139 case INCREMENTAL_INPUT_ARCHIVE:
140 printf("Archive\n");
141 break;
142 case INCREMENTAL_INPUT_SHARED_LIBRARY:
143 printf("Shared library\n");
144 break;
145 case INCREMENTAL_INPUT_SCRIPT:
146 printf("Linker script\n");
20b52f1a 147 if (input.get_data_offset() != 0)
a45500ae
RÁE
148 {
149 fprintf(stderr,"%s: %s: %u is a script but offset is not zero",
20b52f1a
RÁE
150 argv0, filename, i);
151 exit(1);
a45500ae 152 }
e2b8f3c4
RÁE
153 break;
154 case INCREMENTAL_INPUT_INVALID:
155 default:
156 fprintf(stderr, "%s: invalid file type for object %u: %d\n",
20b52f1a
RÁE
157 argv0, i, input_type);
158 exit(1);
e2b8f3c4
RÁE
159 }
160 }
20b52f1a
RÁE
161}
162
163int
164main(int argc, char** argv)
165{
166 if (argc != 2)
167 {
168 fprintf(stderr, "Usage: %s <file>\n", argv[0]);
169 return 1;
170 }
171 const char* filename = argv[1];
172
173 Output_file* file = new Output_file(filename);
174
175 bool t = file->open_for_modification();
176 if (!t)
177 {
178 fprintf(stderr, "%s: open_for_modification(%s): %s\n", argv[0], filename,
179 strerror(errno));
180 return 1;
181 }
182
183 Incremental_binary* inc = open_incremental_binary(file);
184
185 if (inc == NULL)
186 {
187 fprintf(stderr, "%s: open_incremental_binary(%s): %s\n", argv[0],
188 filename, strerror(errno));
189 return 1;
190 }
191
192 switch (parameters->size_and_endianness())
193 {
194#ifdef HAVE_TARGET_32_LITTLE
195 case Parameters::TARGET_32_LITTLE:
196 dump_incremental_inputs<32, false>(argv[0], filename, inc);
197 break;
198#endif
199#ifdef HAVE_TARGET_32_BIG
200 case Parameters::TARGET_32_BIG:
201 dump_incremental_inputs<32, true>(argv[0], filename, inc);
202 break;
203#endif
204#ifdef HAVE_TARGET_64_LITTLE
205 case Parameters::TARGET_64_LITTLE:
206 dump_incremental_inputs<64, false>(argv[0], filename, inc);
207 break;
208#endif
209#ifdef HAVE_TARGET_64_BIG
210 case Parameters::TARGET_64_BIG:
211 dump_incremental_inputs<64, true>(argv[0], filename, inc);
212 break;
213#endif
214 default:
215 gold_unreachable();
216 }
e2b8f3c4
RÁE
217
218 return 0;
219}
This page took 0.07018 seconds and 4 git commands to generate.