mirror of
https://github.com/rui314/mold.git
synced 2024-12-24 17:01:50 +03:00
Handle ar header alignment correctly
This commit is contained in:
parent
83b14328ec
commit
7a689d8361
@ -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
29
test/ar-alignment.sh
Executable 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
|
Loading…
Reference in New Issue
Block a user