<html>
<head>
<base href="https://llvm.org/bugs/" />
</head>
<body><table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Bug ID</th>
<td><a class="bz_bug_link
bz_status_NEW "
title="NEW --- - Segfault when creating archive from lib.exe-created archive"
href="https://llvm.org/bugs/show_bug.cgi?id=25877">25877</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>Segfault when creating archive from lib.exe-created archive
</td>
</tr>
<tr>
<th>Product</th>
<td>tools
</td>
</tr>
<tr>
<th>Version</th>
<td>trunk
</td>
</tr>
<tr>
<th>Hardware</th>
<td>PC
</td>
</tr>
<tr>
<th>OS</th>
<td>All
</td>
</tr>
<tr>
<th>Status</th>
<td>NEW
</td>
</tr>
<tr>
<th>Severity</th>
<td>normal
</td>
</tr>
<tr>
<th>Priority</th>
<td>P
</td>
</tr>
<tr>
<th>Component</th>
<td>llvm-ar
</td>
</tr>
<tr>
<th>Assignee</th>
<td>unassignedbugs@nondot.org
</td>
</tr>
<tr>
<th>Reporter</th>
<td>alex@crichton.co
</td>
</tr>
<tr>
<th>CC</th>
<td>llvm-bugs@lists.llvm.org
</td>
</tr>
<tr>
<th>Classification</th>
<td>Unclassified
</td>
</tr></table>
<p>
<div>
<pre>Over in Rust-land we've got some custom code to create an archive by merging in
archives from other sources, often lib.exe created archives. Some of the
generated archives by LLVM end up being corrupted, spurring on some
investigation.
To reproduce this, the following sequence of steps should suffice. This is
currently specific to MSVC, but I suspect the bug is not Windows-specific:
1. Create an object file foo.obj from cl.exe
2. Create a directory named "reallylongname" and put foo.obj inside
3. Run "lib.exe /out:foo.lib reallylongname/foo.obj"
4. Create the following MRI script
create libfoo.a
addlib foo.lib
save
end
5. Run "llvm-ar.exe -M < script"
That should suffice in segfaulting llvm-ar (at least it does locally). In some
of our own tests we haven't seen segfaults but instead corrupt archives, but I
think it's all basically the same.
What I believe is going on here is that lib.exe creates archives where the name
of each member typically contains the full path rather than just the filename
component. For example the if you run `llvm-ar.exe t foo.lib` it will print
"reallylongname/foo.obj". Upon inspecting the archive it looks like lib.exe
handles these long file names via the standard put-the-name-in-the-string-table
method.
In the code for writeArchive, however, there's some disagreement about whether
filename(Name) or Name is emitted as the name of an entry. For example when
creating the string table (the writeStringTable function), the test for whether
an entry is emitted is based on filename(I.getName()). When emitting an old
entry, however, the name of the entry is I.getName() (in writeArchive). This
disagreement causes the StringMapIndexIter value to overrun the end of the
vector its iterating over, causing the segfault.
I believe we only see this on MSVC because lib.exe stores full paths whereas
most other archivers store file names (e.g. filename(Name) == Name).
tl;dr;, I think the fix is to change the call to printMemberHeader to use
filename(I.getName()), but I could be wrong! If you need any more info, just
let me know.</pre>
</div>
</p>
<hr>
<span>You are receiving this mail because:</span>
<ul>
<li>You are on the CC list for the bug.</li>
</ul>
</body>
</html>