Skip to content

x86 regression: incorrect ELF relocation for llvm.memset and some other builtins #51078

@llvmbot

Description

@llvmbot
Bugzilla Link 51736
Version 12.0
OS Linux
Reporter LLVM Bugzilla Contributor
CC @topperc,@DimitryAndric,@MaskRay,@RKSimon

Extended Description

Consider the following C code:

#include <string.h>

void *
test_memset(void *p, int c, size_t len) {
        return (memset(p, c, len));
}

void *
test_memcpy(void *dst, const void *src, size_t len) {
        return (memcpy(dst, src, len));
}

void *
test_memmove(void *dst, const void *src, size_t len) {
        return (memmove(dst, src, len));
}

When compiled with "clang12 -c test.c -m32" (so targeting x86) the resulting ELF object file has the following relocations (readelf -r test.o):

r_offset r_info   r_type              st_value st_name
0000002c 00000504 R_386_PLT32         00000000 memset
00000067 00000304 R_386_PLT32         00000000 memcpy
000000a7 00000402 R_386_PC32          00000000 memmove

With clang11:

00000036 00000502 R_386_PC32          00000000 memset
00000083 00000302 R_386_PC32          00000000 memcpy
000000d2 00000402 R_386_PC32          00000000 memmove

Note how memset and memcpy (also __stack_chk_fail) are R_386_PLT32 with clang12. When the object file is linked into a shared object (clang -shared -o libtest.so test.o -z notext) these relocations are converted to PLT entries that depend on a PIC register (%ebx) which isn't valid because the code hasn't been compiled with -fPIC so test_memset and test_memcpy tend to crash. They work fine when compiled with clang11.

The .ll code generated by both clang11 and clang12 is the same so the problem must be in LLVM somewhere.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions