Commit | Line | Data |
---|---|---|
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 | ||
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 | } |