Stream: git-cranelift

Topic: cranelift / Issue #1354 segfault before main on alpine linux


view this post on Zulip GitHub (Jan 17 2020 at 04:03):

jyn514 opened Issue #1354:

This code works fine on Ubuntu 18.04. Note that the segfault comes before main.

I am using cranelift, cranelift-object, cranelift-module 0.54.

function u0:0() -> i32 system_v {
    gv0 = symbol colocated u1:0
    sig0 = (i64) -> i32 system_v
    fn0 = u0:0 sig0

ebb0:
    v0 = global_value.i64 gv0
    v1 = load.i64 v0
    v2 = call fn0(v1)
    v3 = iconst.i32 0
    return v3
}
$ target/debug/rcc
int puts(const char *s);
static const char *index_page = "index.html";
int main() {
    puts(index_page);
}
$ ./a.out
Segmentation fault
$ gdb
(gdb) break main
Breakpoint 1 at 0x119a
(gdb) run
Starting program: /home/joshua/src/rcc/a.out

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7fc408c in ?? () from /lib/ld-musl-x86_64.so.1
(gdb) where
#0  0x00007ffff7fc408c in ?? () from /lib/ld-musl-x86_64.so.1
#1  0x0000000000000000 in ?? ()
$ target/debug/rcc -c -o a.o  # this means compile to object file but don't link
int puts(const char *s);
static const char *index_page = "index.html";
int main() {
    puts(index_page);
}
$ objdump -rd a.o

a.o:     file format elf64-x86-64


Disassembly of section .text:

0000000000000000 <main>:
   0:   40 55                   rex push %rbp
   2:   48 89 e5                mov    %rsp,%rbp
   5:   48 8d 05 00 00 00 00    lea    0x0(%rip),%rax        # c <main+0xc>
            8: R_X86_64_PC32    index_page-0x4
   c:   48 8b 00                mov    (%rax),%rax
   f:   48 89 c7                mov    %rax,%rdi
  12:   e8 00 00 00 00          callq  17 <main+0x17>
            13: R_X86_64_PLT32  puts-0x4
  17:   40 b8 00 00 00 00       rex mov $0x0,%eax
  1d:   40 5d                   rex pop %rbp
  1f:   c3                      retq

cc @philipc

view this post on Zulip GitHub (Jan 17 2020 at 04:12):

philipc commented on Issue #1354:

Did this previously work with faerie?

view this post on Zulip GitHub (Jan 17 2020 at 04:14):

jyn514 commented on Issue #1354:

This has something to do with the Linkage, if I remove static it works. Let me double check but I think I use Local with static and Export otherwise.

view this post on Zulip GitHub (Jan 17 2020 at 04:17):

jyn514 commented on Issue #1354:

@philipc that would have been smart to check! This also does not work with faerie 0.51.

view this post on Zulip GitHub (Jan 17 2020 at 04:20):

jyn514 commented on Issue #1354:

I take it back, this is unrelated to the linkage, it's because of the const keyword. I mark data as read only if it has const set, could that have an impact?

view this post on Zulip GitHub (Jan 17 2020 at 06:00):

philipc commented on Issue #1354:

It might be that index_page is being put in a read only segment, but it is a pointer that needs a relocation, so processing the relocation needs to write to that memory.

I haven't looked into this much, but gcc puts index_page in .data.rel.local and clang-8 puts it in .data.

view this post on Zulip GitHub (Jan 17 2020 at 06:06):

philipc commented on Issue #1354:

So this is probably a bug in object. For ELF, it selects .rodata for StandardSection::ReadOnlyDataWithRel. I think that should be .data. Not sure why it works on ubuntu though, something I need to look into more.

view this post on Zulip GitHub (Jan 17 2020 at 10:56):

jyn514 commented on Issue #1354:

Sorry, I forgot to mention: rcc currently parses const qualifiers wrong, if you want to compare this to gcc or clang use char *const index_page = "index.html; or you'll be comparing apples to oranges.

const *p means a mutable pointer to const data, *const p means an immutable pointer to mutable data. I currently get it backwards but both should be valid.

That said I think you are right, clang and GCC both put *const in .data.rel.ro.

view this post on Zulip GitHub (Jan 17 2020 at 10:56):

jyn514 edited a comment on Issue #1354:

Sorry, I forgot to mention: rcc currently parses const qualifiers wrong, if you want to compare this to gcc or clang use char *const index_page = "index.html"; or you'll be comparing apples to oranges.

const *p means a mutable pointer to const data, *const p means an immutable pointer to mutable data. I currently get it backwards but both should be valid.

That said I think you are right, clang and GCC both put *const in .data.rel.ro.


Last updated: Dec 23 2024 at 13:07 UTC