1
1
mirror of https://github.com/rui314/mold.git synced 2024-09-20 17:39:56 +03:00

Do not create a .gdb_index section if there's no debug info section

This commit is contained in:
Rui Ueyama 2022-05-13 11:31:53 +08:00
parent 61d19e65e2
commit 2e47fe5815
2 changed files with 53 additions and 20 deletions

View File

@ -2125,6 +2125,8 @@ template <typename E>
void GdbIndexSection<E>::construct(Context<E> &ctx) {
Timer t(ctx, "GdbIndexSection::construct");
std::atomic_bool has_debug_info = false;
// Read debug sections
tbb::parallel_for_each(ctx.objs, [&](ObjectFile<E> *file) {
if (file->debug_info) {
@ -2133,9 +2135,13 @@ void GdbIndexSection<E>::construct(Context<E> &ctx) {
// Count the number of address areas contained in this file.
file->num_areas = estimate_address_areas(ctx, *file);
has_debug_info = true;
}
});
if (!has_debug_info)
return;
// Initialize `area_offset` and `compunits_idx`.
for (i64 i = 0; i < ctx.objs.size() - 1; i++) {
ctx.objs[i + 1]->area_offset =
@ -2325,6 +2331,10 @@ void GdbIndexSection<E>::copy_buf(Context<E> &ctx) {
template <typename E>
void GdbIndexSection<E>::write_address_areas(Context<E> &ctx) {
Timer t(ctx, "GdbIndexSection::write_address_areas");
if (this->shdr.sh_size == 0)
return;
u8 *base = ctx.buf + this->shdr.sh_offset;
for (Chunk<E> *chunk : ctx.chunks) {
@ -2341,6 +2351,9 @@ void GdbIndexSection<E>::write_address_areas(Context<E> &ctx) {
ctx.debug_rnglists = chunk;
}
assert(ctx.debug_info);
assert(ctx.debug_abbrev);
struct Entry {
ul64 start;
ul64 end;
@ -2349,33 +2362,32 @@ void GdbIndexSection<E>::write_address_areas(Context<E> &ctx) {
// Read address ranges from debug sections and copy them to .gdb_index.
tbb::parallel_for_each(ctx.objs, [&](ObjectFile<E> *file) {
if (!file->debug_info)
return;
Entry *begin = (Entry *)(base + header.areas_offset + file->area_offset);
Entry *e = begin;
u64 offset = file->debug_info->offset;
if (file->debug_info && ctx.debug_abbrev) {
for (i64 i = 0; i < file->compunits.size(); i++) {
std::vector<u64> addrs = read_address_areas(ctx, *file, offset);
u64 offset = file->debug_info->offset;
for (i64 j = 0; j < addrs.size(); j += 2) {
// Skip an empty range
if (addrs[j] == addrs[j + 1])
continue;
for (i64 i = 0; i < file->compunits.size(); i++) {
std::vector<u64> addrs = read_address_areas(ctx, *file, offset);
// Gdb crashes if there are entries with address 0.
if (addrs[j] == 0)
continue;
for (i64 j = 0; j < addrs.size(); j += 2) {
// Skip an empty range
if (addrs[j] == addrs[j + 1])
continue;
// Gdb crashes if there are entries with address 0.
if (addrs[j] == 0)
continue;
assert(e < begin + file->num_areas);
e->start = addrs[j];
e->end = addrs[j + 1];
e->attr = file->compunits_idx + i;
e++;
}
offset += file->compunits[i].size();
assert(e < begin + file->num_areas);
e->start = addrs[j];
e->end = addrs[j + 1];
e->attr = file->compunits_idx + i;
e++;
}
offset += file->compunits[i].size();
}
// Fill trailing null entries with dummy values because gdb

21
test/elf/gdb-index-empty.sh Executable file
View File

@ -0,0 +1,21 @@
#!/bin/bash
export LC_ALL=C
set -e
CC="${TEST_CC:-cc}"
CXX="${TEST_CXX:-c++}"
GCC="${TEST_GCC:-gcc}"
GXX="${TEST_GXX:-g++}"
OBJDUMP="${OBJDUMP:-objdump}"
MACHINE="${MACHINE:-$(uname -m)}"
testname=$(basename "$0" .sh)
echo -n "Testing $testname ... "
cd "$(dirname "$0")"/../..
t=out/test/elf/$testname
mkdir -p $t
echo 'void _start() {}' | $CC -c -o $t/a.o -xc -
./mold -o $t/exe $t/a.o -gdb-index
readelf -WS $t/exe > $t/log
! fgrep -q .gdb_index $t/log || false
echo OK