1
1
mirror of https://github.com/rui314/mold.git synced 2024-11-11 05:46:58 +03:00

Handle ar header alignment correctly

This commit is contained in:
Rui Ueyama 2021-06-20 17:45:49 +09:00
parent 83b14328ec
commit 7a689d8361
2 changed files with 45 additions and 5 deletions

View File

@ -13,21 +13,28 @@ struct ArHdr {
template <typename E>
std::vector<MemoryMappedFile<E> *>
read_thin_archive_members(Context<E> &ctx, MemoryMappedFile<E> *mb) {
u8 *data = mb->data(ctx) + 8;
u8 *begin = mb->data(ctx);
u8 *data = begin + 8;
std::vector<MemoryMappedFile<E> *> vec;
std::string_view strtab;
while (data < mb->data(ctx) + mb->size()) {
while (data < begin + mb->size()) {
// Each header is aligned to a 2 byte boundary.
if ((begin - data) % 2)
data++;
ArHdr &hdr = *(ArHdr *)data;
u8 *body = data + sizeof(hdr);
u64 size = atol(hdr.ar_size);
// Read a string table.
if (!memcmp(hdr.ar_name, "// ", 3)) {
strtab = {(char *)body, size};
data = body + size;
continue;
}
// Skip a symbol table.
if (!memcmp(hdr.ar_name, "/ ", 2)) {
data = body + size;
continue;
@ -49,11 +56,15 @@ read_thin_archive_members(Context<E> &ctx, MemoryMappedFile<E> *mb) {
template <typename E>
std::vector<MemoryMappedFile<E> *>
read_fat_archive_members(Context<E> &ctx, MemoryMappedFile<E> *mb) {
u8 *data = mb->data(ctx) + 8;
u8 *begin = mb->data(ctx);
u8 *data = begin + 8;
std::vector<MemoryMappedFile<E> *> vec;
std::string_view strtab;
while (mb->data(ctx) + mb->size() - data >= 2) {
while (begin + mb->size() - data >= 2) {
if ((begin - data) % 2)
data++;
ArHdr &hdr = *(ArHdr *)data;
u8 *body = data + sizeof(hdr);
u64 size = atol(hdr.ar_size);
@ -77,7 +88,7 @@ read_fat_archive_members(Context<E> &ctx, MemoryMappedFile<E> *mb) {
name = {hdr.ar_name, strchr(hdr.ar_name, '/')};
}
vec.push_back(mb->slice(ctx, name, body - mb->data(ctx), size));
vec.push_back(mb->slice(ctx, name, body - begin, size));
}
return vec;
}

29
test/ar-alignment.sh Executable file
View File

@ -0,0 +1,29 @@
#!/bin/bash
set -e
cd $(dirname $0)
echo -n "Testing $(basename -s .sh $0) ... "
t=$(pwd)/tmp/$(basename -s .sh $0)
mkdir -p $t
truncate -s 15 $t/a.bin
cat <<EOF | cc -o $t/b.o -c -xc -
int three() { return 3; }
EOF
cat <<EOF | cc -o $t/c.o -c -xc -
#include <stdio.h>
int three();
int main() {
printf("%d\n", three());
}
EOF
rm -f $t/d.a
ar rcs $t/d.a $t/a.bin $t/b.o
clang -fuse-ld=`pwd`/../mold -o $t/exe $t/c.o $t/d.a
echo OK