herman ten bruggeRelocation updates5a370d810 months agoHistory
2676 lines · 89.1 KB · C
RawDownload
/* *  TCC - Tiny C Compiler * *  Copyright (c) 2001-2004 Fabrice Bellard * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */ #include "tcc.h" /* stab debug support */ static const struct {  int type;  int size;  int encoding;  const char *name;} default_debug[] = {    {   VT_INT, 4, DW_ATE_signed, "int:t1=r1;-2147483648;2147483647;" },    {   VT_BYTE, 1, DW_ATE_signed_char, "char:t2=r2;0;127;" },#if LONG_SIZE == 4    {   VT_LONG | VT_INT, 4, DW_ATE_signed, "long int:t3=r3;-2147483648;2147483647;" },#else    {   VT_LLONG | VT_LONG, 8, DW_ATE_signed, "long int:t3=r3;-9223372036854775808;9223372036854775807;" },#endif    {   VT_INT | VT_UNSIGNED, 4, DW_ATE_unsigned, "unsigned int:t4=r4;0;037777777777;" },#if LONG_SIZE == 4    {   VT_LONG | VT_INT | VT_UNSIGNED, 4, DW_ATE_unsigned, "long unsigned int:t5=r5;0;037777777777;" },#else    /* use octal instead of -1 so size_t works (-gstabs+ in gcc) */    {   VT_LLONG | VT_LONG | VT_UNSIGNED, 8, DW_ATE_unsigned, "long unsigned int:t5=r5;0;01777777777777777777777;" },#endif    {   VT_QLONG, 16, DW_ATE_signed, "__int128:t6=r6;0;-1;" },    {   VT_QLONG | VT_UNSIGNED, 16, DW_ATE_unsigned, "__int128 unsigned:t7=r7;0;-1;" },    {   VT_LLONG, 8, DW_ATE_signed, "long long int:t8=r8;-9223372036854775808;9223372036854775807;" },    {   VT_LLONG | VT_UNSIGNED, 8, DW_ATE_unsigned, "long long unsigned int:t9=r9;0;01777777777777777777777;" },    {   VT_SHORT, 2, DW_ATE_signed, "short int:t10=r10;-32768;32767;" },    {   VT_SHORT | VT_UNSIGNED, 2, DW_ATE_unsigned, "short unsigned int:t11=r11;0;65535;" },    {   VT_BYTE | VT_DEFSIGN, 1, DW_ATE_signed_char, "signed char:t12=r12;-128;127;" },    {   VT_BYTE | VT_DEFSIGN | VT_UNSIGNED, 1, DW_ATE_unsigned_char, "unsigned char:t13=r13;0;255;" },    {   VT_FLOAT, 4, DW_ATE_float, "float:t14=r1;4;0;" },    {   VT_DOUBLE, 8, DW_ATE_float, "double:t15=r1;8;0;" },#ifdef TCC_USING_DOUBLE_FOR_LDOUBLE    {   VT_DOUBLE | VT_LONG, 8, DW_ATE_float, "long double:t16=r1;8;0;" },#else    {   VT_LDOUBLE, 16, DW_ATE_float, "long double:t16=r1;16;0;" },#endif    {   -1, -1, -1, "_Float32:t17=r1;4;0;" },    {   -1, -1, -1, "_Float64:t18=r1;8;0;" },    {   -1, -1, -1, "_Float128:t19=r1;16;0;" },    {   -1, -1, -1, "_Float32x:t20=r1;8;0;" },    {   -1, -1, -1, "_Float64x:t21=r1;16;0;" },    {   -1, -1, -1, "_Decimal32:t22=r1;4;0;" },    {   -1, -1, -1, "_Decimal64:t23=r1;8;0;" },    {   -1, -1, -1, "_Decimal128:t24=r1;16;0;" },    /* if default char is unsigned */    {   VT_BYTE | VT_UNSIGNED, 1, DW_ATE_unsigned_char, "unsigned char:t25=r25;0;255;" },    /* boolean type */    {   VT_BOOL, 1, DW_ATE_boolean, "bool:t26=r26;0;255;" },#if LONG_SIZE == 4    {   VT_VOID, 1, DW_ATE_unsigned_char, "void:t27=27" },#else    /* bitfields use these */    {   VT_LONG | VT_INT, 8, DW_ATE_signed, "long int:t27=r27;-9223372036854775808;9223372036854775807;" },    {   VT_LONG | VT_INT | VT_UNSIGNED, 8, DW_ATE_unsigned, "long unsigned int:t28=r28;0;01777777777777777777777;" },    {   VT_VOID, 1, DW_ATE_unsigned_char, "void:t29=29" },#endif}; #define	N_DEFAULT_DEBUG	(sizeof (default_debug) / sizeof (default_debug[0])) /* dwarf debug */ #define	DWARF_LINE_BASE				-5#define	DWARF_LINE_RANGE			14#define	DWARF_OPCODE_BASE			13 #if defined TCC_TARGET_ARM64#define	DWARF_MIN_INSTR_LEN			4#elif defined TCC_TARGET_ARM#define	DWARF_MIN_INSTR_LEN			2#else#define	DWARF_MIN_INSTR_LEN			1#endif #define	DWARF_ABBREV_COMPILE_UNIT		1#define	DWARF_ABBREV_BASE_TYPE			2#define	DWARF_ABBREV_VARIABLE_EXTERNAL		3#define	DWARF_ABBREV_VARIABLE_STATIC		4#define	DWARF_ABBREV_VARIABLE_LOCAL		5#define	DWARF_ABBREV_FORMAL_PARAMETER		6#define	DWARF_ABBREV_POINTER			7#define	DWARF_ABBREV_ARRAY_TYPE			8#define	DWARF_ABBREV_SUBRANGE_TYPE		9#define	DWARF_ABBREV_TYPEDEF			10#define	DWARF_ABBREV_ENUMERATOR_SIGNED		11#define	DWARF_ABBREV_ENUMERATOR_UNSIGNED	12#define	DWARF_ABBREV_ENUMERATION_TYPE		13#define	DWARF_ABBREV_MEMBER			14#define	DWARF_ABBREV_MEMBER_BF			15#define	DWARF_ABBREV_STRUCTURE_TYPE		16#define	DWARF_ABBREV_STRUCTURE_EMPTY_TYPE	17#define	DWARF_ABBREV_UNION_TYPE			18#define	DWARF_ABBREV_UNION_EMPTY_TYPE		19#define	DWARF_ABBREV_SUBPROGRAM_EXTERNAL	20#define	DWARF_ABBREV_SUBPROGRAM_STATIC		21#define	DWARF_ABBREV_LEXICAL_BLOCK		22#define	DWARF_ABBREV_LEXICAL_EMPTY_BLOCK	23#define	DWARF_ABBREV_SUBROUTINE_TYPE		24#define	DWARF_ABBREV_SUBROUTINE_EMPTY_TYPE	25#define	DWARF_ABBREV_FORMAL_PARAMETER2		26 /* all entries should have been generated with dwarf_uleb128 except   has_children. All values are currently below 128 so this currently   works.  */static const unsigned char dwarf_abbrev_init[] = {    DWARF_ABBREV_COMPILE_UNIT, DW_TAG_compile_unit, 1,          DW_AT_producer, DW_FORM_strp,          DW_AT_language, DW_FORM_data1,          DW_AT_name, DW_FORM_line_strp,          DW_AT_comp_dir, DW_FORM_line_strp,          DW_AT_low_pc, DW_FORM_addr,#if PTR_SIZE == 4          DW_AT_high_pc, DW_FORM_data4,#else          DW_AT_high_pc, DW_FORM_data8,#endif          DW_AT_stmt_list, DW_FORM_sec_offset,          0, 0,    DWARF_ABBREV_BASE_TYPE, DW_TAG_base_type, 0,          DW_AT_byte_size, DW_FORM_udata,          DW_AT_encoding, DW_FORM_data1,          DW_AT_name, DW_FORM_strp,          0, 0,    DWARF_ABBREV_VARIABLE_EXTERNAL, DW_TAG_variable, 0,          DW_AT_name, DW_FORM_strp,          DW_AT_decl_file, DW_FORM_udata,          DW_AT_decl_line, DW_FORM_udata,          DW_AT_type, DW_FORM_ref4,          DW_AT_external, DW_FORM_flag,          DW_AT_location, DW_FORM_exprloc,          0, 0,    DWARF_ABBREV_VARIABLE_STATIC, DW_TAG_variable, 0,          DW_AT_name, DW_FORM_strp,          DW_AT_decl_file, DW_FORM_udata,          DW_AT_decl_line, DW_FORM_udata,          DW_AT_type, DW_FORM_ref4,          DW_AT_location, DW_FORM_exprloc,          0, 0,    DWARF_ABBREV_VARIABLE_LOCAL, DW_TAG_variable, 0,          DW_AT_name, DW_FORM_strp,          DW_AT_type, DW_FORM_ref4,          DW_AT_location, DW_FORM_exprloc,          0, 0,    DWARF_ABBREV_FORMAL_PARAMETER, DW_TAG_formal_parameter, 0,          DW_AT_name, DW_FORM_strp,          DW_AT_type, DW_FORM_ref4,          DW_AT_location, DW_FORM_exprloc,          0, 0,    DWARF_ABBREV_POINTER, DW_TAG_pointer_type, 0,          DW_AT_byte_size, DW_FORM_data1,          DW_AT_type, DW_FORM_ref4,          0, 0,    DWARF_ABBREV_ARRAY_TYPE, DW_TAG_array_type, 1,          DW_AT_type, DW_FORM_ref4,          DW_AT_sibling, DW_FORM_ref4,          0, 0,    DWARF_ABBREV_SUBRANGE_TYPE, DW_TAG_subrange_type, 0,          DW_AT_type, DW_FORM_ref4,          DW_AT_upper_bound, DW_FORM_udata,          0, 0,    DWARF_ABBREV_TYPEDEF, DW_TAG_typedef, 0,          DW_AT_name, DW_FORM_strp,          DW_AT_decl_file, DW_FORM_udata,          DW_AT_decl_line, DW_FORM_udata,          DW_AT_type, DW_FORM_ref4,          0, 0,    DWARF_ABBREV_ENUMERATOR_SIGNED, DW_TAG_enumerator, 0,          DW_AT_name, DW_FORM_strp,          DW_AT_const_value, DW_FORM_sdata,          0, 0,    DWARF_ABBREV_ENUMERATOR_UNSIGNED, DW_TAG_enumerator, 0,          DW_AT_name, DW_FORM_strp,          DW_AT_const_value, DW_FORM_udata,          0, 0,    DWARF_ABBREV_ENUMERATION_TYPE, DW_TAG_enumeration_type, 1,          DW_AT_name, DW_FORM_strp,          DW_AT_encoding, DW_FORM_data1,          DW_AT_byte_size, DW_FORM_data1,          DW_AT_type, DW_FORM_ref4,          DW_AT_decl_file, DW_FORM_udata,          DW_AT_decl_line, DW_FORM_udata,          DW_AT_sibling, DW_FORM_ref4,          0, 0,    DWARF_ABBREV_MEMBER, DW_TAG_member, 0,          DW_AT_name, DW_FORM_strp,          DW_AT_decl_file, DW_FORM_udata,          DW_AT_decl_line, DW_FORM_udata,          DW_AT_type, DW_FORM_ref4,          DW_AT_data_member_location, DW_FORM_udata,          0, 0,    DWARF_ABBREV_MEMBER_BF, DW_TAG_member, 0,          DW_AT_name, DW_FORM_strp,          DW_AT_decl_file, DW_FORM_udata,          DW_AT_decl_line, DW_FORM_udata,          DW_AT_type, DW_FORM_ref4,          DW_AT_bit_size, DW_FORM_udata,          DW_AT_data_bit_offset, DW_FORM_udata,          0, 0,    DWARF_ABBREV_STRUCTURE_TYPE, DW_TAG_structure_type, 1,          DW_AT_name, DW_FORM_strp,          DW_AT_byte_size, DW_FORM_udata,          DW_AT_decl_file, DW_FORM_udata,          DW_AT_decl_line, DW_FORM_udata,          DW_AT_sibling, DW_FORM_ref4,          0, 0,    DWARF_ABBREV_STRUCTURE_EMPTY_TYPE, DW_TAG_structure_type, 0,          DW_AT_name, DW_FORM_strp,          DW_AT_byte_size, DW_FORM_udata,          DW_AT_decl_file, DW_FORM_udata,          DW_AT_decl_line, DW_FORM_udata,          0, 0,    DWARF_ABBREV_UNION_TYPE, DW_TAG_union_type, 1,          DW_AT_name, DW_FORM_strp,          DW_AT_byte_size, DW_FORM_udata,          DW_AT_decl_file, DW_FORM_udata,          DW_AT_decl_line, DW_FORM_udata,          DW_AT_sibling, DW_FORM_ref4,          0, 0,    DWARF_ABBREV_UNION_EMPTY_TYPE, DW_TAG_union_type, 0,          DW_AT_name, DW_FORM_strp,          DW_AT_byte_size, DW_FORM_udata,          DW_AT_decl_file, DW_FORM_udata,          DW_AT_decl_line, DW_FORM_udata,          0, 0,    DWARF_ABBREV_SUBPROGRAM_EXTERNAL, DW_TAG_subprogram, 1,          DW_AT_external, DW_FORM_flag,          DW_AT_name, DW_FORM_strp,          DW_AT_decl_file, DW_FORM_udata,          DW_AT_decl_line, DW_FORM_udata,          DW_AT_type, DW_FORM_ref4,          DW_AT_low_pc, DW_FORM_addr,#if PTR_SIZE == 4          DW_AT_high_pc, DW_FORM_data4,#else          DW_AT_high_pc, DW_FORM_data8,#endif          DW_AT_sibling, DW_FORM_ref4,	  DW_AT_frame_base, DW_FORM_exprloc,          0, 0,    DWARF_ABBREV_SUBPROGRAM_STATIC, DW_TAG_subprogram, 1,          DW_AT_name, DW_FORM_strp,          DW_AT_decl_file, DW_FORM_udata,          DW_AT_decl_line, DW_FORM_udata,          DW_AT_type, DW_FORM_ref4,          DW_AT_low_pc, DW_FORM_addr,#if PTR_SIZE == 4          DW_AT_high_pc, DW_FORM_data4,#else          DW_AT_high_pc, DW_FORM_data8,#endif          DW_AT_sibling, DW_FORM_ref4,	  DW_AT_frame_base, DW_FORM_exprloc,          0, 0,    DWARF_ABBREV_LEXICAL_BLOCK, DW_TAG_lexical_block, 1,          DW_AT_low_pc, DW_FORM_addr,#if PTR_SIZE == 4          DW_AT_high_pc, DW_FORM_data4,#else          DW_AT_high_pc, DW_FORM_data8,#endif          0, 0,    DWARF_ABBREV_LEXICAL_EMPTY_BLOCK, DW_TAG_lexical_block, 0,          DW_AT_low_pc, DW_FORM_addr,#if PTR_SIZE == 4          DW_AT_high_pc, DW_FORM_data4,#else          DW_AT_high_pc, DW_FORM_data8,#endif          0, 0,    DWARF_ABBREV_SUBROUTINE_TYPE, DW_TAG_subroutine_type, 1,          DW_AT_type, DW_FORM_ref4,          DW_AT_sibling, DW_FORM_ref4,          0, 0,    DWARF_ABBREV_SUBROUTINE_EMPTY_TYPE, DW_TAG_subroutine_type, 0,          DW_AT_type, DW_FORM_ref4,          0, 0,    DWARF_ABBREV_FORMAL_PARAMETER2, DW_TAG_formal_parameter, 0,          DW_AT_type, DW_FORM_ref4,          0, 0,  0}; static const unsigned char dwarf_line_opcodes[] = {    0 ,1 ,1 ,1 ,1 ,0 ,0 ,0 ,1 ,0 ,0 ,1}; /* ------------------------------------------------------------------------- *//* debug state */ #define N_STR_HASH (251) struct dwarf_str_hash {    int len;    unsigned long data_offset;    struct dwarf_str_hash *next;}; struct _tccdbg {     int last_line_num, new_file;    int section_sym;     int debug_next_type;     struct _debug_hash {        int debug_type;        Sym *type;    } *debug_hash_global, *debug_hash_local;     /* store forward structure/unions types */    struct _debug_forw_hash {        Sym *type;        int n_debug_type;        int *debug_type;    } *debug_forw_hash_global, *debug_forw_hash_local;     int n_debug_hash_global;    int n_debug_hash_local;    int n_debug_forw_hash_global;    int n_debug_forw_hash_local;     struct _debug_info {        int start;        int end;        int last_debug_hash;        int last_debug_forw_hash;        int n_sym;        struct debug_sym {            int type;            unsigned long value;            char *str;            Section *sec;            int sym_index;            int info;            int file;            int line;        } *sym;        struct _debug_info *child, *next, *last, *parent;    } *debug_info, *debug_info_root;     struct {        int info;        int abbrev;        int line;        int str;        int line_str;    } dwarf_sym;     struct {        int start;        int dir_size;        char **dir_table;        int filename_size;        struct dwarf_filename_struct {            int dir_entry;            char *name;        } *filename_table;        int line_size;        int line_max_size;        unsigned char *line_data;        int cur_file;        int last_file;        int last_pc;        int last_line;    } dwarf_line;     struct {        int start;        Sym *func;        int line;        int base_type_used[N_DEFAULT_DEBUG];    } dwarf_info;     struct dwarf_str_hash *dwarf_str[N_STR_HASH];    struct dwarf_str_hash *dwarf_line_str[N_STR_HASH];     /* test coverage */    struct {        unsigned long offset;        unsigned long last_file_name;        unsigned long last_func_name;        int ind;        int line;    } tcov_data;}; #define last_line_num             s1->dState->last_line_num#define new_file                  s1->dState->new_file#define section_sym               s1->dState->section_sym#define debug_next_type           s1->dState->debug_next_type#define debug_hash_global         s1->dState->debug_hash_global#define debug_hash_local          s1->dState->debug_hash_local#define debug_forw_hash_global    s1->dState->debug_forw_hash_global#define debug_forw_hash_local     s1->dState->debug_forw_hash_local#define n_debug_hash_global       s1->dState->n_debug_hash_global#define n_debug_hash_local        s1->dState->n_debug_hash_local#define n_debug_forw_hash_global  s1->dState->n_debug_forw_hash_global#define n_debug_forw_hash_local   s1->dState->n_debug_forw_hash_local#define debug_info                s1->dState->debug_info#define debug_info_root           s1->dState->debug_info_root#define dwarf_sym                 s1->dState->dwarf_sym#define dwarf_line                s1->dState->dwarf_line#define dwarf_info                s1->dState->dwarf_info#define dwarf_str                 s1->dState->dwarf_str#define dwarf_line_str            s1->dState->dwarf_line_str#define tcov_data                 s1->dState->tcov_data #define	FDE_ENCODING        (DW_EH_PE_udata4 | DW_EH_PE_signed | DW_EH_PE_pcrel) /* ------------------------------------------------------------------------- */static int put_stabs(TCCState *s1, const char *str, int type, int other,    int desc, unsigned long value); ST_FUNC void tcc_debug_new(TCCState *s1){    int shf = 0;    if (!s1->dState)        s1->dState = tcc_mallocz(sizeof *s1->dState); #ifdef CONFIG_TCC_BACKTRACE    /* include stab info with standalone backtrace support */    if (s1->do_debug && s1->output_type == TCC_OUTPUT_MEMORY)        s1->do_backtrace = 1;    if (s1->do_backtrace)        shf = SHF_ALLOC; /* have debug data available at runtime */#endif     if (s1->dwarf) {	int i;	/* The sections below are just to make reloctions with	   R_DATA_32DW work correctly. See tccelf.c */	static const char *const debug[] = {	    ".debug_macro",	    ".debug_loc",	    ".debug_ranges",	    ".debug_loclists",	    ".debug_rnglists",	    ".debug_str_offsets",	    ".debug_addr"	};         s1->dwlo = s1->nb_sections;        dwarf_info_section =	    new_section(s1, ".debug_info", SHT_PROGBITS, shf);        dwarf_abbrev_section =	    new_section(s1, ".debug_abbrev", SHT_PROGBITS, shf);        dwarf_line_section =	    new_section(s1, ".debug_line", SHT_PROGBITS, shf);        dwarf_aranges_section =	    new_section(s1, ".debug_aranges", SHT_PROGBITS, shf);	for (i = 0; i < sizeof(debug)/sizeof(debug[0]); i++)	    new_section(s1, debug[i], SHT_PROGBITS, 0)->sh_addralign = 1;	shf |= SHF_MERGE | SHF_STRINGS;        dwarf_str_section =	    new_section(s1, ".debug_str", SHT_PROGBITS, shf);	dwarf_str_section->sh_entsize = 1;	dwarf_info_section->sh_addralign =	dwarf_abbrev_section->sh_addralign =	dwarf_line_section->sh_addralign =	dwarf_aranges_section->sh_addralign =	dwarf_str_section->sh_addralign = 1;	if (s1->dwarf >= 5) {            dwarf_line_str_section =	        new_section(s1, ".debug_line_str", SHT_PROGBITS, shf);	    dwarf_line_str_section->sh_entsize = 1;	    dwarf_line_str_section->sh_addralign = 1;	}        s1->dwhi = s1->nb_sections;    }    else    {        stab_section = new_section(s1, ".stab", SHT_PROGBITS, shf);        stab_section->sh_entsize = sizeof(Stab_Sym);        stab_section->sh_addralign = sizeof ((Stab_Sym*)0)->n_value;        stab_section->link = new_section(s1, ".stabstr", SHT_STRTAB, shf);        /* put first entry */        put_stabs(s1, "", 0, 0, 0, 0);

Lines 1–500 of 2676.