Skip to content

[ELF][Objcopy] unable to locate the extended symbol index table after update-sectionΒ #168060

@Nechda

Description

@Nechda

Problem:

I'm trying to insert some data into my ELF file. To achieve this, I create a const char array with the attribute __attribute__((section(".rodata.holder"))). Then, I try to insert the data into the object file using llvm-objcopy --update-section. However, during the linking process, I get an error from the linker:

ld.lld: error: found an extended symbol index (5), but unable to locate the extended symbol index table

How to reproduce:

Step 1 : Download and build llvm 21.1.5 tools

git clone https://github.com/llvm/llvm-project.git && cd llvm-project && git checkout llvmorg-21.1.5

mkdir bld && cd bld
cmake -G Ninja -DCMAKE_BUILD_TYPE=Debug -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_ENABLE_PROJECTS="llvm;clang;lld" ../llvm
ninja clang lld llvm-objcopy

Step 2 : Put broken sources into build directory

Source examples:

// main.cpp
int External(const char*, const char*, const char*) { return 0; }
int main() { return 0; }
//lib.cpp
static __attribute__((section(".rodata.holder"))) const char resource_holder[0x1000] = {0};

int External(const char*, const char*, const char*);

static const int REG1 = External("Range1", resource_holder + 128 * 0, resource_holder + 128 * 1);
static const int REG2 = External("Range2", resource_holder + 128 * 1, resource_holder + 128 * 2);
static const int REG3 = External("Range3", resource_holder + 128 * 2, resource_holder + 128 * 3);

Generate some random binary data:

head -c 4k /dev/urandom > data.bin

Step 3 : Try to compile

./bin/clang++ lib.cpp -c -O0 -g0 -o lib.o

./bin/llvm-objcopy lib.o --update-section=.rodata.holder=data.bin

./bin/clang++ lib.o main.cpp -o a.out -fuse-ld=lld --ld-path=./bin/ld.lld
# ld.lld: error: found an extended symbol index (5), but unable to locate the extended symbol index table

Possible bug(?) explanation

I've spent some time debugging. It seems the problem is related to the code of the Object::updateSectionData function:

Error Object::updateSectionData(SecPtr &Sec, ArrayRef<uint8_t> Data) {
if (!Sec->hasContents())
return createStringError(
errc::invalid_argument,
"section '%s' cannot be updated because it does not have contents",
Sec->Name.c_str());
if (Data.size() > Sec->Size && Sec->ParentSegment)
return createStringError(errc::invalid_argument,
"cannot fit data of size %zu into section '%s' "
"with size %" PRIu64 " that is part of a segment",
Data.size(), Sec->Name.c_str(), Sec->Size);
if (!Sec->ParentSegment) {
Sec = std::make_unique<OwnedDataSection>(*Sec, Data);
} else {
// The segment writer will be in charge of updating these contents.
Sec->Size = Data.size();
UpdatedSections[Sec.get()] = Data;
}
return Error::success();
}

If we create a new section, then there will not be any calls to Object::replaceSections:

if (!Sec->ParentSegment) {
Sec = std::make_unique<OwnedDataSection>(*Sec, Data);
} else {
// The segment writer will be in charge of updating these contents.
Sec->Size = Data.size();
UpdatedSections[Sec.get()] = Data;
}

So, the symbols were not updated with the appropriate section index and an error occurred.

Could anyone tell me is it correct behaviour or we should fix it?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions