Sync with GCC:
[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
45int
46main(int argc, char** argv)
47{
48 if (argc != 2)
49 {
50 fprintf(stderr, "Usage: %s <file>\n", argv[0]);
51 return 1;
52 }
53 const char* filename = argv[1];
54
55 Output_file* file = new Output_file(filename);
56
57 bool t = file->open_for_modification();
58 if (!t)
59 {
60 fprintf(stderr, "%s: open_for_modification(%s): %s\n", argv[0], filename,
61 strerror(errno));
62 return 1;
63 }
64
65 Incremental_binary* inc = open_incremental_binary(file);
66
67 if (inc == NULL)
68 {
69 fprintf(stderr, "%s: open_incremental_binary(%s): %s\n", argv[0],
70 filename, strerror(errno));
71 return 1;
72 }
73
74 unsigned int strtab_shndx;
75 Incremental_binary::Location location;
76
77 t = inc->find_incremental_inputs_section(&location, &strtab_shndx);
78 if (!t)
79 {
80 fprintf(stderr, "%s: %s: no .gnu_incremental_inputs section\n", argv[0],
81 filename);
82 return 1;
83 }
84
85 Incremental_binary::View inputs_view(inc->view(location));
86 const unsigned char *p = inputs_view.data();
87
88 const Incremental_inputs_header_data* incremental_header =
89 reinterpret_cast<const Incremental_inputs_header_data*> (p);
90
91 const Incremental_inputs_entry_data* incremental_inputs =
92 reinterpret_cast<const Incremental_inputs_entry_data*>
93 (p + sizeof(Incremental_inputs_header_data));
94
95 if (incremental_header->version != 1)
96 {
954c3e2e 97 fprintf(stderr, "%s: %s: unknown incremental version %d\n", argv[0],
e2b8f3c4
RÁE
98 filename, incremental_header->version);
99 return 1;
100 }
101
102 elfcpp::Elf_file<64, false, Incremental_binary> elf_file(inc);
103
104 if (elf_file.section_type(strtab_shndx) != elfcpp::SHT_STRTAB)
105 {
106 fprintf(stderr,
107 "%s: %s: invalid string table section %u (type %d != %d)\n",
108 argv[0], filename, strtab_shndx,
109 elf_file.section_type(strtab_shndx), elfcpp::SHT_STRTAB);
110 return 1;
111 }
112
113 Incremental_binary::Location
114 strtab_location(elf_file.section_contents(strtab_shndx));
115
116 Incremental_binary::View strtab_view(inc->view(strtab_location));
117 p = strtab_view.data();
118
119 elfcpp::Elf_strtab strtab(strtab_view.data(), strtab_location.data_size);
120 const char* command_line;
121 t = strtab.get_c_string(incremental_header->command_line_offset,
122 &command_line);
123
124 if (!t)
125 {
126 fprintf(stderr,
127 "%s: %s: failed to get link command line: %zu out of range\n",
128 argv[0], filename,
129 static_cast<size_t>(incremental_header->command_line_offset));
130 return 1;
131 }
132
133 printf("Link command line: %s\n", command_line);
134
135 printf("Input files:\n");
136 for (unsigned i = 0; i < incremental_header->input_file_count; ++i)
137 {
138 const Incremental_inputs_entry_data* input =
139 &incremental_inputs[i];
140 const char *objname;
141
142 t = strtab.get_c_string(input->filename_offset, &objname);
143 if (!t)
144 {
145 fprintf(stderr,"%s: %s: failed to get file name for object %u:"
146 " %zu out of range\n", argv[0], filename, i,
147 static_cast<size_t>(input->filename_offset));
148 return 1;
149 }
150 printf(" %s\n", objname);
f8086623
RÁE
151 printf(" Timestamp sec = %llu\n",
152 static_cast<unsigned long long>(input->timestamp_sec));
e2b8f3c4
RÁE
153 printf(" Timestamp nsec = %d\n", input->timestamp_nsec);
154 printf(" Type = ");
155 // TODO: print the data at input->data_offset once we have it.
156 switch (input->input_type)
157 {
158 case INCREMENTAL_INPUT_OBJECT:
954c3e2e 159 printf("Object\n");
e2b8f3c4
RÁE
160 break;
161 case INCREMENTAL_INPUT_ARCHIVE:
162 printf("Archive\n");
163 break;
164 case INCREMENTAL_INPUT_SHARED_LIBRARY:
165 printf("Shared library\n");
166 break;
167 case INCREMENTAL_INPUT_SCRIPT:
168 printf("Linker script\n");
a45500ae
RÁE
169 if (input->data_offset != 0)
170 {
171 fprintf(stderr,"%s: %s: %u is a script but offset is not zero",
172 argv[0], filename, i);
173 return 1;
174 }
e2b8f3c4
RÁE
175 break;
176 case INCREMENTAL_INPUT_INVALID:
177 default:
178 fprintf(stderr, "%s: invalid file type for object %u: %d\n",
179 argv[0], i, input->input_type);
180 return 1;
181 }
182 }
183
184 return 0;
185}
This page took 0.031399 seconds and 4 git commands to generate.