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:
parent
2d25a93126
commit
2e8bd0b7a6
@ -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());
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
18
test/elf/relocatable-many-sections.sh
Executable file
18
test/elf/relocatable-many-sections.sh
Executable 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
|
Loading…
Reference in New Issue
Block a user