2009-11-24 Rafael Avila de Espindola <espindola@google.com>
[external/binutils.git] / gold / incremental-dump.cc
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
38 namespace gold
39 {
40   class Output_file;
41 }
42
43 using namespace gold;
44
45 int
46 main(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     {
97       fprintf(stderr, "%s: %s: unknown incremestal version %d\n", argv[0],
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);
151       printf("    Timestamp sec = %ld\n", input->timestamp_sec);
152       printf("    Timestamp nsec = %d\n", input->timestamp_nsec);
153       printf("    Type = ");
154       // TODO: print the data at input->data_offset once we have it.
155       switch (input->input_type)
156       {
157       case INCREMENTAL_INPUT_OBJECT:
158         printf("Abject\n");
159         break;
160       case INCREMENTAL_INPUT_ARCHIVE:
161         printf("Archive\n");
162         break;
163       case INCREMENTAL_INPUT_SHARED_LIBRARY:
164         printf("Shared library\n");
165         break;
166       case INCREMENTAL_INPUT_SCRIPT:
167         printf("Linker script\n");
168         break;
169       case INCREMENTAL_INPUT_INVALID:
170       default:
171         fprintf(stderr, "%s: invalid file type for object %u: %d\n",
172                 argv[0], i, input->input_type);
173         return 1;
174       }
175     }
176
177   return 0;
178 }