History

Update to run on apple 13.0 (Ventura)

Add --config-codesign option to run codesign on apple to sign executables. See configure and Makefile In tccmacho.c use codesign option to call codesign application. Add build_version/source_version Sort sections in __LINKEDIT the same way as llvm does. Add simple support for trie code. Need some more attention. Fix rebase/bind error.

herman ten brugge committed 3 years ago

Commit f48efee1 parent b86d82c3 files · +151 −20Browse files

Unified · Split

3 files
  1. Makefile +1 −0
  2. configure +1 −0
  3. tccmacho.c +149 −20
Makefile+1−0
@@ -94,6 +94,7 @@ NATIVE_DEFINES_$(CONFIG_Android) += -DTARGETOS_ANDROID · 93 unmodified lines
94NATIVE_DEFINES_$(CONFIG_pie) += -DCONFIG_TCC_PIE94NATIVE_DEFINES_$(CONFIG_pie) += -DCONFIG_TCC_PIE
95NATIVE_DEFINES_$(CONFIG_pic) += -DCONFIG_TCC_PIC95NATIVE_DEFINES_$(CONFIG_pic) += -DCONFIG_TCC_PIC
96NATIVE_DEFINES_$(CONFIG_new_macho) += -DCONFIG_NEW_MACHO96NATIVE_DEFINES_$(CONFIG_new_macho) += -DCONFIG_NEW_MACHO
97NATIVE_DEFINES_$(CONFIG_codesign) += -DCONFIG_CODESIGN
97NATIVE_DEFINES_$(CONFIG_new-dtags) += -DCONFIG_NEW_DTAGS98NATIVE_DEFINES_$(CONFIG_new-dtags) += -DCONFIG_NEW_DTAGS
98NATIVE_DEFINES_no_$(CONFIG_bcheck) += -DCONFIG_TCC_BCHECK=099NATIVE_DEFINES_no_$(CONFIG_bcheck) += -DCONFIG_TCC_BCHECK=0
99NATIVE_DEFINES_no_$(CONFIG_backtrace) += -DCONFIG_TCC_BACKTRACE=0100NATIVE_DEFINES_no_$(CONFIG_backtrace) += -DCONFIG_TCC_BACKTRACE=0
configure+1−0
@@ -351,6 +351,7 @@ Advanced options (experts only): · 350 unmodified lines
351 --config-bcheck=no disable bounds checker (-b)351 --config-bcheck=no disable bounds checker (-b)
352 --config-predefs=no do not compile tccdefs.h, instead just include352 --config-predefs=no do not compile tccdefs.h, instead just include
353 --config-new_macho Use apple new macho object format353 --config-new_macho Use apple new macho object format
354 --config-codesign Use codesign on apple to sign executables
354 --dwarf=x Use dwarf debug info instead of stabs (x=2..5)355 --dwarf=x Use dwarf debug info instead of stabs (x=2..5)
355EOF356EOF
356exit 1357exit 1
tccmacho.c+149−20
@@ -107,6 +107,8 @@ struct load_command { · 106 unmodified lines
107#define LC_REEXPORT_DYLIB (0x1f | LC_REQ_DYLD)107#define LC_REEXPORT_DYLIB (0x1f | LC_REQ_DYLD)
108#define LC_DYLD_INFO_ONLY (0x22|LC_REQ_DYLD)108#define LC_DYLD_INFO_ONLY (0x22|LC_REQ_DYLD)
109#define LC_MAIN (0x28|LC_REQ_DYLD)109#define LC_MAIN (0x28|LC_REQ_DYLD)
110#define LC_SOURCE_VERSION 0x2A
111#define LC_BUILD_VERSION 0x32
110#define LC_DYLD_EXPORTS_TRIE (0x33 | LC_REQ_DYLD)112#define LC_DYLD_EXPORTS_TRIE (0x33 | LC_REQ_DYLD)
111#define LC_DYLD_CHAINED_FIXUPS (0x34 | LC_REQ_DYLD)113#define LC_DYLD_CHAINED_FIXUPS (0x34 | LC_REQ_DYLD)
112 114
@@ -256,6 +258,24 @@ struct linkedit_data_command { · 143 unmodified lines
256 uint32_t datasize; /* file size of data in __LINKEDIT segment */258 uint32_t datasize; /* file size of data in __LINKEDIT segment */
257};259};
258 260
261#define PLATFORM_MACOS 1
262
263struct build_version_command {
264 uint32_t cmd; /* LC_BUILD_VERSION */
265 uint32_t cmdsize; /* sizeof(struct build_version_command) plus */
266 /* ntools * sizeof(struct build_tool_version) */
267 uint32_t platform; /* platform */
268 uint32_t minos; /* X.Y.Z is encoded in nibbles xxxx.yy.zz */
269 uint32_t sdk; /* X.Y.Z is encoded in nibbles xxxx.yy.zz */
270 uint32_t ntools; /* number of tool entries following this */
271};
272
273struct source_version_command {
274 uint32_t cmd; /* LC_SOURCE_VERSION */
275 uint32_t cmdsize; /* 16 */
276 uint64_t version; /* A.B.C.D.E packed as a24.b10.c10.d10.e10 */
277};
278
259struct symtab_command {279struct symtab_command {
260 uint32_t cmd; /* LC_SYMTAB */280 uint32_t cmd; /* LC_SYMTAB */
261 uint32_t cmdsize; /* sizeof(struct symtab_command) */281 uint32_t cmdsize; /* sizeof(struct symtab_command) */
@@ -492,7 +512,17 @@ static void * add_dylib(struct macho *mo, char *name) · 230 unmodified lines
492 return lc;512 return lc;
493}513}
494 514
495#ifndef CONFIG_NEW_MACHO515static int uleb128_size (unsigned long long value)
516{
517 int size = 0;
518
519 do {
520 value >>= 7;
521 size++;
522 } while (value != 0);
523 return size;
524}
525
496static void write_uleb128(Section *section, uint64_t value)526static void write_uleb128(Section *section, uint64_t value)
497{527{
498 do {528 do {
@@ -503,7 +533,6 @@ static void write_uleb128(Section *section, uint64_t value) · 4 unmodified lines
503 *ptr = byte | (value ? 0x80 : 0);533 *ptr = byte | (value ? 0x80 : 0);
504 } while (value != 0);534 } while (value != 0);
505}535}
506#endif
507 536
508static void tcc_macho_add_destructor(TCCState *s1)537static void tcc_macho_add_destructor(TCCState *s1)
509{538{
@@ -512,15 +541,15 @@ static void tcc_macho_add_destructor(TCCState *s1) · 2 unmodified lines
512 ElfW_Rel *rel;541 ElfW_Rel *rel;
513 uint8_t *ptr;542 uint8_t *ptr;
514 543
544 mh_execute_header = put_elf_sym(s1->symtab, -4096, 0,
545 ELFW(ST_INFO)(STB_GLOBAL, STT_OBJECT), 0,
546 text_section->sh_num, "__mh_execute_header");
515 s = find_section(s1, ".fini_array");547 s = find_section(s1, ".fini_array");
516 if (s->data_offset == 0)548 if (s->data_offset == 0)
517 return; 549 return;
518 init_sym = put_elf_sym(s1->symtab, text_section->data_offset, 0,550 init_sym = put_elf_sym(s1->symtab, text_section->data_offset, 0,
519 ELFW(ST_INFO)(STB_LOCAL, STT_FUNC), 0,551 ELFW(ST_INFO)(STB_LOCAL, STT_FUNC), 0,
520 text_section->sh_num, "___GLOBAL_init_65535");552 text_section->sh_num, "___GLOBAL_init_65535");
521 mh_execute_header = put_elf_sym(s1->symtab, 0x100000000ll, 0,
522 ELFW(ST_INFO)(STB_LOCAL, STT_OBJECT), 0,
523 SHN_ABS, "__mh_execute_header");
524 at_exit_sym = put_elf_sym(s1->symtab, 0, 0,553 at_exit_sym = put_elf_sym(s1->symtab, 0, 0,
525 ELFW(ST_INFO)(STB_GLOBAL, STT_FUNC), 0,554 ELFW(ST_INFO)(STB_GLOBAL, STT_FUNC), 0,
526 SHN_UNDEF, "___cxa_atexit");555 SHN_UNDEF, "___cxa_atexit");
@@ -674,11 +703,11 @@ static void check_relocs(TCCState *s1, struct macho *mo) · 147 unmodified lines
674 attr->plt_offset = 0; // ignore next bind703 attr->plt_offset = 0; // ignore next bind
675 s1->got->reloc->data_offset -= sizeof (ElfW_Rel);704 s1->got->reloc->data_offset -= sizeof (ElfW_Rel);
676 }705 }
677 if (for_code)706 if (for_code && sym->st_shndx == SHN_UNDEF)
678 s1->got->reloc->data_offset -= sizeof (ElfW_Rel);707 s1->got->reloc->data_offset -= sizeof (ElfW_Rel);
679 }708 }
680 }709 }
681 if (for_code) {710 if (for_code && sym->st_shndx == SHN_UNDEF) {
682 if (attr->plt_offset == -1) {711 if (attr->plt_offset == -1) {
683 uint8_t *jmp;712 uint8_t *jmp;
684 713
@@ -1312,27 +1341,103 @@ static void bind_rebase(TCCState *s1, struct macho *mo) · 627 unmodified lines
1312}1341}
1313#endif1342#endif
1314 1343
1315/* FIXME */1344struct trie {
1345 const char *name;
1346 int flag;
1347 addr_t addr;
1348 int offset_size;
1349 int str_size;
1350 int term_size;
1351 int term_offset;
1352};
1353
1354static int triecmp(const void *_a, const void *_b, void *arg)
1355{
1356 struct trie *a = (struct trie *) _a;
1357 struct trie *b = (struct trie *) _b;
1358
1359 return strcmp(a->name, b->name);
1360}
1361
1316static void export_trie(TCCState *s1, struct macho *mo)1362static void export_trie(TCCState *s1, struct macho *mo)
1317{1363{
1364 int i, j, n, m, offset;
1365 uint8_t *ptr;
1318 int sym_index;1366 int sym_index;
1319 int sym_end = symtab_section->data_offset / sizeof(ElfW(Sym));;1367 int sym_end = symtab_section->data_offset / sizeof(ElfW(Sym));
1368 int n_trie = 0;
1369 struct trie *trie = NULL;
1370 addr_t vm_addr = get_segment(mo, 1)->vmaddr;
1320 1371
1321 for (sym_index = 1; sym_index < sym_end; ++sym_index) {1372 for (sym_index = 1; sym_index < sym_end; ++sym_index) {
1322 ElfW(Sym) *sym = (ElfW(Sym) *)symtab_section->data + sym_index;1373 ElfW(Sym) *sym = (ElfW(Sym) *)symtab_section->data + sym_index;
1323 const char *name = (char*)symtab_section->link->data + sym->st_name;1374 const char *name = (char*)symtab_section->link->data + sym->st_name;
1324 1375
1325 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE &&1376 if (sym->st_shndx == text_section->sh_num &&
1326 ELFW(ST_BIND)(sym->st_info) == STB_GLOBAL) {1377 (ELFW(ST_BIND)(sym->st_info) == STB_GLOBAL ||
1378 ELFW(ST_BIND)(sym->st_info) == STB_WEAK)) {
1327 int flag = EXPORT_SYMBOL_FLAGS_KIND_REGULAR;1379 int flag = EXPORT_SYMBOL_FLAGS_KIND_REGULAR;
1380 addr_t addr =
1381 sym->st_value + s1->sections[sym->st_shndx]->sh_addr - vm_addr;
1328 1382
1329 if (sym->st_shndx == SHN_ABS)
1330 flag = EXPORT_SYMBOL_FLAGS_KIND_ABSOLUTE;
1331 if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK)1383 if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK)
1332 flag |= EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION;1384 flag |= EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION;
1333 dprintf ("%s %d %llx\n", name, flag, sym->st_value + s1->sections[sym->st_shndx]->sh_addr);1385 dprintf ("%s %d %llx\n", name, flag, addr + vm_addr);
1386 trie = tcc_realloc(trie, (n_trie + 1) * sizeof(struct trie));
1387 trie[n_trie].name = name;
1388 trie[n_trie].flag = flag;
1389 trie[n_trie].addr = addr;
1390 trie[n_trie].offset_size = 1;
1391 trie[n_trie].str_size = strlen(name) + 1;
1392 trie[n_trie].term_size = uleb128_size(flag) + uleb128_size(addr);
1393 trie[n_trie].term_offset = 0;
1394 n_trie++;
1334 }1395 }
1335 }1396 }
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) {
1403 tcc_qsort(trie, n_trie, sizeof(struct trie), triecmp, NULL);
1404 offset = 1 + 1;
1405 for (i = 0; i < n_trie; i++)
1406 offset += trie[i].str_size + trie[i].offset_size;
1407 for (i = 0; i < n_trie; i++) {
1408 n = uleb128_size(offset);
1409 trie[i].term_offset = offset + n - 1;
1410 trie[i].offset_size = n;
1411 offset += 1 + trie[i].term_size + 1 + n - 1;
1412 if (n > 1)
1413 for (j = i - 1; j >= 0; j--) {
1414 trie[j].term_offset += n - 1;
1415 m = uleb128_size(trie[j].term_offset);
1416 if (m != trie[j].offset_size) {
1417 n += m - trie[j].offset_size;
1418 offset += m - trie[j].offset_size;
1419 trie[j].offset_size = m;
1420 }
1421 }
1422 }
1423 ptr = section_ptr_add(mo->exports, 2);
1424 *ptr++ = 0;
1425 *ptr = n_trie;
1426 for (i = 0; i < n_trie; i++) {
1427 ptr = section_ptr_add(mo->exports, trie[i].str_size);
1428 memcpy(ptr, trie[i].name, trie[i].str_size);
1429 write_uleb128(mo->exports, trie[i].term_offset);
1430 }
1431 for (i = 0; i < n_trie; i++) {
1432 write_uleb128(mo->exports, trie[i].term_size);
1433 write_uleb128(mo->exports, trie[i].flag);
1434 write_uleb128(mo->exports, trie[i].addr);
1435 ptr = section_ptr_add(mo->exports, 1);
1436 *ptr = 0;
1437 }
1438 section_ptr_add(mo->exports, -mo->exports->data_offset & 7);
1439 }
1440 tcc_free(trie);
1336}1441}
1337 1442
1338static void collect_sections(TCCState *s1, struct macho *mo)1443static void collect_sections(TCCState *s1, struct macho *mo)
@@ -1345,6 +1450,8 @@ static void collect_sections(TCCState *s1, struct macho *mo) · 6 unmodified lines
1345 struct linkedit_data_command *chained_fixups_lc;1450 struct linkedit_data_command *chained_fixups_lc;
1346 struct linkedit_data_command *export_trie_lc;1451 struct linkedit_data_command *export_trie_lc;
1347#endif1452#endif
1453 struct build_version_command *dyldbv;
1454 struct source_version_command *dyldsv;
1348 struct dylinker_command *dyldlc;1455 struct dylinker_command *dyldlc;
1349 struct symtab_command *symlc;1456 struct symtab_command *symlc;
1350 struct dysymtab_command *dysymlc;1457 struct dysymtab_command *dysymlc;
@@ -1377,8 +1484,8 @@ static void collect_sections(TCCState *s1, struct macho *mo) · 26 unmodified lines
1377 mo->dyldinfo = add_lc(mo, LC_DYLD_INFO_ONLY, sizeof(*mo->dyldinfo));1484 mo->dyldinfo = add_lc(mo, LC_DYLD_INFO_ONLY, sizeof(*mo->dyldinfo));
1378#endif1485#endif
1379 1486
1380 mo->ep = add_lc(mo, LC_MAIN, sizeof(*mo->ep));1487 symlc = add_lc(mo, LC_SYMTAB, sizeof(*symlc));
1381 mo->ep->entryoff = 4096;1488 dysymlc = add_lc(mo, LC_DYSYMTAB, sizeof(*dysymlc));
1382 1489
1383 i = (sizeof(*dyldlc) + strlen("/usr/lib/dyld") + 1 + 7) &-8;1490 i = (sizeof(*dyldlc) + strlen("/usr/lib/dyld") + 1 + 7) &-8;
1384 dyldlc = add_lc(mo, LC_LOAD_DYLINKER, i);1491 dyldlc = add_lc(mo, LC_LOAD_DYLINKER, i);
@@ -1386,8 +1493,17 @@ static void collect_sections(TCCState *s1, struct macho *mo) · 1 unmodified line
1386 str = (char*)dyldlc + dyldlc->name;1493 str = (char*)dyldlc + dyldlc->name;
1387 strcpy(str, "/usr/lib/dyld");1494 strcpy(str, "/usr/lib/dyld");
1388 1495
1389 symlc = add_lc(mo, LC_SYMTAB, sizeof(*symlc));1496 dyldbv = add_lc(mo, LC_BUILD_VERSION, sizeof(*dyldbv));
1390 dysymlc = add_lc(mo, LC_DYSYMTAB, sizeof(*dysymlc));1497 dyldbv->platform = PLATFORM_MACOS;
1498 dyldbv->minos = (10 << 16) + (6 << 8);
1499 dyldbv->sdk = (10 << 16) + (6 << 8);
1500 dyldbv->ntools = 0;
1501
1502 dyldsv = add_lc(mo, LC_SOURCE_VERSION, sizeof(*dyldsv));
1503 dyldsv->version = 0;
1504
1505 mo->ep = add_lc(mo, LC_MAIN, sizeof(*mo->ep));
1506 mo->ep->entryoff = 4096;
1391 1507
1392 for(i = 0; i < s1->nb_loaded_dlls; i++) {1508 for(i = 0; i < s1->nb_loaded_dlls; i++) {
1393 DLLReference *dllref = s1->loaded_dlls[i];1509 DLLReference *dllref = s1->loaded_dlls[i];
@@ -1710,7 +1826,9 @@ ST_FUNC void bind_rebase_import(TCCState *s1, struct macho *mo) · 316 unmodified lines
1710 sym_index = ELFW(R_SYM)(mo->bind_rebase[i].rel.r_info);1826 sym_index = ELFW(R_SYM)(mo->bind_rebase[i].rel.r_info);
1711 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];1827 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1712 name = (char *) symtab_section->link->data + sym->st_name;1828 name = (char *) symtab_section->link->data + sym->st_name;
1713 tcc_error("Overlap bind/rebase %s:%s",1829 tcc_error("Overlap %s/%s %s:%s",
1830 mo->bind_rebase[i].bind ? "bind" : "rebase",
1831 mo->bind_rebase[i + 1].bind ? "bind" : "rebase",
1714 s1->sections[mo->bind_rebase[i].section]->name, name);1832 s1->sections[mo->bind_rebase[i].section]->name, name);
1715 }1833 }
1716 header = (struct dyld_chained_fixups_header *) data;1834 header = (struct dyld_chained_fixups_header *) data;
@@ -1832,7 +1950,7 @@ ST_FUNC void bind_rebase_import(TCCState *s1, struct macho *mo) · 115 unmodified lines
1832 import[bind_index].weak_import =1950 import[bind_index].weak_import =
1833 ELFW(ST_BIND)(sym->st_info) == STB_WEAK;1951 ELFW(ST_BIND)(sym->st_info) == STB_WEAK;
1834 name = (char *) symtab_section->link->data + sym->st_name;1952 name = (char *) symtab_section->link->data + sym->st_name;
1835 strcpy(data, name);1953 strcpy((char *) data, name);
1836 data += strlen(name) + 1;1954 data += strlen(name) + 1;
1837 bind_index++;1955 bind_index++;
1838 }1956 }
@@ -1893,6 +2011,17 @@ ST_FUNC int macho_output_file(TCCState *s1, const char *filename) · 54 unmodified lines
1893 tcc_free(mo.e2msym);2011 tcc_free(mo.e2msym);
1894 2012
1895 fclose(fp);2013 fclose(fp);
2014#ifdef CONFIG_CODESIGN
2015 {
2016 char command[1024];
2017 int retval;
2018
2019 snprintf(command, sizeof(command), "codesign -f -s - %s", filename);
2020 retval = system (command);
2021 if (retval == -1 || !(WIFEXITED(retval) && WEXITSTATUS(retval) == 0))
2022 tcc_error ("command failed '%s'", command);
2023 }
2024#endif
1896 return ret;2025 return ret;
1897}2026}
1898 2027

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