Alien-TinyCC

 view release on metacpan or  search on metacpan

lib/Alien/TinyCC.pm  view on Meta::CPAN


gives the full path to the diretory containing F<libtcc.h>

=item libtcc_library_path

gives the full path to the directory containing F<libtcc.dll> or F<libtcc.a>

=back

If you want to link against F<libtcc>, you will need to include C<Alien::TinyCC>
in your F<.pm> file that loads your XS bindings, to ensure that the
C<PATH> or C<LD_LIBRARY_PATH> is properly set. Then, in your F<Build.PL>
file, you can use

=over

=item MB_linker_flags

gives the proper list of arguments to link against F<libtcc>.

=back

lib/Alien/TinyCC.pm  view on Meta::CPAN


This library was built specifically to be used by the C code system provided
by L<C::TinyCompiler>.

=head1 AUTHOR

David Mertens (dcmertens.perl@gmail.com)

=head1 BUGS

Please report any bugs or feature requests for the Alien bindings at the
project's main github page:
L<http://github.com/run4flat/Alien-TinyCC/issues>.

=head1 SUPPORT

You can find documentation for this module with the perldoc command.

    perldoc Alien::TinyCC

You can also look for information at:

src/Makefile  view on Meta::CPAN

TCC_INCLUDES = stdarg.h stddef.h stdbool.h float.h varargs.h
INSTALL=install
ifdef STRIP_BINARIES
INSTALLBIN=$(INSTALL) -s
else
INSTALLBIN=$(INSTALL)
endif

ifndef CONFIG_WIN32
install: $(PROGS) $(TCCLIBS) $(TCCDOCS)
	mkdir -p "$(bindir)"
ifeq ($(CC),tcc)
	$(INSTALL) -m755 $(PROGS) "$(bindir)"
else
	$(INSTALLBIN) -m755 $(PROGS) "$(bindir)"
endif
	mkdir -p "$(mandir)/man1"
	-$(INSTALL) tcc.1 "$(mandir)/man1"
	mkdir -p "$(infodir)"
	-$(INSTALL) tcc-doc.info "$(infodir)"
	mkdir -p "$(tccdir)"
	mkdir -p "$(tccdir)/include"
ifneq ($(LIBTCC1),)
	$(INSTALL) -m644 $(LIBTCC1) "$(tccdir)"
endif

src/Makefile  view on Meta::CPAN

	cp -r "$(tccdir)/include" "$(tccdir)/i386"
endif
	$(INSTALL) -m644 $(top_srcdir)/win32/lib/*.def "$(tccdir)/win32/lib"
	$(INSTALL) -m644 lib/i386-win32/libtcc1.a "$(tccdir)/win32/lib/32"
	$(INSTALL) -m644 lib/x86_64-win32/libtcc1.a "$(tccdir)/win32/lib/64"
	cp -r $(top_srcdir)/win32/include/. "$(tccdir)/win32/include"
	cp -r $(top_srcdir)/include/. "$(tccdir)/win32/include"
endif

uninstall:
	rm -fv $(foreach P,$(PROGS),"$(bindir)/$P")
	rm -fv $(foreach P,$(LIBTCC1),"$(tccdir)/$P")
	rm -fv $(foreach P,$(TCC_INCLUDES),"$(tccdir)/include/$P")
	rm -fv "$(tccdir)/include/tcclib.h"
	rm -fv "$(docdir)/tcc-doc.html" "$(mandir)/man1/tcc.1" "$(infodir)/tcc-doc.info"
	rm -fv "$(libdir)/$(LIBTCC)" "$(includedir)/libtcc.h"
	rm -fv "$(libdir)/libtcc.so*"
	rm -rf "$(tccdir)/win32"
	-rmdir $(tccdir)/include
ifeq ($(ARCH),x86-64)
	rm -rf "$(tccdir)/i386"

src/configure  view on Meta::CPAN


TMPN="./conftest-$$"
TMPH=$TMPN.h

# default parameters
build_cross="no"
use_libgcc="no"
enable_assert="no"
prefix=""
execprefix=""
bindir=""
libdir=""
tccdir=""
includedir=""
mandir=""
infodir=""
sysroot=""
cross_prefix=""
cc="gcc"
host_cc="gcc"
ar="ar"

src/configure  view on Meta::CPAN


for opt do
  eval opt=\"$opt\"
  case "$opt" in
  --prefix=*) prefix=`echo $opt | cut -d '=' -f 2`
  ;;
  --exec-prefix=*) execprefix=`echo $opt | cut -d '=' -f 2`
  ;;
  --tccdir=*) tccdir=`echo $opt | cut -d '=' -f 2`
  ;;
  --bindir=*) bindir=`echo $opt | cut -d '=' -f 2`
  ;;
  --libdir=*) libdir=`echo $opt | cut -d '=' -f 2`
  ;;
  --includedir=*) includedir=`echo $opt | cut -d '=' -f 2`
  ;;
  --sharedir=*) sharedir=`echo $opt | cut -d '=' -f 2`
  ;;
  --mandir=*) mandir=`echo $opt | cut -d '=' -f 2`
  ;;
  --infodir=*) infodir=`echo $opt | cut -d '=' -f 2`

src/configure  view on Meta::CPAN

    if test x"$tccdir" = x""; then
    tccdir="tcc"
    fi
    if test -z "$prefix" ; then
    prefix="C:/Program Files/${tccdir}"
    fi
    if test -z "$sharedir" ; then
    sharedir="${prefix}"
    fi
    execprefix="$prefix"
    bindir="${prefix}"
    tccdir="${prefix}"
    libdir="${prefix}/lib"
    docdir="${sharedir}/doc"
    mandir="${sharedir}/man"
    infodir="${sharedir}/info"
    LIBSUF=".lib"
    EXESUF=".exe"
else
    if test -z "$prefix" ; then
    prefix="/usr/local"
    fi
    if test -z "$sharedir" ; then
    sharedir="${prefix}/share"
    fi
    if test x"$execprefix" = x""; then
    execprefix="${prefix}"
    fi
    if test x"$libdir" = x""; then
    libdir="${execprefix}/lib"
    fi
    if test x"$bindir" = x""; then
    bindir="${execprefix}/bin"
    fi
    if test x"$tccdir" = x""; then
    tccdir="tcc"
    fi
    if test x"$docdir" = x""; then
    docdir="${sharedir}/doc/${tccdir}"
    fi
    if test x"$mandir" = x""; then
    mandir="${sharedir}/man"
    fi

src/configure  view on Meta::CPAN

if test x"$show_help" = "xyes" ; then
cat << EOF
Usage: configure [options]
Options: [defaults in brackets after descriptions]

Standard options:
  --help                   print this message
  --prefix=PREFIX          install in PREFIX [$prefix]
  --exec-prefix=EPREFIX    install architecture-dependent files in EPREFIX
                           [same as prefix]
  --bindir=DIR             user executables in DIR [EPREFIX/bin]
  --libdir=DIR             object code libraries in DIR [EPREFIX/lib]
  --tccdir=DIR             installation directory [EPREFIX/lib/tcc]
  --includedir=DIR         C header files in DIR [PREFIX/include]
  --sharedir=DIR           documentation root DIR [PREFIX/share]
  --docdir=DIR             documentation in DIR [SHAREDIR/doc/tcc]
  --mandir=DIR             man documentation in DIR [SHAREDIR/man]
  --infodir=DIR            info documentation in DIR [SHAREDIR/info]

Advanced options (experts only):
  --source-path=PATH       path of source code [$source_path]

src/configure  view on Meta::CPAN

    fi
  fi
else
  # if cross compiling, cannot launch a program, so make a static guess
  case $cpu in
    powerpc|mips|s390)  bigendian=yes;;
  esac
fi

cat <<EOF
Binary  directory   $bindir
TinyCC directory    $tccdir
Library directory   $libdir
Include directory   $includedir
Manual directory    $mandir
Info directory      $infodir
Doc directory       $docdir
Target root prefix  $sysroot
Source path      $source_path
C compiler       $cc
Target OS        $targetos

src/configure  view on Meta::CPAN

gprof enabled    $gprof
cross compilers  $build_cross
use libgcc       $use_libgcc
EOF

echo "Creating config.mak and config.h"

cat >config.mak <<EOF
# Automatically generated by configure - do not modify
prefix=$prefix
bindir=\$(DESTDIR)$bindir
tccdir=\$(DESTDIR)$tccdir
libdir=\$(DESTDIR)$libdir
ln_libdir=$libdir
includedir=\$(DESTDIR)$includedir
mandir=\$(DESTDIR)$mandir
infodir=\$(DESTDIR)$infodir
docdir=\$(DESTDIR)$docdir
CC=$cc
GCC_MAJOR=$gcc_major
GCC_MINOR=$gcc_minor

src/elf.h  view on Meta::CPAN

#define SHF_ORDERED     0x40000000
#define SHF_EXCLUDE     0x80000000

/* Symbol table entry.  */

typedef struct
{
  Elf32_Word    st_name;                /* Symbol name (string tbl index) */
  Elf32_Addr    st_value;               /* Symbol value */
  Elf32_Word    st_size;                /* Symbol size */
  unsigned char st_info;                /* Symbol type and binding */
  unsigned char st_other;               /* No defined meaning, 0 */
  Elf32_Section st_shndx;               /* Section index */
} Elf32_Sym;

typedef struct
{
  Elf64_Word    st_name;                /* Symbol name (string tbl index) */
  unsigned char st_info;                /* Symbol type and binding */
  unsigned char st_other;               /* No defined meaning, 0 */
  Elf64_Section st_shndx;               /* Section index */
  Elf64_Addr    st_value;               /* Symbol value */
  Elf64_Xword   st_size;                /* Symbol size */
} Elf64_Sym;

/* The syminfo section if available contains additional information about
   every dynamic symbol.  */

typedef struct
{
  Elf32_Half si_boundto;                /* Direct bindings, symbol bound to */
  Elf32_Half si_flags;                  /* Per symbol flags */
} Elf32_Syminfo;

typedef struct
{
  Elf64_Half si_boundto;                /* Direct bindings, symbol bound to */
  Elf64_Half si_flags;                  /* Per symbol flags */
} Elf64_Syminfo;

/* Possible values for si_boundto.  */
#define SYMINFO_BT_SELF         0xffff  /* Symbol bound to self */
#define SYMINFO_BT_PARENT       0xfffe  /* Symbol bound to parent */
#define SYMINFO_BT_LOWRESERVE   0xff00  /* Beginning of reserved entries */

/* Possible bitmasks for si_flags.  */
#define SYMINFO_FLG_DIRECT      0x0001  /* Direct bound symbol */

src/elf.h  view on Meta::CPAN



/* Special section index.  */

#define SHN_UNDEF       0               /* No section, undefined symbol.  */

/* How to extract and insert information held in the st_info field.  */

#define ELF32_ST_BIND(val)              (((unsigned char) (val)) >> 4)
#define ELF32_ST_TYPE(val)              ((val) & 0xf)
#define ELF32_ST_INFO(bind, type)       (((bind) << 4) + ((type) & 0xf))

/* Both Elf32_Sym and Elf64_Sym use the same one-byte st_info field.  */
#define ELF64_ST_BIND(val)              ELF32_ST_BIND (val)
#define ELF64_ST_TYPE(val)              ELF32_ST_TYPE (val)
#define ELF64_ST_INFO(bind, type)       ELF32_ST_INFO ((bind), (type))

/* Legal values for ST_BIND subfield of st_info (symbol binding).  */

#define STB_LOCAL       0               /* Local symbol */
#define STB_GLOBAL      1               /* Global symbol */
#define STB_WEAK        2               /* Weak symbol */
#define STB_NUM         3               /* Number of defined types.  */
#define STB_LOOS        10              /* Start of OS-specific */
#define STB_HIOS        12              /* End of OS-specific */
#define STB_LOPROC      13              /* Start of processor-specific */
#define STB_HIPROC      15              /* End of processor-specific */

src/libtcc.c  view on Meta::CPAN

    /* sections are created as PROGBITS */
    return new_section(s1, name, SHT_PROGBITS, SHF_ALLOC);
}

/* update sym->c so that it points to an external symbol in section
   'section' with value 'value' */
ST_FUNC void put_extern_sym2(Sym *sym, Section *section, 
                            addr_t value, unsigned long size,
                            int can_add_underscore)
{
    int sym_type, sym_bind, sh_num, info, other;
    ElfW(Sym) *esym;
    const char *name;
    char buf1[256];

    if (section == NULL)
        sh_num = SHN_UNDEF;
    else if (section == SECTION_ABS) 
        sh_num = SHN_ABS;
    else
        sh_num = section->sh_num;

    if ((sym->type.t & VT_BTYPE) == VT_FUNC) {
        sym_type = STT_FUNC;
    } else if ((sym->type.t & VT_BTYPE) == VT_VOID) {
        sym_type = STT_NOTYPE;
    } else {
        sym_type = STT_OBJECT;
    }

    if (sym->type.t & VT_STATIC)
        sym_bind = STB_LOCAL;
    else {
        if (sym->type.t & VT_WEAK)
            sym_bind = STB_WEAK;
        else
            sym_bind = STB_GLOBAL;
    }

    if (!sym->c) {
        name = get_tok_str(sym->v, NULL);
#ifdef CONFIG_TCC_BCHECK
        if (tcc_state->do_bounds_check) {
            char buf[32];

            /* XXX: avoid doing that for statics ? */
            /* if bound checking is activated, we change some function

src/libtcc.c  view on Meta::CPAN

        }
#endif
        if (tcc_state->leading_underscore && can_add_underscore) {
            buf1[0] = '_';
            pstrcpy(buf1 + 1, sizeof(buf1) - 1, name);
            name = buf1;
        }
        if (sym->asm_label) {
            name = sym->asm_label;
        }
        info = ELFW(ST_INFO)(sym_bind, sym_type);
        sym->c = add_elf_sym(symtab_section, value, size, info, other, sh_num, name);
    } else {
        esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
        esym->st_value = value;
        esym->st_size = size;
        esym->st_shndx = sh_num;
    }
}

ST_FUNC void put_extern_sym(Sym *sym, Section *section, 

src/tccelf.c  view on Meta::CPAN

    return (void*)get_elf_sym_addr(s, name, 1);
}
#endif

/* add an elf symbol : check if it is already defined and patch
   it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
ST_FUNC int add_elf_sym(Section *s, addr_t value, unsigned long size,
                       int info, int other, int sh_num, const char *name)
{
    ElfW(Sym) *esym;
    int sym_bind, sym_index, sym_type, esym_bind;
    unsigned char sym_vis, esym_vis, new_vis;

    sym_bind = ELFW(ST_BIND)(info);
    sym_type = ELFW(ST_TYPE)(info);
    sym_vis = ELFW(ST_VISIBILITY)(other);
        
    if (sym_bind != STB_LOCAL) {
        /* we search global or weak symbols */
        sym_index = find_elf_sym(s, name);
        if (!sym_index)
            goto do_def;
        esym = &((ElfW(Sym) *)s->data)[sym_index];
        if (esym->st_shndx != SHN_UNDEF) {
            esym_bind = ELFW(ST_BIND)(esym->st_info);
            /* propagate the most constraining visibility */
            /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
            esym_vis = ELFW(ST_VISIBILITY)(esym->st_other);
            if (esym_vis == STV_DEFAULT) {
                new_vis = sym_vis;
            } else if (sym_vis == STV_DEFAULT) {
                new_vis = esym_vis;
            } else {
                new_vis = (esym_vis < sym_vis) ? esym_vis : sym_vis;
            }
            esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1))
                             | new_vis;
            other = esym->st_other; /* in case we have to patch esym */
            if (sh_num == SHN_UNDEF) {
                /* ignore adding of undefined symbol if the
                   corresponding symbol is already defined */
            } else if (sym_bind == STB_GLOBAL && esym_bind == STB_WEAK) {
                /* global overrides weak, so patch */
                goto do_patch;
            } else if (sym_bind == STB_WEAK && esym_bind == STB_GLOBAL) {
                /* weak is ignored if already global */
            } else if (sym_bind == STB_WEAK && esym_bind == STB_WEAK) {
                /* keep first-found weak definition, ignore subsequents */
            } else if (sym_vis == STV_HIDDEN || sym_vis == STV_INTERNAL) {
                /* ignore hidden symbols after */
            } else if (esym->st_shndx == SHN_COMMON
                    && (sh_num < SHN_LORESERVE || sh_num == SHN_COMMON)) {
                /* gr: Happens with 'tcc ... -static tcctest.c' on e.g. Ubuntu 6.01
                   No idea if this is the correct solution ... */
                goto do_patch;
            } else if (s == tcc_state->dynsymtab_section) {
                /* we accept that two DLL define the same symbol */
            } else {
#if 0
                printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
                       sym_bind, sh_num, new_vis, esym_bind, esym->st_shndx, esym_vis);
#endif
                tcc_error_noabort("'%s' defined twice", name);
            }
        } else {
        do_patch:
            esym->st_info = ELFW(ST_INFO)(sym_bind, sym_type);
            esym->st_shndx = sh_num;
            new_undef_sym = 1;
            esym->st_value = value;
            esym->st_size = size;
            esym->st_other = other;
        }
    } else {
    do_def:
        sym_index = put_elf_sym(s, value, size, 
                                ELFW(ST_INFO)(sym_bind, sym_type), other, 
                                sh_num, name);
    }
    return sym_index;
}

/* put relocation */
ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
                          int type, int symbol)
{
    char buf[256];

src/tccelf.c  view on Meta::CPAN

            bss_section->data_offset = offset;
        }
    }
}

/* relocate symbol table, resolve undefined symbols if do_resolve is
   true and output error if undefined symbol. */
ST_FUNC void relocate_syms(TCCState *s1, int do_resolve)
{
    ElfW(Sym) *sym, *esym, *sym_end;
    int sym_bind, sh_num, sym_index;
    const char *name;

    sym_end = (ElfW(Sym) *)(symtab_section->data + symtab_section->data_offset);
    for(sym = (ElfW(Sym) *)symtab_section->data + 1; 
        sym < sym_end;
        sym++) {
        sh_num = sym->st_shndx;
        if (sh_num == SHN_UNDEF) {
            name = strtab_section->data + sym->st_name;
            if (do_resolve) {

src/tccelf.c  view on Meta::CPAN

                    sym->st_value = esym->st_value;
                    goto found;
                }
            }
            /* XXX: _fp_hw seems to be part of the ABI, so we ignore
               it */
            if (!strcmp(name, "_fp_hw"))
                goto found;
            /* only weak symbols are accepted to be undefined. Their
               value is zero */
            sym_bind = ELFW(ST_BIND)(sym->st_info);
            if (sym_bind == STB_WEAK) {
                sym->st_value = 0;
            } else {
                tcc_error_noabort("undefined symbol '%s'", name);
            }
        } else if (sh_num < SHN_LORESERVE) {
            /* add section base */
            sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
        }
    found: ;
    }

src/tccelf.c  view on Meta::CPAN

}

#ifndef TCC_TARGET_PE
/* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
   is referenced by the user (so it should be added as DT_NEEDED in
   the generated ELF file) */
ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
{ 
    ElfW(Ehdr) ehdr;
    ElfW(Shdr) *shdr, *sh, *sh1;
    int i, j, nb_syms, nb_dts, sym_bind, ret;
    ElfW(Sym) *sym, *dynsym;
    ElfW(Dyn) *dt, *dynamic;
    unsigned char *dynstr;
    const char *name, *soname;
    DLLReference *dllref;
    
    read(fd, &ehdr, sizeof(ehdr));

    /* test CPU specific stuff */
    if (ehdr.e_ident[5] != ELFDATA2LSB ||

src/tccelf.c  view on Meta::CPAN

    //    printf("loading dll '%s'\n", soname);

    /* add the dll and its level */
    dllref = tcc_mallocz(sizeof(DLLReference) + strlen(soname));
    dllref->level = level;
    strcpy(dllref->name, soname);
    dynarray_add((void ***)&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);

    /* add dynamic symbols in dynsym_section */
    for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
        sym_bind = ELFW(ST_BIND)(sym->st_info);
        if (sym_bind == STB_LOCAL)
            continue;
        name = dynstr + sym->st_name;
        add_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
                    sym->st_info, sym->st_other, sym->st_shndx, name);
    }

    /* load all referenced DLLs */
    for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
        switch(dt->d_tag) {
        case DT_NEEDED:

src/tccpe.c  view on Meta::CPAN

    fprintf(f, "%-8s", "offset");
    for (i = 0; i < m; ++i)
        fprintf(f, " %02x", i);
    n = 56;

    if (s->sh_type == SHT_SYMTAB || s->sh_type == SHT_RELX) {
        const char *fields1[] = {
            "name",
            "value",
            "size",
            "bind",
            "type",
            "other",
            "shndx",
            NULL
        };

        const char *fields2[] = {
            "offs",
            "type",
            "symb",



( run in 1.338 second using v1.01-cache-2.11-cpan-2398b32b56e )