1
1
mirror of https://github.com/rui314/mold.git synced 2024-09-11 13:06:59 +03:00

Handle an output relocatable object file with a large number of sections

Fixes https://github.com/rui314/mold/issues/1061
This commit is contained in:
Rui Ueyama 2023-07-20 15:37:45 +09:00
parent 2d25a93126
commit 2e8bd0b7a6
3 changed files with 34 additions and 9 deletions

View File

@ -180,7 +180,7 @@ void ObjectFile<E>::initialize_sections(Context<E> &ctx) {
std::string_view signature;
if (esym.st_type == STT_SECTION) {
signature = this->shstrtab.data() +
this->elf_sections[esym.st_shndx].sh_name;
this->elf_sections[get_shndx(esym)].sh_name;
} else {
signature = this->symbol_strtab.data() + esym.st_name;
}
@ -206,10 +206,8 @@ void ObjectFile<E>::initialize_sections(Context<E> &ctx) {
comdat_groups.push_back({group, (u32)i, entries.subspan(1)});
break;
}
case SHT_SYMTAB_SHNDX:
symtab_shndx_sec = this->template get_data<U32<E>>(ctx, shdr);
break;
case SHT_SYMTAB:
case SHT_SYMTAB_SHNDX:
case SHT_STRTAB:
case SHT_REL:
case SHT_RELA:
@ -866,6 +864,9 @@ void ObjectFile<E>::parse(Context<E> &ctx) {
this->first_global = symtab_sec->sh_info;
this->elf_syms = this->template get_data<ElfSym<E>>(ctx, *symtab_sec);
this->symbol_strtab = this->get_string(ctx, symtab_sec->sh_link);
if (ElfShdr<E> *shdr = this->find_section(SHT_SYMTAB_SHNDX))
symtab_shndx_sec = this->template get_data<U32<E>>(ctx, *shdr);
}
initialize_sections(ctx);
@ -1189,8 +1190,7 @@ void ObjectFile<E>::populate_symtab(Context<E> &ctx) {
auto write_sym = [&](Symbol<E> &sym, i64 &symtab_idx) {
U32<E> *xindex = nullptr;
if (ctx.symtab_shndx)
xindex = (U32<E> *)(ctx.buf + ctx.symtab_shndx->shdr.sh_offset +
symtab_idx * 4);
xindex = (U32<E> *)(ctx.buf + ctx.symtab_shndx->shdr.sh_offset) + symtab_idx;
symtab_base[symtab_idx++] = to_output_esym(ctx, sym, strtab_off, xindex);
strtab_off += write_string(strtab_base + strtab_off, sym.name());
@ -1493,8 +1493,8 @@ void SharedFile<E>::populate_symtab(Context<E> &ctx) {
U32<E> *xindex = nullptr;
if (ctx.symtab_shndx)
xindex = (U32<E> *)(ctx.buf + ctx.symtab_shndx->shdr.sh_offset +
(this->global_symtab_idx + i) * 4);
xindex = (U32<E> *)(ctx.buf + ctx.symtab_shndx->shdr.sh_offset) +
this->global_symtab_idx + i;
*symtab++ = to_output_esym(ctx, sym, strtab_off, xindex);
strtab_off += write_string(strtab + strtab_off, sym.name());

View File

@ -652,7 +652,14 @@ void SymtabSection<E>::copy_buf(Context<E> &ctx) {
memset(&sym, 0, sizeof(sym));
sym.st_type = STT_SECTION;
sym.st_value = chunk->shdr.sh_addr;
sym.st_shndx = chunk->shndx;
if (ctx.symtab_shndx) {
U32<E> *xindex = (U32<E> *)(ctx.buf + ctx.symtab_shndx->shdr.sh_offset);
xindex[chunk->shndx] = chunk->shndx;
sym.st_shndx = SHN_XINDEX;
} else {
sym.st_shndx = chunk->shndx;
}
}
}

View File

@ -0,0 +1,18 @@
#!/bin/bash
. $(dirname $0)/common.inc
seq 1 80000 | sed 's/.*/.section .data.\0,"aw"\n.word 0\n/g' | \
$CC -c -xassembler -o $t/a.o -
cat <<'EOF' | $CC -c -xc -o $t/b.o -
#include <stdio.h>
int main() {
printf("Hello\n");
return 0;
}
EOF
./mold -r -o $t/c.o $t/a.o $t/b.o
$CC -B. -o $t/exe $t/c.o
$QEMU $t/exe | grep -q Hello