History

Fixed trie code generation for apple

I removed the FIXME for generating trie code with working code. I also fixed a problem where: cc -g -c a.c; cc -o a a.o created a bind/rebase error because the second cc did not use -g and .debug sections where not checked correctly. I also removed the elfinterp printout in tcc.c when TCC_TARGET_MACHO is set.

herman ten brugge committed 3 years ago

Commit 6b9fb931 parent d8329c22 files · +168 −68Browse files

Unified · Split

2 files
  1. tcc.c +1 −1
  2. tccmacho.c +167 −67
tcc.c+1−1
@@ -207,7 +207,7 @@ static void print_search_dirs(TCCState *s) · 206 unmodified lines
207 print_dirs("include", s->sysinclude_paths, s->nb_sysinclude_paths);207 print_dirs("include", s->sysinclude_paths, s->nb_sysinclude_paths);
208 print_dirs("libraries", s->library_paths, s->nb_library_paths);208 print_dirs("libraries", s->library_paths, s->nb_library_paths);
209 printf("libtcc1:\n %s/%s\n", s->library_paths[0], CONFIG_TCC_CROSSPREFIX TCC_LIBTCC1);209 printf("libtcc1:\n %s/%s\n", s->library_paths[0], CONFIG_TCC_CROSSPREFIX TCC_LIBTCC1);
210#ifndef TCC_TARGET_PE210#if !defined TCC_TARGET_PE && !defined TCC_TARGET_MACHO
211 print_dirs("crt", s->crt_paths, s->nb_crt_paths);211 print_dirs("crt", s->crt_paths, s->nb_crt_paths);
212 printf("elfinterp:\n %s\n", DEFAULT_ELFINTERP(s));212 printf("elfinterp:\n %s\n", DEFAULT_ELFINTERP(s));
213#endif213#endif
tccmacho.c+167−67
@@ -650,7 +650,6 @@ static void check_relocs(TCCState *s1, struct macho *mo) · 649 unmodified lines
650 ElfW_Rel *rel;650 ElfW_Rel *rel;
651 ElfW(Sym) *sym;651 ElfW(Sym) *sym;
652 int i, type, gotplt_entry, sym_index, for_code;652 int i, type, gotplt_entry, sym_index, for_code;
653 int sh_num, debug;
654 uint32_t *pi, *goti;653 uint32_t *pi, *goti;
655 struct sym_attr *attr;654 struct sym_attr *attr;
656 655
@@ -659,12 +658,9 @@ static void check_relocs(TCCState *s1, struct macho *mo) · 2 unmodified lines
659 mo->nr_plt = mo->n_got = 0;658 mo->nr_plt = mo->n_got = 0;
660 for (i = 1; i < s1->nb_sections; i++) {659 for (i = 1; i < s1->nb_sections; i++) {
661 s = s1->sections[i];660 s = s1->sections[i];
662 if (s->sh_type != SHT_RELX)661 if (s->sh_type != SHT_RELX ||
662 !strncmp(s1->sections[s->sh_info]->name, ".debug_", 7))
663 continue;663 continue;
664 sh_num = s1->sections[s->sh_info]->sh_num;
665 debug = sh_num >= s1->dwlo && sh_num < s1->dwhi;
666 if (debug)
667 continue;
668 for_each_elem(s, 0, rel, ElfW_Rel) {664 for_each_elem(s, 0, rel, ElfW_Rel) {
669 type = ELFW(R_TYPE)(rel->r_info);665 type = ELFW(R_TYPE)(rel->r_info);
670 gotplt_entry = gotplt_entry_type(type);666 gotplt_entry = gotplt_entry_type(type);
@@ -765,7 +761,7 @@ static void check_relocs(TCCState *s1, struct macho *mo) · 94 unmodified lines
765 ElfW_Rel *rel;761 ElfW_Rel *rel;
766 ElfW(Sym) *sym;762 ElfW(Sym) *sym;
767 int i, type, gotplt_entry, sym_index, for_code;763 int i, type, gotplt_entry, sym_index, for_code;
768 int sh_num, debug, bind_offset, la_symbol_offset;764 int bind_offset, la_symbol_offset;
769 uint32_t *pi, *goti;765 uint32_t *pi, *goti;
770 struct sym_attr *attr;766 struct sym_attr *attr;
771 767
@@ -807,10 +803,9 @@ static void check_relocs(TCCState *s1, struct macho *mo) · 35 unmodified lines
807 mo->nr_plt = mo->n_got = 0;803 mo->nr_plt = mo->n_got = 0;
808 for (i = 1; i < s1->nb_sections; i++) {804 for (i = 1; i < s1->nb_sections; i++) {
809 s = s1->sections[i];805 s = s1->sections[i];
810 if (s->sh_type != SHT_RELX)806 if (s->sh_type != SHT_RELX ||
807 !strncmp(s1->sections[s->sh_info]->name, ".debug_", 7))
811 continue;808 continue;
812 sh_num = s1->sections[s->sh_info]->sh_num;
813 debug = sh_num >= s1->dwlo && sh_num < s1->dwhi;
814 for_each_elem(s, 0, rel, ElfW_Rel) {809 for_each_elem(s, 0, rel, ElfW_Rel) {
815 type = ELFW(R_TYPE)(rel->r_info);810 type = ELFW(R_TYPE)(rel->r_info);
816 gotplt_entry = gotplt_entry_type(type);811 gotplt_entry = gotplt_entry_type(type);
@@ -820,9 +815,8 @@ static void check_relocs(TCCState *s1, struct macho *mo) · 3 unmodified lines
820 address due to codegen (i.e. a reloc requiring a got slot). */815 address due to codegen (i.e. a reloc requiring a got slot). */
821 sym_index = ELFW(R_SYM)(rel->r_info);816 sym_index = ELFW(R_SYM)(rel->r_info);
822 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];817 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
823 if (!debug &&818 if (sym->st_shndx == SHN_UNDEF
824 (sym->st_shndx == SHN_UNDEF819 || gotplt_entry == ALWAYS_GOTPLT_ENTRY) {
825 || gotplt_entry == ALWAYS_GOTPLT_ENTRY)) {
826 attr = get_sym_attr(s1, sym_index, 1);820 attr = get_sym_attr(s1, sym_index, 1);
827 if (!attr->dyn_index) {821 if (!attr->dyn_index) {
828 attr->got_offset = s1->got->data_offset;822 attr->got_offset = s1->got->data_offset;
@@ -1041,8 +1035,7 @@ static void convert_symbol(TCCState *s1, struct macho *mo, struct nlist_64 *pn) · 212 unmodified lines
1041 else if (sym->st_shndx >= SHN_LORESERVE)1035 else if (sym->st_shndx >= SHN_LORESERVE)
1042 tcc_error("unhandled ELF symbol section %d %s", sym->st_shndx, name);1036 tcc_error("unhandled ELF symbol section %d %s", sym->st_shndx, name);
1043 else if (!mo->elfsectomacho[sym->st_shndx]) {1037 else if (!mo->elfsectomacho[sym->st_shndx]) {
1044 int sh_num = s1->sections[sym->st_shndx]->sh_num;1038 if (strncmp(s1->sections[sym->st_shndx]->name, ".debug_", 7))
1045 if (sh_num < s1->dwlo || sh_num >= s1->dwhi)
1046 tcc_error("ELF section %d(%s) not mapped into Mach-O for symbol %s",1039 tcc_error("ELF section %d(%s) not mapped into Mach-O for symbol %s",
1047 sym->st_shndx, s1->sections[sym->st_shndx]->name, name);1040 sym->st_shndx, s1->sections[sym->st_shndx]->name, name);
1048 }1041 }
@@ -1341,32 +1334,139 @@ static void bind_rebase(TCCState *s1, struct macho *mo) · 292 unmodified lines
1341}1334}
1342#endif1335#endif
1343 1336
1344struct trie {1337struct trie_info {
1345 const char *name;1338 const char *name;
1346 int flag;1339 int flag;
1347 addr_t addr;1340 addr_t addr;
1348 int offset_size;
1349 int str_size;1341 int str_size;
1350 int term_size;1342 int term_size;
1351 int term_offset;
1352};1343};
1353 1344
1345struct trie_node {
1346 int start;
1347 int end;
1348 int index_start;
1349 int index_end;
1350 int n_child;
1351 struct trie_node *child;
1352};
1353
1354struct trie_seq {
1355 int n_child;
1356 struct trie_node *node;
1357 int offset;
1358 int nest_offset;
1359};
1360
1361static void create_trie(struct trie_node *node,
1362 int from, int to, int index_start,
1363 int n_trie, struct trie_info *trie)
1364{
1365 int i;
1366 int start, end, index_end;
1367 char cur;
1368 struct trie_node *child;
1369
1370 for (i = from; i < to; i = end) {
1371 cur = trie[i].name[index_start];
1372 start = i++;
1373 for (; i < to; i++)
1374 if (cur != trie[i].name[index_start])
1375 break;
1376 end = i;
1377 if (start == end - 1 ||
1378 (trie[start].name[index_start] &&
1379 trie[start].name[index_start + 1] == 0))
1380 index_end = trie[start].str_size - 1;
1381 else {
1382 index_end = index_start + 1;
1383 for (;;) {
1384 cur = trie[start].name[index_end];
1385 for (i = start + 1; i < end; i++)
1386 if (cur != trie[i].name[index_end])
1387 break;
1388 if (trie[start].name[index_end] &&
1389 trie[start].name[index_end + 1] == 0) {
1390 end = start + 1;
1391 index_end = trie[start].str_size - 1;
1392 break;
1393 }
1394 if (i != end)
1395 break;
1396 index_end++;
1397 }
1398 }
1399 node->child = tcc_realloc(node->child,
1400 (node->n_child + 1) *
1401 sizeof(struct trie_node));
1402 child = &node->child[node->n_child];
1403 child->start = start;
1404 child->end = end;
1405 child->index_start = index_start;
1406 child->index_end = index_end;
1407 child->n_child = 0;
1408 child->child = NULL;
1409 node->n_child++;
1410 if (start != end - 1)
1411 create_trie(child, start, end, index_end, n_trie, trie);
1412 }
1413}
1414
1415static int create_seq(int *offset, int *n_head, struct trie_seq **seq,
1416 struct trie_node *node,
1417 int n_trie, struct trie_info *trie)
1418{
1419 int i, nest_offset, last_head = *n_head, retval = *offset;
1420 struct trie_seq *p_head;
1421 struct trie_node *p_nest;
1422
1423 for (i = 0; i < node->n_child; i++) {
1424 p_nest = &node->child[i];
1425 *seq = tcc_realloc(*seq, (*n_head + 1) * sizeof(struct trie_seq));
1426 p_head = &(*seq)[(*n_head)++];
1427 p_head->n_child = i == 0 ? node->n_child : -1;
1428 p_head->node = p_nest;
1429 p_head->offset = *offset;
1430 p_head->nest_offset = 0;
1431 *offset += (i == 0 ? 1 + 1 : 0) +
1432 p_nest->index_end - p_nest->index_start + 1 + 3;
1433 }
1434 for (i = 0; i < node->n_child; i++) {
1435 nest_offset =
1436 create_seq(offset, n_head, seq, &node->child[i], n_trie, trie);
1437 p_head = &(*seq)[last_head + i];
1438 p_head->nest_offset = nest_offset;
1439 }
1440 return retval;
1441}
1442
1443static void node_free(struct trie_node *node)
1444{
1445 int i;
1446
1447 for (i = 0; i < node->n_child; i++)
1448 node_free(&node->child[i]);
1449 tcc_free(node->child);
1450}
1451
1354static int triecmp(const void *_a, const void *_b, void *arg)1452static int triecmp(const void *_a, const void *_b, void *arg)
1355{1453{
1356 struct trie *a = (struct trie *) _a;1454 struct trie_info *a = (struct trie_info *) _a;
1357 struct trie *b = (struct trie *) _b;1455 struct trie_info *b = (struct trie_info *) _b;
1358 1456
1359 return strcmp(a->name, b->name);1457 return strcmp(a->name, b->name);
1360}1458}
1361 1459
1362static void export_trie(TCCState *s1, struct macho *mo)1460static void export_trie(TCCState *s1, struct macho *mo)
1363{1461{
1364 int i, j, n, m, offset;1462 int i, size, offset = 0, save_offset;
1365 uint8_t *ptr;1463 uint8_t *ptr;
1366 int sym_index;1464 int sym_index;
1367 int sym_end = symtab_section->data_offset / sizeof(ElfW(Sym));1465 int sym_end = symtab_section->data_offset / sizeof(ElfW(Sym));
1368 int n_trie = 0;1466 int n_trie = 0, n_head = 0;
1369 struct trie *trie = NULL;1467 struct trie_info *trie = NULL, *p_trie;
1468 struct trie_node node, *p_node;
1469 struct trie_seq *seq = NULL;
1370 addr_t vm_addr = get_segment(mo, 1)->vmaddr;1470 addr_t vm_addr = get_segment(mo, 1)->vmaddr;
1371 1471
1372 for (sym_index = 1; sym_index < sym_end; ++sym_index) {1472 for (sym_index = 1; sym_index < sym_end; ++sym_index) {
@@ -1383,59 +1483,59 @@ static void export_trie(TCCState *s1, struct macho *mo) · 10 unmodified lines
1383 if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK)1483 if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK)
1384 flag |= EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION;1484 flag |= EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION;
1385 dprintf ("%s %d %llx\n", name, flag, addr + vm_addr);1485 dprintf ("%s %d %llx\n", name, flag, addr + vm_addr);
1386 trie = tcc_realloc(trie, (n_trie + 1) * sizeof(struct trie));1486 trie = tcc_realloc(trie, (n_trie + 1) * sizeof(struct trie_info));
1387 trie[n_trie].name = name;1487 trie[n_trie].name = name;
1388 trie[n_trie].flag = flag;1488 trie[n_trie].flag = flag;
1389 trie[n_trie].addr = addr;1489 trie[n_trie].addr = addr;
1390 trie[n_trie].offset_size = 1;
1391 trie[n_trie].str_size = strlen(name) + 1;1490 trie[n_trie].str_size = strlen(name) + 1;
1392 trie[n_trie].term_size = uleb128_size(flag) + uleb128_size(addr);1491 trie[n_trie].term_size = uleb128_size(flag) + uleb128_size(addr);
1393 trie[n_trie].term_offset = 0;
1394 n_trie++;1492 n_trie++;
1395 }1493 }
1396 }1494 }
1397 /* FIXME: generate tree */
1398 if (n_trie > 255) {
1399 tcc_warning("Fix trie code. n_trie(%d) > 255", n_trie);
1400 n_trie = 255;
1401 }
1402 if (n_trie) {1495 if (n_trie) {
1403 tcc_qsort(trie, n_trie, sizeof(struct trie), triecmp, NULL);1496 tcc_qsort(trie, n_trie, sizeof(struct trie_info), triecmp, NULL);
1404 offset = 1 + 1;1497 memset(&node, 0, sizeof(node));
1405 for (i = 0; i < n_trie; i++)1498 create_trie(&node, 0, n_trie, 0, n_trie, trie);
1406 offset += trie[i].str_size + trie[i].offset_size;1499 create_seq(&offset, &n_head, &seq, &node, n_trie, trie);
1407 for (i = 0; i < n_trie; i++) {1500 save_offset = offset;
1408 n = uleb128_size(offset);1501 for (i = 0; i < n_head; i++) {
1409 trie[i].term_offset = offset + n - 1;1502 p_node = seq[i].node;
1410 trie[i].offset_size = n;1503 if (p_node->n_child == 0) {
1411 offset += 1 + trie[i].term_size + 1 + n - 1;1504 p_trie = &trie[p_node->start];
1412 if (n > 1)1505 seq[i].nest_offset = offset;
1413 for (j = i - 1; j >= 0; j--) {1506 offset += 1 + p_trie->term_size + 1;
1414 trie[j].term_offset += n - 1;1507 }
1415 m = uleb128_size(trie[j].term_offset);1508 }
1416 if (m != trie[j].offset_size) {1509 for (i = 0; i < n_head; i++) {
1417 n += m - trie[j].offset_size;1510 p_node = seq[i].node;
1418 offset += m - trie[j].offset_size;1511 p_trie = &trie[p_node->start];
1419 trie[j].offset_size = m;1512 if (seq[i].n_child >= 0) {
1420 }1513 section_ptr_add(mo->exports, seq[i].offset - mo->exports->data_offset);
1421 }1514 ptr = section_ptr_add(mo->exports, 2);
1422 }1515 *ptr++ = 0;
1423 ptr = section_ptr_add(mo->exports, 2);1516 *ptr = seq[i].n_child;
1424 *ptr++ = 0;1517 }
1425 *ptr = n_trie;1518 size = p_node->index_end - p_node->index_start;
1426 for (i = 0; i < n_trie; i++) {1519 ptr = section_ptr_add(mo->exports, size + 1);
1427 ptr = section_ptr_add(mo->exports, trie[i].str_size);1520 memcpy(ptr, &p_trie->name[p_node->index_start], size);
1428 memcpy(ptr, trie[i].name, trie[i].str_size);1521 ptr[size] = 0;
1429 write_uleb128(mo->exports, trie[i].term_offset);1522 write_uleb128(mo->exports, seq[i].nest_offset);
1430 }1523 }
1431 for (i = 0; i < n_trie; i++) {1524 section_ptr_add(mo->exports, save_offset - mo->exports->data_offset);
1432 write_uleb128(mo->exports, trie[i].term_size);1525 for (i = 0; i < n_head; i++) {
1433 write_uleb128(mo->exports, trie[i].flag);1526 p_node = seq[i].node;
1434 write_uleb128(mo->exports, trie[i].addr);1527 if (p_node->n_child == 0) {
1435 ptr = section_ptr_add(mo->exports, 1);1528 p_trie = &trie[p_node->start];
1436 *ptr = 0;1529 write_uleb128(mo->exports, p_trie->term_size);
1437 }1530 write_uleb128(mo->exports, p_trie->flag);
1438 section_ptr_add(mo->exports, -mo->exports->data_offset & 7);1531 write_uleb128(mo->exports, p_trie->addr);
1532 ptr = section_ptr_add(mo->exports, 1);
1533 *ptr = 0;
1534 }
1535 }
1536 section_ptr_add(mo->exports, -mo->exports->data_offset & 7);
1537 node_free(&node);
1538 tcc_free(seq);
1439 }1539 }
1440 tcc_free(trie);1540 tcc_free(trie);
1441}1541}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t