[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Tinycc-devel] Argh! No PIE on musl libC (i give up)

From: Steffen Nurpmeso
Subject: [Tinycc-devel] Argh! No PIE on musl libC (i give up)
Date: Thu, 05 Oct 2017 22:41:23 +0200
User-agent: s-nail v14.9.4


You know, i have zero knowledge on ELF a.k.a. involved problems.
The standard is laying around since many years (download 2012), but
i never made it.  With the current port of tcc the executables are
real executables and therefore not PIE enabled.  musl ldd(1)
cannot even dig them, which i do not consider soo bad since the
pcc(1) port comes out the very same though:

  address@hidden tmp]$ ldd z-tcc
  ldd: z-tcc: Not a valid dynamic program

But so i tried a simple-minded approach which surprisingly simple
ends up as

  diff --git a/tccelf.c b/tccelf.c
  index 225cd9d..b34efdc 100644
  --- a/tccelf.c
  +++ b/tccelf.c
  @@ -1529,10 +1529,13 @@ static int layout_sections(TCCState *s1, ElfW(Phdr) 
*phdr, int phnum,
                   a_offset += s_align;
               file_offset += (a_offset - p_offset);
           } else {
  -            if (file_type == TCC_OUTPUT_DLL)
  -                addr = 0;
  -            else
  +            /* musl uses PIE by treating (complying) exes as shared 
libraries */
  +#ifndef TCC_MUSL
  +            if (file_type != TCC_OUTPUT_DLL)
                   addr = ELF_START_ADDR;
  +            else
  +                addr = 0;
               /* compute address after headers */
               addr += (file_offset & (s_align - 1));
  @@ -1853,7 +1856,11 @@ static void tcc_output_elf(TCCState *s1, FILE *f, int 
phnum, ElfW(Phdr) *phdr,
       switch(file_type) {
       case TCC_OUTPUT_EXE:
  +#ifdef TCC_MUSL
  +        ehdr.e_type = ET_DYN;
           ehdr.e_type = ET_EXEC;
           ehdr.e_entry = get_elf_sym_addr(s1, "_start", 1);
       case TCC_OUTPUT_DLL:

and it creates a running program just fine and ldd digs it

  address@hidden tmp]$ ldd zt
        /lib/ld-musl-x86_64.so.1 (0x636b87d68000)
        libc.musl-x86_64.so.1 => /lib/ld-musl-x86_64.so.1 (0x636b87d68000)

(i cannot test whether TEXT is really PI since /proc/X/maps is all
0 on GRSEC, even for root, terrible..), and ldd(1) now gives the
right results even for complicated executables.  However i get
crashes and it seems that tcc does support getgot etc., but the
addresses used are false and thus result in a crash for symbols
local to the executable.  For example, the simple

  #include <stdio.h>
  struct a_amv_var_defval{
     unsigned int avdv_okey; 
     unsigned char avdv__pad[4];
     char const *avdv_value;
  void heu(void);
  static char const w[8] = "ok";
  static struct a_amv_var_defval x = {100,{0,},"ab"};
  int main(void){heu();return 0;}
  void heu(void){
    fprintf(stderr, "%s\n", w);
    fprintf(stderr, "%s\n", x.avdv_value);


  address@hidden tmp]$ ./zt                                                     
  Segmentation fault

However, if i split out the data into its own file

  struct a_amv_var_defval{
     unsigned int avdv_okey; 
     unsigned char avdv__pad[4];
     char const *avdv_value;
  extern char const w[8];
  char const w[8] = "ok";
  extern struct a_amv_var_defval x;
  struct a_amv_var_defval x = {100,{0,},"ab"};

create a shared library of that (with non-tcc, i have segv there)
and link it in

  $ LD_RUN_PATH=`pwd` tcc -o zt t.c -L./ -lt2

i get a valid executable.  So my, excuse me please, very
simple-minded question is, what is necessary to get those symbols
placed right.  In fact the code seems to be pretty equal.
Has anybody a quick and dirty idea and/or real solution for this?
Would be cool!

|Der Kragenbaer,                The moon bear,
|der holt sich munter           he cheerfully and one by one
|einen nach dem anderen runter  wa.ks himself off
|(By Robert Gernhardt)

reply via email to

[Prev in Thread] Current Thread [Next in Thread]