1 // archive.cc -- archive support for gold
21 // The header of an entry in the archive. This is all readable text,
22 // padded with spaces where necesary. If the contents of an archive
23 // are all text file, the entire archive is readable.
25 struct Archive::Archive_header
29 // The file modification time.
31 // The user's UID in decimal.
33 // The user's GID in decimal.
35 // The file mode in octal.
37 // The file size in decimal.
39 // The final magic code.
45 const char Archive::armag
[sarmag
] =
47 '!', '<', 'a', 'r', 'c', 'h', '>', '\n'
50 const char Archive::arfmag
[2] = { '`', '\n' };
52 // Set up the archive: read the symbol map and the extended name
58 // The first member of the archive should be the symbol table.
59 std::string armap_name
;
60 off_t armap_size
= this->read_header(sarmag
, &armap_name
);
62 if (armap_name
.empty())
64 this->read_armap(sarmag
+ sizeof(Archive_header
), armap_size
);
65 off
= sarmag
+ sizeof(Archive_header
) + armap_size
;
67 else if (!this->input_file_
->options().include_whole_archive())
69 fprintf(stderr
, _("%s: %s: no archive symbol table (run ranlib)\n"),
70 program_name
, this->name().c_str());
76 // See if there is an extended name table.
80 off_t extended_size
= this->read_header(off
, &xname
);
83 const unsigned char* p
= this->get_view(off
+ sizeof(Archive_header
),
85 const char* px
= reinterpret_cast<const char*>(p
);
86 this->extended_names_
.assign(px
, extended_size
);
89 // Opening the file locked it. Unlock it now.
90 this->input_file_
->file().unlock();
93 // Read the archive symbol map.
96 Archive::read_armap(off_t start
, off_t size
)
98 // Read in the entire armap.
99 const unsigned char* p
= this->get_view(start
, size
);
101 // Numbers in the armap are always big-endian.
102 const elfcpp::Elf_Word
* pword
= reinterpret_cast<const elfcpp::Elf_Word
*>(p
);
103 unsigned int nsyms
= elfcpp::Swap
<32, true>::readval(pword
);
106 // Note that the addition is in units of sizeof(elfcpp::Elf_Word).
107 const char* pnames
= reinterpret_cast<const char*>(pword
+ nsyms
);
109 this->armap_
.resize(nsyms
);
111 for (unsigned int i
= 0; i
< nsyms
; ++i
)
113 this->armap_
[i
].name
= pnames
;
114 this->armap_
[i
].offset
= elfcpp::Swap
<32, true>::readval(pword
);
115 pnames
+= strlen(pnames
) + 1;
119 if (reinterpret_cast<const unsigned char*>(pnames
) - p
> size
)
121 fprintf(stderr
, _("%s: %s: bad archive symbol table names\n"),
122 program_name
, this->name().c_str());
126 // This array keeps track of which symbols are for archive elements
127 // which we have already included in the link.
128 this->armap_checked_
.resize(nsyms
);
131 // Read the header of an archive member at OFF. Fail if something
132 // goes wrong. Return the size of the member. Set *PNAME to the name
136 Archive::read_header(off_t off
, std::string
* pname
)
138 const unsigned char* p
= this->get_view(off
, sizeof(Archive_header
));
139 const Archive_header
* hdr
= reinterpret_cast<const Archive_header
*>(p
);
140 return this->interpret_header(hdr
, off
, pname
);
143 // Interpret the header of HDR, the header of the archive member at
144 // file offset OFF. Fail if something goes wrong. Return the size of
145 // the member. Set *PNAME to the name of the member.
148 Archive::interpret_header(const Archive_header
* hdr
, off_t off
,
151 if (memcmp(hdr
->ar_fmag
, arfmag
, sizeof arfmag
) != 0)
153 fprintf(stderr
, _("%s; %s: malformed archive header at %ld\n"),
154 program_name
, this->name().c_str(),
155 static_cast<long>(off
));
159 const int size_string_size
= sizeof hdr
->ar_size
;
160 char size_string
[size_string_size
+ 1];
161 memcpy(size_string
, hdr
->ar_size
, size_string_size
);
162 char* ps
= size_string
+ size_string_size
;
163 while (ps
[-1] == ' ')
169 off_t member_size
= strtol(size_string
, &end
, 10);
172 || (member_size
== LONG_MAX
&& errno
== ERANGE
))
174 fprintf(stderr
, _("%s: %s: malformed archive header size at %ld\n"),
175 program_name
, this->name().c_str(),
176 static_cast<long>(off
));
180 if (hdr
->ar_name
[0] != '/')
182 const char* name_end
= strchr(hdr
->ar_name
, '/');
184 || name_end
- hdr
->ar_name
>= static_cast<int>(sizeof hdr
->ar_name
))
186 fprintf(stderr
, _("%s: %s: malformed archive header name at %ld\n"),
187 program_name
, this->name().c_str(),
188 static_cast<long>(off
));
191 pname
->assign(hdr
->ar_name
, name_end
- hdr
->ar_name
);
193 else if (hdr
->ar_name
[1] == ' ')
195 // This is the symbol table.
198 else if (hdr
->ar_name
[1] == '/')
200 // This is the extended name table.
201 pname
->assign(1, '/');
206 long x
= strtol(hdr
->ar_name
+ 1, &end
, 10);
209 || (x
== LONG_MAX
&& errno
== ERANGE
)
210 || static_cast<size_t>(x
) >= this->extended_names_
.size())
212 fprintf(stderr
, _("%s: %s: bad extended name index at %ld\n"),
213 program_name
, this->name().c_str(),
214 static_cast<long>(off
));
218 const char* name
= this->extended_names_
.data() + x
;
219 const char* name_end
= strchr(name
, '/');
220 if (static_cast<size_t>(name_end
- name
) > this->extended_names_
.size()
221 || name_end
[1] != '\n')
223 fprintf(stderr
, _("%s: %s: bad extended name entry at header %ld\n"),
224 program_name
, this->name().c_str(),
225 static_cast<long>(off
));
228 pname
->assign(name
, name_end
- name
);
234 // Select members from the archive and add them to the link. We walk
235 // through the elements in the archive map, and look each one up in
236 // the symbol table. If it exists as a strong undefined symbol, we
237 // pull in the corresponding element. We have to do this in a loop,
238 // since pulling in one element may create new undefined symbols which
239 // may be satisfied by other objects in the archive.
242 Archive::add_symbols(Symbol_table
* symtab
, Layout
* layout
,
243 Input_objects
* input_objects
)
245 if (this->input_file_
->options().include_whole_archive())
246 return this->include_all_members(symtab
, layout
, input_objects
);
248 const size_t armap_size
= this->armap_
.size();
250 // This is a quick optimization, since we usually see many symbols
251 // in a row with the same offset. last_seen_offset holds the last
252 // offset we saw that was present in the seen_offsets_ set.
253 off_t last_seen_offset
= -1;
255 // Track which symbols in the symbol table we've already found to be
258 bool added_new_object
;
261 added_new_object
= false;
262 for (size_t i
= 0; i
< armap_size
; ++i
)
264 if (this->armap_checked_
[i
])
266 if (this->armap_
[i
].offset
== last_seen_offset
)
268 this->armap_checked_
[i
] = true;
271 if (this->seen_offsets_
.find(this->armap_
[i
].offset
)
272 != this->seen_offsets_
.end())
274 this->armap_checked_
[i
] = true;
275 last_seen_offset
= this->armap_
[i
].offset
;
279 Symbol
* sym
= symtab
->lookup(this->armap_
[i
].name
);
282 else if (!sym
->is_undefined())
284 this->armap_checked_
[i
] = true;
287 else if (sym
->binding() == elfcpp::STB_WEAK
)
290 // We want to include this object in the link.
291 last_seen_offset
= this->armap_
[i
].offset
;
292 this->seen_offsets_
.insert(last_seen_offset
);
293 this->armap_checked_
[i
] = true;
294 this->include_member(symtab
, layout
, input_objects
,
296 added_new_object
= true;
299 while (added_new_object
);
302 // Include all the archive members in the link. This is for --whole-archive.
305 Archive::include_all_members(Symbol_table
* symtab
, Layout
* layout
,
306 Input_objects
* input_objects
)
312 const unsigned char* p
= this->get_view(off
, sizeof(Archive_header
),
314 if (bytes
< sizeof(Archive_header
))
318 fprintf(stderr
, _("%s: %s: short archive header at %ld\n"),
319 program_name
, this->name().c_str(),
320 static_cast<long>(off
));
327 const Archive_header
* hdr
= reinterpret_cast<const Archive_header
*>(p
);
329 off_t size
= this->interpret_header(hdr
, off
, &name
);
334 else if (name
== "/")
336 // Extended name table.
339 this->include_member(symtab
, layout
, input_objects
, off
);
341 off
+= sizeof(Archive_header
) + size
;
347 // Include an archive member in the link. OFF is the file offset of
348 // the member header.
351 Archive::include_member(Symbol_table
* symtab
, Layout
* layout
,
352 Input_objects
* input_objects
, off_t off
)
355 this->read_header(off
, &n
);
357 size_t memoff
= off
+ sizeof(Archive_header
);
359 // Read enough of the file to pick up the entire ELF header.
360 int ehdr_size
= elfcpp::Elf_sizes
<64>::ehdr_size
;
362 const unsigned char* p
= this->input_file_
->file().get_view(memoff
,
367 fprintf(stderr
, _("%s: %s: member at %ld is not an ELF object"),
368 program_name
, this->name().c_str(),
369 static_cast<long>(off
));
373 static unsigned char elfmagic
[4] =
375 elfcpp::ELFMAG0
, elfcpp::ELFMAG1
,
376 elfcpp::ELFMAG2
, elfcpp::ELFMAG3
378 if (memcmp(p
, elfmagic
, 4) != 0)
380 fprintf(stderr
, _("%s: %s: member at %ld is not an ELF object"),
381 program_name
, this->name().c_str(),
382 static_cast<long>(off
));
386 Object
* obj
= make_elf_object((std::string(this->input_file_
->filename())
388 this->input_file_
, memoff
, p
, bytes
);
390 input_objects
->add_object(obj
);
392 Read_symbols_data sd
;
393 obj
->read_symbols(&sd
);
394 obj
->layout(symtab
, layout
, &sd
);
395 obj
->add_symbols(symtab
, &sd
);
398 // Add_archive_symbols methods.
400 Add_archive_symbols::~Add_archive_symbols()
402 if (this->this_blocker_
!= NULL
)
403 delete this->this_blocker_
;
404 // next_blocker_ is deleted by the task associated with the next
408 // Return whether we can add the archive symbols. We are blocked by
409 // this_blocker_. We block next_blocker_. We also lock the file.
411 Task::Is_runnable_type
412 Add_archive_symbols::is_runnable(Workqueue
*)
414 if (this->this_blocker_
!= NULL
&& this->this_blocker_
->is_blocked())
419 class Add_archive_symbols::Add_archive_symbols_locker
: public Task_locker
422 Add_archive_symbols_locker(Task_token
& token
, Workqueue
* workqueue
,
424 : blocker_(token
, workqueue
), filelock_(file
)
428 Task_locker_block blocker_
;
429 Task_locker_obj
<File_read
> filelock_
;
433 Add_archive_symbols::locks(Workqueue
* workqueue
)
435 return new Add_archive_symbols_locker(*this->next_blocker_
,
437 this->archive_
->file());
441 Add_archive_symbols::run(Workqueue
*)
443 this->archive_
->add_symbols(this->symtab_
, this->layout_
,
444 this->input_objects_
);
446 if (this->input_group_
!= NULL
)
447 this->input_group_
->add_archive(this->archive_
);
450 // We no longer need to know about this archive.
451 delete this->archive_
;
455 } // End namespace gold.