Rev 9619 | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 9619 | Rev 9782 | ||
---|---|---|---|
Line 1... | Line 1... | ||
1 | /* |
1 | /* |
2 | * TCCMEOS.C - KolibriOS/MenuetOS file output for the TinyC Compiler |
2 | * TCCMEOS.C - KolibriOS/MenuetOS file output for the TinyC Compiler |
3 | * |
3 | * |
4 | * Copyright (c) 2006 Andrey Khalyavin |
4 | * Copyright (c) 2006 Andrey Khalyavin |
5 | * Copyright (c) 2021 Coldy (KX extension) |
5 | * Copyright (c) 2021-2022 Coldy (KX extension) |
6 | * |
6 | * |
7 | * This library is free software; you can redistribute it and/or |
7 | * This library is free software; you can redistribute it and/or |
8 | * modify it under the terms of the GNU Lesser General Public |
8 | * modify it under the terms of the GNU Lesser General Public |
9 | * License as published by the Free Software Foundation; either |
9 | * License as published by the Free Software Foundation; either |
10 | * version 2 of the License, or (at your option) any later version. |
10 | * version 2 of the License, or (at your option) any later version. |
Line 56... | Line 56... | ||
56 | } me_info; |
56 | } me_info; |
Line 57... | Line 57... | ||
57 | 57 | ||
58 | #ifdef TCC_TARGET_KX |
58 | #ifdef TCC_TARGET_KX |
59 | void kx_init(me_info* me); |
59 | void kx_init(me_info* me); |
- | 60 | void kx_build_imports(me_info* me); |
|
60 | void kx_build_imports(me_info* me); |
61 | void kx_check_import_error(int reloc_type, const char* code_base, Elf32_Addr offset, const char* symbol_name); |
61 | long kx_get_header_length(me_info* me); |
62 | long kx_get_header_length(me_info* me); |
62 | void kx_write_header(me_info* me, FILE* f); |
63 | void kx_write_header(me_info* me, FILE* f); |
63 | void kx_write_imports(me_info* me, FILE* f); |
64 | void kx_write_imports(me_info* me, FILE* f); |
64 | void kx_free(me_info* me); |
65 | void kx_free(me_info* me); |
Line 110... | Line 111... | ||
110 | rel_=rel; |
111 | rel_=rel; |
111 | while (rel_ |
112 | while (rel_ |
112 | rel=rel_; |
113 | rel=rel_; |
113 | int type = ELF32_R_TYPE(rel->r_info); |
114 | int type = ELF32_R_TYPE(rel->r_info); |
114 | rel_=rel+1; |
115 | rel_=rel+1; |
115 | if (type != R_386_PC32 && type != R_386_32) |
116 | if (type != R_386_PC32 && type != R_386_32) { |
- | 117 | // gcc (and friends) object files is used? |
|
- | 118 | tcc_error("unsupported relocation type %d", type); |
|
116 | continue; |
119 | continue; |
- | 120 | } |
|
117 | int sym = ELF32_R_SYM(rel->r_info); |
121 | int sym = ELF32_R_SYM(rel->r_info); |
118 | if (sym>symtab_section->data_offset/sizeof(Elf32_Sym)) |
122 | if (sym>symtab_section->data_offset/sizeof(Elf32_Sym)) |
119 | continue; |
123 | continue; |
120 | Elf32_Sym* esym = ((Elf32_Sym *)symtab_section->data)+sym; |
124 | Elf32_Sym* esym = ((Elf32_Sym *)symtab_section->data)+sym; |
121 | int sect=esym->st_shndx; |
125 | int sect=esym->st_shndx; |
122 | int sh_addr; |
126 | int sh_addr; |
123 | ss=findsection(me,sect); |
127 | ss=findsection(me,sect); |
- | 128 | const char* sym_name = strtab_section->data + esym->st_name; |
|
- | 129 | int sym_index; |
|
- | 130 | Elf32_Sym* dyn_sym; |
|
- | 131 | // Import has more less priority in relation to local symbols |
|
124 | if (ss==0) |
132 | if (ss==0) |
125 | { |
133 | { |
126 | const char *sym_name = strtab_section->data + esym->st_name; |
- | |
127 | #ifdef TCC_TARGET_KX |
134 | #ifdef TCC_TARGET_KX |
128 | int sym_index = find_elf_sym(me->s1->dynsymtab_section, sym_name); |
135 | sym_index = find_elf_sym(me->s1->dynsymtab_section, sym_name); |
129 | Elf32_Sym* dyn_sym; |
- | |
130 | if (sym_index == 0) { |
136 | if (sym_index == 0) { |
131 | #endif |
137 | #endif |
132 | tcc_error_noabort("undefined symbol '%s'", sym_name); |
138 | tcc_error_noabort("undefined import symbol '%s'", sym_name); |
133 | continue; |
139 | continue; |
134 | #ifdef TCC_TARGET_KX |
140 | #ifdef TCC_TARGET_KX |
135 | } |
141 | } |
136 | dyn_sym = &((ElfW(Sym) *)me->s1->dynsymtab_section->data)[sym_index]; |
142 | dyn_sym = &((ElfW(Sym) *)me->s1->dynsymtab_section->data)[sym_index]; |
137 | sh_addr = dyn_sym->st_value; |
143 | sh_addr = dyn_sym->st_value; |
138 | if (sh_addr == 0) { |
144 | if (sh_addr == 0) { |
139 | tcc_error_noabort("symbol '%s' has zero value", sym_name); |
145 | tcc_error_noabort("import symbol '%s' has zero value", sym_name); |
140 | continue; |
146 | continue; |
141 | } |
147 | } |
- | 148 | ||
- | 149 | // Stop linking if incorrect import |
|
- | 150 | kx_check_import_error(type, s->data, rel->r_offset, sym_name); |
|
142 | #endif |
151 | #endif |
143 | } |
152 | } |
144 | else |
153 | else { |
- | 154 | if (esym->st_shndx == SHN_UNDEF) |
|
- | 155 | tcc_error("unresolved external symbol '%s'", sym_name); |
|
145 | sh_addr = ss->sh_addr; |
156 | sh_addr = ss->sh_addr; |
- | 157 | } |
|
146 | if (rel->r_offset>s->data_size) |
158 | if (rel->r_offset>s->data_size) |
147 | continue; |
159 | continue; |
148 | if (type==R_386_PC32) |
160 | if (type==R_386_PC32) |
149 | *(int*)(rel->r_offset+s->data)+=/*ss->*/sh_addr+esym->st_value-rel->r_offset-s->sh_addr; |
161 | *(int*)(rel->r_offset+s->data)+= sh_addr+esym->st_value-rel->r_offset-s->sh_addr; |
150 | else if (type==R_386_32) |
162 | else if (type==R_386_32) |
151 | *(int*)(rel->r_offset+s->data)+=/*ss->*/sh_addr+esym->st_value; |
163 | *(int*)(rel->r_offset+s->data)+= sh_addr+esym->st_value; |
152 | } |
164 | } |
153 | rel=rel_; |
165 | rel=rel_; |
154 | s=s->next; |
166 | s=s->next; |
155 | if (s==0) // what about multiple BSS sections ? |
167 | if (s==0) // what about multiple BSS sections ? |
156 | { |
168 | { |