1 #ifdef TARGET_DEFS_ONLY
2 
3 #define EM_TCC_TARGET EM_C60
4 
5 /* relocation type for 32 bit data relocation */
6 #define R_DATA_32   R_C60_32
7 #define R_DATA_PTR  R_C60_32
8 #define R_JMP_SLOT  R_C60_JMP_SLOT
9 #define R_GLOB_DAT  R_C60_GLOB_DAT
10 #define R_COPY      R_C60_COPY
11 #define R_RELATIVE  R_C60_RELATIVE
12 
13 #define R_NUM       R_C60_NUM
14 
15 #define ELF_START_ADDR 0x00000400
16 #define ELF_PAGE_SIZE  0x1000
17 
18 #define PCRELATIVE_DLLPLT 0
19 #define RELOCATE_DLLPLT 0
20 
21 #else /* !TARGET_DEFS_ONLY */
22 
23 #include "tcc.h"
24 
25 /* Returns 1 for a code relocation, 0 for a data relocation. For unknown
26    relocations, returns -1. */
code_reloc(int reloc_type)27 int code_reloc (int reloc_type)
28 {
29     switch (reloc_type) {
30         case R_C60_32:
31 	case R_C60LO16:
32 	case R_C60HI16:
33         case R_C60_GOT32:
34         case R_C60_GOTOFF:
35         case R_C60_GOTPC:
36         case R_C60_COPY:
37             return 0;
38 
39         case R_C60_PLT32:
40             return 1;
41     }
42     return -1;
43 }
44 
45 /* Returns an enumerator to describe whether and when the relocation needs a
46    GOT and/or PLT entry to be created. See tcc.h for a description of the
47    different values. */
gotplt_entry_type(int reloc_type)48 int gotplt_entry_type (int reloc_type)
49 {
50     switch (reloc_type) {
51         case R_C60_32:
52 	case R_C60LO16:
53 	case R_C60HI16:
54         case R_C60_COPY:
55             return NO_GOTPLT_ENTRY;
56 
57         case R_C60_GOTOFF:
58         case R_C60_GOTPC:
59             return BUILD_GOT_ONLY;
60 
61         case R_C60_PLT32:
62         case R_C60_GOT32:
63             return ALWAYS_GOTPLT_ENTRY;
64     }
65     return -1;
66 }
67 
create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_attr *attr)68 ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_attr *attr)
69 {
70     tcc_error("C67 got not implemented");
71     return 0;
72 }
73 
74 /* relocate the PLT: compute addresses and offsets in the PLT now that final
75    address for PLT and GOT are known (see fill_program_header) */
relocate_plt(TCCState *s1)76 ST_FUNC void relocate_plt(TCCState *s1)
77 {
78     uint8_t *p, *p_end;
79 
80     if (!s1->plt)
81       return;
82 
83     p = s1->plt->data;
84     p_end = p + s1->plt->data_offset;
85 
86     if (p < p_end) {
87         /* XXX: TODO */
88         while (p < p_end) {
89             /* XXX: TODO */
90         }
91    }
92 }
93 
relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val)94 void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val)
95 {
96     switch(type) {
97         case R_C60_32:
98             *(int *)ptr += val;
99             break;
100         case R_C60LO16:
101             {
102                 uint32_t orig;
103 
104                 /* put the low 16 bits of the absolute address add to what is
105                    already there */
106                 orig  =   ((*(int *)(ptr  )) >> 7) & 0xffff;
107                 orig |=  (((*(int *)(ptr+4)) >> 7) & 0xffff) << 16;
108 
109                 /* patch both at once - assumes always in pairs Low - High */
110                 *(int *) ptr    = (*(int *) ptr    & (~(0xffff << 7)) ) |
111                                    (((val+orig)      & 0xffff) << 7);
112                 *(int *)(ptr+4) = (*(int *)(ptr+4) & (~(0xffff << 7)) ) |
113                                   ((((val+orig)>>16) & 0xffff) << 7);
114             }
115             break;
116         case R_C60HI16:
117             break;
118         default:
119             fprintf(stderr,"FIXME: handle reloc type %x at %x [%p] to %x\n",
120                     type, (unsigned) addr, ptr, (unsigned) val);
121             break;
122     }
123 }
124 
125 #endif /* !TARGET_DEFS_ONLY */
126