Changeset 60139 in vbox
- Timestamp:
- Mar 22, 2016 7:18:42 PM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/ValidationKit/bootsectors/bs3kit/VBoxBs3ObjConverter.cpp
r60137 r60139 665 665 if (pThis->aFixupps[iFixupp].cbRec + cbSubRec >= OMF_MAX_RECORD_PAYLOAD) 666 666 { 667 if (g_cVerbose >= 2) 668 printf("debug: FIXUPP split\n"); 667 669 iFixupp++; 668 670 if (iFixupp >= RT_ELEMENTS(pThis->aFixupps)) … … 695 697 || idxTarget >= _32K 696 698 || fTargetDisp != (bTarget <= OMF_FIX_T_FRAME_NO) ) 697 /*return*/error(pThis->pszSrc,699 return error(pThis->pszSrc, 698 700 "Internal error: offDataRec=%#x bFrame=%u idxFrame=%#x bTarget=%u idxTarget=%#x fTargetDisp=%d offTargetDisp=%#x\n", 699 701 offDataRec, bFrame, idxFrame, bTarget, idxTarget, fTargetDisp, offTargetDisp); … … 742 744 for (unsigned iFixupp = 0; iFixupp <= pThis->iFixupp; iFixupp++) 743 745 { 744 uint 8_t const cbRec = pThis->aFixupps[iFixupp].cbRec;746 uint16_t const cbRec = pThis->aFixupps[iFixupp].cbRec; 745 747 if (!cbRec) 746 748 break; 749 if (g_cVerbose >= 3) 750 printf("debug: FIXUPP32 #%u cbRec=%#x\n", iFixupp, cbRec); 747 751 if ( !omfWriter_RecBegin(pThis, OMF_FIXUPP32) 748 752 || !omfWriter_RecAddBytes(pThis, pThis->aFixupps[iFixupp].abData, cbRec) … … 1034 1038 return fRet; 1035 1039 } 1036 1037 #define ELF_TO_OMF_CONVERSION1038 1039 #ifdef ELF_TO_OMF_CONVERSION1040 1040 1041 1041 … … 1485 1485 return error(pThis->pszSrc, "Wtf? cbVirtData is zero!\n"); 1486 1486 } 1487 if (g_cVerbose >= 2) 1488 printf("debug: LEDATA off=%#x cb=%#x cRelocs=%#x sect=#%u segdef=%#x grpdef=%#x '%s'\n", 1489 off, cbChunk, cRelocs, i, pThis->paSegments[i].iSegDef, pThis->paSegments[i].iGrpDef, pszSegNm); 1487 1490 1488 1491 /* … … 1679 1682 return false; 1680 1683 } 1681 1682 #else /* !ELF_TO_OMF_CONVERSION */1683 1684 static bool convertelf(const char *pszFile, uint8_t *pbFile, size_t cbFile)1685 {1686 /*1687 * Validate the header and our other expectations.1688 */1689 ELFDETAILS ElfStuff;1690 if (!validateElf(pszFile, pbFile, cbFile, &ElfStuff))1691 return false;1692 1693 /*1694 * Locate the section name string table.1695 * We assume it's okay as we only reference it in verbose mode.1696 */1697 Elf64_Ehdr const *pEhdr = (Elf64_Ehdr const *)pbFile;1698 Elf64_Shdr const *paShdrs = (Elf64_Shdr const *)&pbFile[pEhdr->e_shoff];1699 const char *pszStrTab = (const char *)&pbFile[paShdrs[pEhdr->e_shstrndx].sh_offset];1700 1701 /*1702 * Work the section table.1703 */1704 for (uint32_t i = 1; i < pEhdr->e_shnum; i++)1705 {1706 if (g_cVerbose)1707 printf("shdr[%u]: name=%#x '%s' type=%#x flags=%#" ELF_FMT_X64 " addr=%#" ELF_FMT_X64 " off=%#" ELF_FMT_X64 " size=%#" ELF_FMT_X64 "\n"1708 " link=%u info=%#x align=%#" ELF_FMT_X64 " entsize=%#" ELF_FMT_X64 "\n",1709 i, paShdrs[i].sh_name, &pszStrTab[paShdrs[i].sh_name], paShdrs[i].sh_type, paShdrs[i].sh_flags,1710 paShdrs[i].sh_addr, paShdrs[i].sh_offset, paShdrs[i].sh_size,1711 paShdrs[i].sh_link, paShdrs[i].sh_info, paShdrs[i].sh_addralign, paShdrs[i].sh_entsize);1712 if (paShdrs[i].sh_type == SHT_RELA)1713 {1714 Elf64_Rela *paRelocs = (Elf64_Rela *)&pbFile[paShdrs[i].sh_offset];1715 uint32_t const cRelocs = paShdrs[i].sh_size / sizeof(Elf64_Rela);1716 for (uint32_t j = 0; j < cRelocs; j++)1717 {1718 uint32_t const uType = ELF64_R_TYPE(paRelocs[j].r_info);1719 if (g_cVerbose > 1)1720 printf("%#018" ELF_FMT_X64 " %#018" ELF_FMT_X64 " %s %+" ELF_FMT_D64 "\n", paRelocs[j].r_offset, paRelocs[j].r_info,1721 uType < RT_ELEMENTS(g_apszElfAmd64RelTypes) ? g_apszElfAmd64RelTypes[uType] : "unknown", paRelocs[j].r_addend);1722 1723 /* Truncate 64-bit wide absolute relocations, ASSUMING that the high bits1724 are already zero and won't be non-zero after calculating the fixup value. */1725 if (uType == R_X86_64_64)1726 {1727 paRelocs[j].r_info &= ~(uint64_t)0xff;1728 paRelocs[j].r_info |= R_X86_64_32;1729 }1730 }1731 }1732 else if (paShdrs[i].sh_type == SHT_REL)1733 return error(pszFile, "Did not expect SHT_REL sections (#%u '%s')\n", i, &pszStrTab[paShdrs[i].sh_name]);1734 }1735 return true;1736 }1737 1738 #endif /* !ELF_TO_OMF_CONVERSION */1739 1740 1684 1741 1685 … … 2583 2527 2584 2528 2529 /********************************************************************************************************************************* 2530 * Mach-O/AMD64 -> OMF/i386 Converter * 2531 *********************************************************************************************************************************/ 2532 2533 //#define MACHO_TO_OMF_CONVERSION 2534 #ifdef MACHO_TO_OMF_CONVERSION 2535 2536 /** AMD64 relocation type names for Mach-O. */ 2537 static const char * const g_apszMachOAmd64RelTypes[] = 2538 { 2539 "X86_64_RELOC_UNSIGNED", 2540 "X86_64_RELOC_SIGNED", 2541 "X86_64_RELOC_BRANCH", 2542 "X86_64_RELOC_GOT_LOAD", 2543 "X86_64_RELOC_GOT", 2544 "X86_64_RELOC_SUBTRACTOR", 2545 "X86_64_RELOC_SIGNED_1", 2546 "X86_64_RELOC_SIGNED_2", 2547 "X86_64_RELOC_SIGNED_4" 2548 }; 2549 2550 /** AMD64 relocation type sizes for Mach-O. */ 2551 static uint8_t const g_acbMachOAmd64RelTypes[] = 2552 { 2553 8, /* X86_64_RELOC_UNSIGNED */ 2554 4, /* X86_64_RELOC_SIGNED */ 2555 4, /* X86_64_RELOC_BRANCH */ 2556 4, /* X86_64_RELOC_GOT_LOAD */ 2557 4, /* X86_64_RELOC_GOT */ 2558 8, /* X86_64_RELOC_SUBTRACTOR */ 2559 4, /* X86_64_RELOC_SIGNED_1 */ 2560 4, /* X86_64_RELOC_SIGNED_2 */ 2561 4, /* X86_64_RELOC_SIGNED_4 */ 2562 }; 2563 2564 /** Macro for getting the size of a AMD64 ELF relocation. */ 2565 #define ELF_AMD64_RELOC_SIZE(a_Type) ( (a_Type) < RT_ELEMENTS(g_acbElfAmd64RelTypes) ? g_acbElfAmd64RelTypes[(a_Type)] : 1) 2566 2567 2568 typedef struct ELFDETAILS 2569 { 2570 /** The ELF header. */ 2571 Elf64_Ehdr const *pEhdr; 2572 /** The section header table. */ 2573 Elf64_Shdr const *paShdrs; 2574 /** The string table for the section names. */ 2575 const char *pchShStrTab; 2576 2577 /** The symbol table section number. UINT16_MAX if not found. */ 2578 uint16_t iSymSh; 2579 /** The string table section number. UINT16_MAX if not found. */ 2580 uint16_t iStrSh; 2581 2582 /** The symbol table. */ 2583 Elf64_Sym const *paSymbols; 2584 /** The number of symbols in the symbol table. */ 2585 uint32_t cSymbols; 2586 2587 /** Pointer to the (symbol) string table if found. */ 2588 const char *pchStrTab; 2589 /** The string table size. */ 2590 size_t cbStrTab; 2591 2592 } ELFDETAILS; 2593 typedef ELFDETAILS *PELFDETAILS; 2594 typedef ELFDETAILS const *PCELFDETAILS; 2595 2596 2597 static bool validateElf(const char *pszFile, uint8_t const *pbFile, size_t cbFile, PELFDETAILS pElfStuff) 2598 { 2599 /* 2600 * Initialize the ELF details structure. 2601 */ 2602 memset(pElfStuff, 0, sizeof(*pElfStuff)); 2603 pElfStuff->iSymSh = UINT16_MAX; 2604 pElfStuff->iStrSh = UINT16_MAX; 2605 2606 /* 2607 * Validate the header and our other expectations. 2608 */ 2609 Elf64_Ehdr const *pEhdr = (Elf64_Ehdr const *)pbFile; 2610 pElfStuff->pEhdr = pEhdr; 2611 if ( pEhdr->e_ident[EI_CLASS] != ELFCLASS64 2612 || pEhdr->e_ident[EI_DATA] != ELFDATA2LSB 2613 || pEhdr->e_ehsize != sizeof(Elf64_Ehdr) 2614 || pEhdr->e_shentsize != sizeof(Elf64_Shdr) 2615 || pEhdr->e_version != EV_CURRENT ) 2616 return error(pszFile, "Unsupported ELF config\n"); 2617 if (pEhdr->e_type != ET_REL) 2618 return error(pszFile, "Expected relocatable ELF file (e_type=%d)\n", pEhdr->e_type); 2619 if (pEhdr->e_machine != EM_X86_64) 2620 return error(pszFile, "Expected relocatable ELF file (e_type=%d)\n", pEhdr->e_machine); 2621 if (pEhdr->e_phnum != 0) 2622 return error(pszFile, "Expected e_phnum to be zero not %u\n", pEhdr->e_phnum); 2623 if (pEhdr->e_shnum < 2) 2624 return error(pszFile, "Expected e_shnum to be two or higher\n"); 2625 if (pEhdr->e_shstrndx >= pEhdr->e_shnum || pEhdr->e_shstrndx == 0) 2626 return error(pszFile, "Bad e_shstrndx=%u (e_shnum=%u)\n", pEhdr->e_shstrndx, pEhdr->e_shnum); 2627 if ( pEhdr->e_shoff >= cbFile 2628 || pEhdr->e_shoff + pEhdr->e_shnum * sizeof(Elf64_Shdr) > cbFile) 2629 return error(pszFile, "Section table is outside the file (e_shoff=%#llx, e_shnum=%u, cbFile=%#llx)\n", 2630 pEhdr->e_shstrndx, pEhdr->e_shnum, (uint64_t)cbFile); 2631 2632 /* 2633 * Locate the section name string table. 2634 * We assume it's okay as we only reference it in verbose mode. 2635 */ 2636 Elf64_Shdr const *paShdrs = (Elf64_Shdr const *)&pbFile[pEhdr->e_shoff]; 2637 pElfStuff->paShdrs = paShdrs; 2638 2639 Elf64_Xword const cbShStrTab = paShdrs[pEhdr->e_shstrndx].sh_size; 2640 if ( paShdrs[pEhdr->e_shstrndx].sh_offset > cbFile 2641 || cbShStrTab > cbFile 2642 || paShdrs[pEhdr->e_shstrndx].sh_offset + cbShStrTab > cbFile) 2643 return error(pszFile, 2644 "Section string table is outside the file (sh_offset=%#" ELF_FMT_X64 " sh_size=%#" ELF_FMT_X64 " cbFile=%#" ELF_FMT_X64 ")\n", 2645 paShdrs[pEhdr->e_shstrndx].sh_offset, paShdrs[pEhdr->e_shstrndx].sh_size, (Elf64_Xword)cbFile); 2646 const char *pchShStrTab = (const char *)&pbFile[paShdrs[pEhdr->e_shstrndx].sh_offset]; 2647 pElfStuff->pchShStrTab = pchShStrTab; 2648 2649 /* 2650 * Work the section table. 2651 */ 2652 bool fRet = true; 2653 for (uint32_t i = 1; i < pEhdr->e_shnum; i++) 2654 { 2655 if (paShdrs[i].sh_name >= cbShStrTab) 2656 return error(pszFile, "Invalid sh_name value (%#x) for section #%u\n", paShdrs[i].sh_name, i); 2657 const char *pszShNm = &pchShStrTab[paShdrs[i].sh_name]; 2658 2659 if ( paShdrs[i].sh_offset > cbFile 2660 || paShdrs[i].sh_size > cbFile 2661 || paShdrs[i].sh_offset + paShdrs[i].sh_size > cbFile) 2662 return error(pszFile, "Section #%u '%s' has data outside the file: %#" ELF_FMT_X64 " LB %#" ELF_FMT_X64 " (cbFile=%#" ELF_FMT_X64 ")\n", 2663 i, pszShNm, paShdrs[i].sh_offset, paShdrs[i].sh_size, (Elf64_Xword)cbFile); 2664 if (g_cVerbose) 2665 printf("shdr[%u]: name=%#x '%s' type=%#x flags=%#" ELF_FMT_X64 " addr=%#" ELF_FMT_X64 " off=%#" ELF_FMT_X64 " size=%#" ELF_FMT_X64 "\n" 2666 " link=%u info=%#x align=%#" ELF_FMT_X64 " entsize=%#" ELF_FMT_X64 "\n", 2667 i, paShdrs[i].sh_name, pszShNm, paShdrs[i].sh_type, paShdrs[i].sh_flags, 2668 paShdrs[i].sh_addr, paShdrs[i].sh_offset, paShdrs[i].sh_size, 2669 paShdrs[i].sh_link, paShdrs[i].sh_info, paShdrs[i].sh_addralign, paShdrs[i].sh_entsize); 2670 2671 if (paShdrs[i].sh_link >= pEhdr->e_shnum) 2672 return error(pszFile, "Section #%u '%s' links to a section outside the section table: %#x, max %#x\n", 2673 i, pszShNm, paShdrs[i].sh_link, pEhdr->e_shnum); 2674 if (!RT_IS_POWER_OF_TWO(paShdrs[i].sh_addralign)) 2675 return error(pszFile, "Section #%u '%s' alignment value is not a power of two: %#" ELF_FMT_X64 "\n", 2676 i, pszShNm, paShdrs[i].sh_addralign); 2677 if (!RT_IS_POWER_OF_TWO(paShdrs[i].sh_addralign)) 2678 return error(pszFile, "Section #%u '%s' alignment value is not a power of two: %#" ELF_FMT_X64 "\n", 2679 i, pszShNm, paShdrs[i].sh_addralign); 2680 if (paShdrs[i].sh_addr != 0) 2681 return error(pszFile, "Section #%u '%s' has non-zero address: %#" ELF_FMT_X64 "\n", i, pszShNm, paShdrs[i].sh_addr); 2682 2683 if (paShdrs[i].sh_type == SHT_RELA) 2684 { 2685 if (paShdrs[i].sh_entsize != sizeof(Elf64_Rela)) 2686 return error(pszFile, "Expected sh_entsize to be %u not %u for section #%u (%s)\n", (unsigned)sizeof(Elf64_Rela), 2687 paShdrs[i].sh_entsize, i, pszShNm); 2688 uint32_t const cRelocs = paShdrs[i].sh_size / sizeof(Elf64_Rela); 2689 if (cRelocs * sizeof(Elf64_Rela) != paShdrs[i].sh_size) 2690 return error(pszFile, "Uneven relocation entry count in #%u (%s): sh_size=%#" ELF_FMT_X64 "\n", 2691 i, pszShNm, paShdrs[i].sh_size); 2692 if ( paShdrs[i].sh_offset > cbFile 2693 || paShdrs[i].sh_size >= cbFile 2694 || paShdrs[i].sh_offset + paShdrs[i].sh_size > cbFile) 2695 return error(pszFile, "The content of section #%u '%s' is outside the file (%#" ELF_FMT_X64 " LB %#" ELF_FMT_X64 ", cbFile=%#lx)\n", 2696 i, pszShNm, paShdrs[i].sh_offset, paShdrs[i].sh_size, (unsigned long)cbFile); 2697 if (paShdrs[i].sh_info != i - 1) 2698 return error(pszFile, "Expected relocation section #%u (%s) to link to previous section: sh_info=%#u\n", 2699 i, pszShNm, (unsigned)paShdrs[i].sh_link); 2700 if (paShdrs[paShdrs[i].sh_link].sh_type != SHT_SYMTAB) 2701 return error(pszFile, "Expected relocation section #%u (%s) to link to symbol table: sh_link=%#u -> sh_type=%#x\n", 2702 i, pszShNm, (unsigned)paShdrs[i].sh_link, (unsigned)paShdrs[paShdrs[i].sh_link].sh_type); 2703 uint32_t cSymbols = paShdrs[paShdrs[i].sh_link].sh_size / paShdrs[paShdrs[i].sh_link].sh_entsize; 2704 2705 Elf64_Rela const *paRelocs = (Elf64_Rela *)&pbFile[paShdrs[i].sh_offset]; 2706 for (uint32_t j = 0; j < cRelocs; j++) 2707 { 2708 uint8_t const bType = ELF64_R_TYPE(paRelocs[j].r_info); 2709 if (RT_UNLIKELY(bType >= R_X86_64_COUNT)) 2710 fRet = error(pszFile, 2711 "%#018" ELF_FMT_X64 " %#018" ELF_FMT_X64 ": unknown fix up %#x (%+" ELF_FMT_D64 ")\n", 2712 paRelocs[j].r_offset, paRelocs[j].r_info, bType, paRelocs[j].r_addend); 2713 if (RT_UNLIKELY( j > 1 2714 && paRelocs[j].r_offset <= paRelocs[j - 1].r_offset 2715 && paRelocs[j].r_offset + ELF_AMD64_RELOC_SIZE(ELF64_R_TYPE(paRelocs[j].r_info)) 2716 < paRelocs[j - 1].r_offset )) 2717 fRet = error(pszFile, 2718 "%#018" ELF_FMT_X64 " %#018" ELF_FMT_X64 ": out of offset order (prev %" ELF_FMT_X64 ")\n", 2719 paRelocs[j].r_offset, paRelocs[j].r_info, paRelocs[j - 1].r_offset); 2720 uint32_t const iSymbol = ELF64_R_SYM(paRelocs[j].r_info); 2721 if (RT_UNLIKELY(iSymbol >= cSymbols)) 2722 fRet = error(pszFile, 2723 "%#018" ELF_FMT_X64 " %#018" ELF_FMT_X64 ": symbol index (%#x) out of bounds (%#x)\n", 2724 paRelocs[j].r_offset, paRelocs[j].r_info, iSymbol, cSymbols); 2725 } 2726 if (RT_UNLIKELY( cRelocs > 0 2727 && fRet 2728 && ( paRelocs[cRelocs - 1].r_offset > paShdrs[i - 1].sh_size 2729 || paRelocs[cRelocs - 1].r_offset + ELF_AMD64_RELOC_SIZE(ELF64_R_TYPE(paRelocs[cRelocs-1].r_info)) 2730 > paShdrs[i - 1].sh_size ))) 2731 fRet = error(pszFile, 2732 "%#018" ELF_FMT_X64 " %#018" ELF_FMT_X64 ": out of bounds (sh_size %" ELF_FMT_X64 ")\n", 2733 paRelocs[cRelocs - 1].r_offset, paRelocs[cRelocs - 1].r_info, paShdrs[i - 1].sh_size); 2734 2735 } 2736 else if (paShdrs[i].sh_type == SHT_REL) 2737 fRet = error(pszFile, "Section #%u '%s': Unexpected SHT_REL section\n", i, pszShNm); 2738 else if (paShdrs[i].sh_type == SHT_SYMTAB) 2739 { 2740 if (paShdrs[i].sh_entsize != sizeof(Elf64_Sym)) 2741 fRet = error(pszFile, "Section #%u '%s': Unsupported symbol table entry size in : #%u (expected #%u)\n", 2742 i, pszShNm, paShdrs[i].sh_entsize, sizeof(Elf64_Sym)); 2743 Elf64_Xword const cSymbols = paShdrs[i].sh_size / paShdrs[i].sh_entsize; 2744 if (cSymbols * paShdrs[i].sh_entsize != paShdrs[i].sh_size) 2745 fRet = error(pszFile, "Section #%u '%s': Size not a multiple of entry size: %#" ELF_FMT_X64 " %% %#" ELF_FMT_X64 " = %#" ELF_FMT_X64 "\n", 2746 i, pszShNm, paShdrs[i].sh_size, paShdrs[i].sh_entsize, paShdrs[i].sh_size % paShdrs[i].sh_entsize); 2747 if (cSymbols > UINT32_MAX) 2748 fRet = error(pszFile, "Section #%u '%s': too many symbols: %" ELF_FMT_X64 "\n", 2749 i, pszShNm, paShdrs[i].sh_size, cSymbols); 2750 2751 if (pElfStuff->iSymSh == UINT16_MAX) 2752 { 2753 pElfStuff->iSymSh = (uint16_t)i; 2754 pElfStuff->paSymbols = (Elf64_Sym const *)&pbFile[paShdrs[i].sh_offset]; 2755 pElfStuff->cSymbols = cSymbols; 2756 2757 if (paShdrs[i].sh_link != 0) 2758 { 2759 /* Note! The symbol string table section header may not have been validated yet! */ 2760 Elf64_Shdr const *pStrTabShdr = &paShdrs[paShdrs[i].sh_link]; 2761 pElfStuff->iStrSh = paShdrs[i].sh_link; 2762 pElfStuff->pchStrTab = (const char *)&pbFile[pStrTabShdr->sh_offset]; 2763 pElfStuff->cbStrTab = (size_t)pStrTabShdr->sh_size; 2764 } 2765 else 2766 fRet = error(pszFile, "Section #%u '%s': String table link is out of bounds (%#x)\n", 2767 i, pszShNm, paShdrs[i].sh_link); 2768 } 2769 else 2770 fRet = error(pszFile, "Section #%u '%s': Found additonal symbol table, previous in #%u\n", 2771 i, pszShNm, pElfStuff->iSymSh); 2772 } 2773 } 2774 return fRet; 2775 } 2776 2777 static bool convertElfSectionsToSegDefsAndGrpDefs(POMFWRITER pThis, PCELFDETAILS pElfStuff) 2778 { 2779 /* 2780 * Do the list of names pass. 2781 */ 2782 uint16_t idxGrpFlat, idxGrpData; 2783 uint16_t idxClassCode, idxClassData, idxClassDwarf; 2784 if ( !omfWriter_LNamesBegin(pThis) 2785 || !omfWriter_LNamesAddN(pThis, RT_STR_TUPLE("FLAT"), &idxGrpFlat) 2786 || !omfWriter_LNamesAddN(pThis, RT_STR_TUPLE("BS3DATA64_GROUP"), &idxGrpData) 2787 || !omfWriter_LNamesAddN(pThis, RT_STR_TUPLE("BS3CLASS64CODE"), &idxClassCode) 2788 || !omfWriter_LNamesAddN(pThis, RT_STR_TUPLE("FAR_DATA"), &idxClassData) 2789 || !omfWriter_LNamesAddN(pThis, RT_STR_TUPLE("DWARF"), &idxClassDwarf) 2790 ) 2791 return false; 2792 2793 bool fHaveData = false; 2794 Elf64_Shdr const *pShdr = &pElfStuff->paShdrs[1]; 2795 Elf64_Half const cSections = pElfStuff->pEhdr->e_shnum; 2796 for (Elf64_Half i = 1; i < cSections; i++, pShdr++) 2797 { 2798 const char *pszName = &pElfStuff->pchShStrTab[pShdr->sh_name]; 2799 if (*pszName == '\0') 2800 return error(pThis->pszSrc, "Section #%u has an empty name!\n", i); 2801 2802 switch (pShdr->sh_type) 2803 { 2804 case SHT_PROGBITS: 2805 case SHT_NOBITS: 2806 /* We drop a few sections we don't want:. */ 2807 if ( strcmp(pszName, ".comment") != 0 /* compiler info */ 2808 && strcmp(pszName, ".note.GNU-stack") != 0 /* some empty section for hinting the linker/whatever */ 2809 && strcmp(pszName, ".eh_frame") != 0 /* unwind / exception info */ 2810 ) 2811 { 2812 pThis->paSegments[i].iSegDef = UINT16_MAX; 2813 pThis->paSegments[i].iGrpDef = UINT16_MAX; 2814 2815 /* Translate the name and determine group and class. 2816 Note! We currently strip sub-sections. */ 2817 if ( strcmp(pszName, ".text") == 0 2818 || strncmp(pszName, RT_STR_TUPLE(".text.")) == 0) 2819 { 2820 pszName = "BS3TEXT64"; 2821 pThis->paSegments[i].iGrpNm = idxGrpFlat; 2822 pThis->paSegments[i].iClassNm = idxClassCode; 2823 } 2824 else if ( strcmp(pszName, ".data") == 0 2825 || strncmp(pszName, RT_STR_TUPLE(".data.")) == 0) 2826 { 2827 pszName = "BS3DATA64"; 2828 pThis->paSegments[i].iGrpNm = idxGrpData; 2829 pThis->paSegments[i].iClassNm = idxClassData; 2830 } 2831 else if (strcmp(pszName, ".bss") == 0) 2832 { 2833 pszName = "BS3BSS64"; 2834 pThis->paSegments[i].iGrpNm = idxGrpData; 2835 pThis->paSegments[i].iClassNm = idxClassData; 2836 } 2837 else if ( strcmp(pszName, ".rodata") == 0 2838 || strncmp(pszName, RT_STR_TUPLE(".rodata.")) == 0) 2839 { 2840 pszName = "BS3DATA64CONST"; 2841 pThis->paSegments[i].iGrpNm = idxGrpData; 2842 pThis->paSegments[i].iClassNm = idxClassData; 2843 } 2844 else if (strncmp(pszName, RT_STR_TUPLE(".debug_")) == 0) 2845 { 2846 pThis->paSegments[i].iGrpNm = UINT16_MAX; 2847 pThis->paSegments[i].iClassNm = idxClassDwarf; 2848 } 2849 else 2850 { 2851 pThis->paSegments[i].iGrpNm = idxGrpData; 2852 pThis->paSegments[i].iClassNm = idxClassData; 2853 error(pThis->pszSrc, "Unknown data (?) segment: '%s'\n", pszName); 2854 } 2855 2856 /* Save the name. */ 2857 pThis->paSegments[i].pszName = strdup(pszName); 2858 if (!pThis->paSegments[i].pszName) 2859 return error(pThis->pszSrc, "Out of memory!\n"); 2860 2861 /* Add the section name. */ 2862 if (!omfWriter_LNamesAdd(pThis, pThis->paSegments[i].pszName, &pThis->paSegments[i].iSegNm)) 2863 return false; 2864 2865 fHaveData |= pThis->paSegments[i].iGrpDef == idxGrpData; 2866 break; 2867 } 2868 /* fall thru */ 2869 2870 default: 2871 pThis->paSegments[i].iSegDef = UINT16_MAX; 2872 pThis->paSegments[i].iGrpDef = UINT16_MAX; 2873 pThis->paSegments[i].iSegNm = UINT16_MAX; 2874 pThis->paSegments[i].iGrpNm = UINT16_MAX; 2875 pThis->paSegments[i].iClassNm = UINT16_MAX; 2876 pThis->paSegments[i].pszName = NULL; 2877 break; 2878 } 2879 } 2880 2881 if (!omfWriter_LNamesEnd(pThis)) 2882 return false; 2883 2884 /* 2885 * Emit segment definitions. 2886 */ 2887 uint16_t iSegDef = 1; /* Start counting at 1. */ 2888 pShdr = &pElfStuff->paShdrs[1]; 2889 for (Elf64_Half i = 1; i < cSections; i++, pShdr++) 2890 { 2891 if (pThis->paSegments[i].iSegNm == UINT16_MAX) 2892 continue; 2893 2894 uint8_t bSegAttr = 0; 2895 2896 /* The A field. */ 2897 switch (pShdr->sh_addralign) 2898 { 2899 case 0: 2900 case 1: 2901 bSegAttr |= 1 << 5; 2902 break; 2903 case 2: 2904 bSegAttr |= 2 << 5; 2905 break; 2906 case 4: 2907 bSegAttr |= 5 << 5; 2908 break; 2909 case 8: 2910 case 16: 2911 bSegAttr |= 3 << 5; 2912 break; 2913 case 32: 2914 case 64: 2915 case 128: 2916 case 256: 2917 bSegAttr |= 4 << 5; 2918 break; 2919 default: 2920 bSegAttr |= 6 << 5; /* page aligned, pharlabs extension. */ 2921 break; 2922 } 2923 2924 /* The C field. */ 2925 bSegAttr |= 2 << 2; /* public */ 2926 2927 /* The B field. We don't have 4GB segments, so leave it as zero. */ 2928 2929 /* The D field shall be set as we're doing USE32. */ 2930 bSegAttr |= 1; 2931 2932 2933 /* Done. */ 2934 if (!omfWriter_SegDef(pThis, bSegAttr, (uint32_t)pShdr->sh_size, 2935 pThis->paSegments[i].iSegNm, 2936 pThis->paSegments[i].iClassNm)) 2937 return false; 2938 pThis->paSegments[i].iSegDef = iSegDef++; 2939 } 2940 2941 /* 2942 * Flat group definition (#1) - special, no members. 2943 */ 2944 uint16_t iGrpDef = 1; 2945 if ( !omfWriter_GrpDefBegin(pThis, idxGrpFlat) 2946 || !omfWriter_GrpDefEnd(pThis)) 2947 return false; 2948 for (uint16_t i = 0; i < cSections; i++) 2949 if (pThis->paSegments[i].iGrpNm == idxGrpFlat) 2950 pThis->paSegments[i].iGrpDef = iGrpDef; 2951 pThis->idxGrpFlat = iGrpDef++; 2952 2953 /* 2954 * Data group definition (#2). 2955 */ 2956 /** @todo do we need to consider missing segments and ordering? */ 2957 uint16_t cGrpNms = 0; 2958 uint16_t aiGrpNms[2]; 2959 if (fHaveData) 2960 aiGrpNms[cGrpNms++] = idxGrpData; 2961 for (uint32_t iGrpNm = 0; iGrpNm < cGrpNms; iGrpNm++) 2962 { 2963 if (!omfWriter_GrpDefBegin(pThis, aiGrpNms[iGrpNm])) 2964 return false; 2965 for (uint16_t i = 0; i < cSections; i++) 2966 if (pThis->paSegments[i].iGrpNm == aiGrpNms[iGrpNm]) 2967 { 2968 pThis->paSegments[i].iGrpDef = iGrpDef; 2969 if (!omfWriter_GrpDefAddSegDef(pThis, pThis->paSegments[i].iSegDef)) 2970 return false; 2971 } 2972 if (!omfWriter_GrpDefEnd(pThis)) 2973 return false; 2974 iGrpDef++; 2975 } 2976 2977 return true; 2978 } 2979 2980 static bool convertElfSymbolsToPubDefsAndExtDefs(POMFWRITER pThis, PCELFDETAILS pElfStuff) 2981 { 2982 if (!pElfStuff->cSymbols) 2983 return true; 2984 2985 /* 2986 * Process the symbols the first. 2987 */ 2988 uint32_t cAbsSyms = 0; 2989 uint32_t cExtSyms = 0; 2990 uint32_t cPubSyms = 0; 2991 for (uint32_t iSeg = 0; iSeg < pThis->cSegments; iSeg++) 2992 pThis->paSegments[iSeg].cPubDefs = 0; 2993 2994 uint32_t const cSections = pElfStuff->pEhdr->e_shnum; 2995 uint32_t const cSymbols = pElfStuff->cSymbols; 2996 Elf64_Sym const * const paSymbols = pElfStuff->paSymbols; 2997 for (uint32_t iSym = 0; iSym < cSymbols; iSym++) 2998 { 2999 const uint8_t bBind = ELF64_ST_BIND(paSymbols[iSym].st_info); 3000 const uint8_t bType = ELF64_ST_TYPE(paSymbols[iSym].st_info); 3001 const char *pszSymName = &pElfStuff->pchStrTab[paSymbols[iSym].st_name]; 3002 if ( *pszSymName == '\0' 3003 && bType == STT_SECTION 3004 && paSymbols[iSym].st_shndx < cSections) 3005 pszSymName = &pElfStuff->pchShStrTab[pElfStuff->paShdrs[paSymbols[iSym].st_shndx].sh_name]; 3006 3007 pThis->paSymbols[iSym].enmType = OMFSYMTYPE_IGNORED; 3008 pThis->paSymbols[iSym].idx = UINT16_MAX; 3009 pThis->paSymbols[iSym].idxSegDef = UINT16_MAX; 3010 pThis->paSymbols[iSym].idxGrpDef = UINT16_MAX; 3011 3012 uint32_t const idxSection = paSymbols[iSym].st_shndx; 3013 if (idxSection == SHN_UNDEF) 3014 { 3015 if (bBind == STB_GLOBAL) 3016 { 3017 pThis->paSymbols[iSym].enmType = OMFSYMTYPE_EXTDEF; 3018 cExtSyms++; 3019 if (*pszSymName == '\0') 3020 return error(pThis->pszSrc, "External symbol #%u (%s) has an empty name.\n", iSym, pszSymName); 3021 } 3022 else if (bBind != STB_LOCAL || iSym != 0) /* Entry zero is usually a dummy. */ 3023 return error(pThis->pszSrc, "Unsupported or invalid bind type %#x for undefined symbol #%u (%s)\n", 3024 bBind, iSym, pszSymName); 3025 } 3026 else if (idxSection < cSections) 3027 { 3028 pThis->paSymbols[iSym].idxSegDef = pThis->paSegments[idxSection].iSegDef; 3029 pThis->paSymbols[iSym].idxGrpDef = pThis->paSegments[idxSection].iGrpDef; 3030 if (bBind == STB_GLOBAL) 3031 { 3032 pThis->paSymbols[iSym].enmType = OMFSYMTYPE_PUBDEF; 3033 pThis->paSegments[idxSection].cPubDefs++; 3034 cPubSyms++; 3035 if (bType == STT_SECTION) 3036 return error(pThis->pszSrc, "Don't know how to export STT_SECTION symbol #%u (%s)\n", iSym, pszSymName); 3037 if (*pszSymName == '\0') 3038 return error(pThis->pszSrc, "Public symbol #%u (%s) has an empty name.\n", iSym, pszSymName); 3039 } 3040 else if (bType == STT_SECTION) 3041 pThis->paSymbols[iSym].enmType = OMFSYMTYPE_SEGDEF; 3042 else 3043 pThis->paSymbols[iSym].enmType = OMFSYMTYPE_INTERNAL; 3044 } 3045 else if (idxSection == SHN_ABS) 3046 { 3047 if (bType != STT_FILE) 3048 { 3049 if (bBind == STB_GLOBAL) 3050 { 3051 pThis->paSymbols[iSym].enmType = OMFSYMTYPE_PUBDEF; 3052 pThis->paSymbols[iSym].idxSegDef = 0; 3053 pThis->paSymbols[iSym].idxGrpDef = 0; 3054 cAbsSyms++; 3055 if (*pszSymName == '\0') 3056 return error(pThis->pszSrc, "Public absolute symbol #%u (%s) has an empty name.\n", iSym, pszSymName); 3057 } 3058 else 3059 return error(pThis->pszSrc, "Unsupported or invalid bind type %#x for absolute symbol #%u (%s)\n", 3060 bBind, iSym, pszSymName); 3061 } 3062 } 3063 else 3064 return error(pThis->pszSrc, "Unsupported or invalid section number %#x for symbol #%u (%s)\n", 3065 idxSection, iSym, pszSymName); 3066 } 3067 3068 /* 3069 * Emit the PUBDEFs the first time around (see order of records in TIS spec). 3070 */ 3071 uint16_t idxPubDef = 1; 3072 if (cPubSyms) 3073 { 3074 for (uint32_t iSeg = 0; iSeg < pThis->cSegments; iSeg++) 3075 if (pThis->paSegments[iSeg].cPubDefs > 0) 3076 { 3077 uint16_t const idxSegDef = pThis->paSegments[iSeg].iSegDef; 3078 if (!omfWriter_PubDefBegin(pThis, pThis->paSegments[iSeg].iGrpDef, idxSegDef)) 3079 return false; 3080 for (uint16_t iSym = 0; iSym < cSymbols; iSym++) 3081 if ( pThis->paSymbols[iSym].idxSegDef == idxSegDef 3082 && pThis->paSymbols[iSym].enmType == OMFSYMTYPE_PUBDEF) 3083 { 3084 const char *pszName = &pElfStuff->pchStrTab[paSymbols[iSym].st_name]; 3085 if (!omfWriter_PubDefAdd(pThis, paSymbols[iSym].st_value, pszName)) 3086 return false; 3087 3088 /* If the symbol doesn't start with an underscore and is a _c64 or _lm64 symbol, 3089 add an underscore prefixed alias to ease access from 16-bit and 32-bit code. */ 3090 size_t cchName = strlen(pszName); 3091 if ( *pszName != '_' 3092 && ( (cchName > 4 && strcmp(&pszName[cchName - 4], "_c64") == 0) 3093 || (cchName > 5 && strcmp(&pszName[cchName - 5], "_lm64") == 0) ) ) 3094 { 3095 char szCdeclName[512]; 3096 if (cchName > sizeof(szCdeclName) - 2) 3097 cchName = sizeof(szCdeclName) - 2; 3098 szCdeclName[0] = '_'; 3099 memcpy(&szCdeclName[1], pszName, cchName); 3100 szCdeclName[cchName + 1] = '\0'; 3101 if (!omfWriter_PubDefAdd(pThis, paSymbols[iSym].st_value, szCdeclName)) 3102 return false; 3103 } 3104 3105 pThis->paSymbols[iSym].idx = idxPubDef++; 3106 } 3107 if (!omfWriter_PubDefEnd(pThis)) 3108 return false; 3109 } 3110 } 3111 3112 if (cAbsSyms > 0) 3113 { 3114 if (!omfWriter_PubDefBegin(pThis, 0, 0)) 3115 return false; 3116 for (uint16_t iSym = 0; iSym < cSymbols; iSym++) 3117 if ( pThis->paSymbols[iSym].idxSegDef == 0 3118 && pThis->paSymbols[iSym].enmType == OMFSYMTYPE_PUBDEF) 3119 { 3120 const char *pszName = &pElfStuff->pchStrTab[paSymbols[iSym].st_name]; 3121 if (!omfWriter_PubDefAdd(pThis, paSymbols[iSym].st_value, pszName)) 3122 return false; 3123 pThis->paSymbols[iSym].idx = idxPubDef++; 3124 } 3125 if (!omfWriter_PubDefEnd(pThis)) 3126 return false; 3127 } 3128 3129 /* 3130 * Go over the symbol table and emit external definition records. 3131 */ 3132 if (!omfWriter_ExtDefBegin(pThis)) 3133 return false; 3134 uint16_t idxExtDef = 1; 3135 for (uint16_t iSym = 0; iSym < cSymbols; iSym++) 3136 if (pThis->paSymbols[iSym].enmType == OMFSYMTYPE_EXTDEF) 3137 { 3138 const char *pszName = &pElfStuff->pchStrTab[paSymbols[iSym].st_name]; 3139 if (!omfWriter_ExtDefAdd(pThis, pszName)) 3140 return false; 3141 pThis->paSymbols[iSym].idx = idxExtDef++; 3142 } 3143 3144 if (!omfWriter_ExtDefEnd(pThis)) 3145 return false; 3146 3147 return true; 3148 } 3149 3150 static bool convertElfSectionsToLeDataAndFixupps(POMFWRITER pThis, PCELFDETAILS pElfStuff, uint8_t const *pbFile, size_t cbFile) 3151 { 3152 Elf64_Sym const *paSymbols = pElfStuff->paSymbols; 3153 Elf64_Shdr const *paShdrs = pElfStuff->paShdrs; 3154 bool fRet = true; 3155 for (uint32_t i = 1; i < pThis->cSegments; i++) 3156 { 3157 if (pThis->paSegments[i].iSegDef == UINT16_MAX) 3158 continue; 3159 3160 const char *pszSegNm = &pElfStuff->pchShStrTab[paShdrs[i].sh_name]; 3161 bool const fRelocs = i + 1 < pThis->cSegments && paShdrs[i + 1].sh_type == SHT_RELA; 3162 uint32_t cRelocs = fRelocs ? paShdrs[i + 1].sh_size / sizeof(Elf64_Rela) : 0; 3163 Elf64_Rela const *paRelocs = fRelocs ? (Elf64_Rela *)&pbFile[paShdrs[i + 1].sh_offset] : NULL; 3164 Elf64_Xword cbVirtData = paShdrs[i].sh_size; 3165 Elf64_Xword cbData = paShdrs[i].sh_type == SHT_NOBITS ? 0 : cbVirtData; 3166 uint8_t const *pbData = &pbFile[paShdrs[i].sh_offset]; 3167 uint32_t off = 0; 3168 3169 /* The OMF record size requires us to split larger sections up. To make 3170 life simple, we fill zeros for unitialized (BSS) stuff. */ 3171 const uint32_t cbMaxData = RT_MIN(OMF_MAX_RECORD_PAYLOAD - 1 - (pThis->paSegments[i].iSegDef >= 128) - 4 - 1, _1K); 3172 while (cbVirtData > 0) 3173 { 3174 /* Figure out how many bytes to put out in this chunk. Must make sure 3175 fixups doesn't cross chunk boundraries. ASSUMES sorted relocs. */ 3176 uint32_t cChunkRelocs = cRelocs; 3177 uint32_t cbChunk = cbVirtData; 3178 uint32_t offEnd = off + cbChunk; 3179 if (cbChunk > cbMaxData) 3180 { 3181 cbChunk = cbMaxData; 3182 offEnd = off + cbChunk; 3183 cChunkRelocs = 0; 3184 3185 /* Quickly determin the reloc range. */ 3186 while ( cChunkRelocs < cRelocs 3187 && paRelocs[cChunkRelocs].r_offset < offEnd) 3188 cChunkRelocs++; 3189 3190 /* Ensure final reloc doesn't go beyond chunk. */ 3191 while ( cChunkRelocs > 0 3192 && paRelocs[cChunkRelocs - 1].r_offset 3193 + ELF_AMD64_RELOC_SIZE(ELF64_R_TYPE(paRelocs[cChunkRelocs - 1].r_info)) 3194 > offEnd) 3195 { 3196 uint32_t cbDrop = offEnd - paRelocs[cChunkRelocs - 1].r_offset; 3197 cbChunk -= cbDrop; 3198 offEnd -= cbDrop; 3199 cChunkRelocs--; 3200 } 3201 3202 if (!cbVirtData) 3203 return error(pThis->pszSrc, "Wtf? cbVirtData is zero!\n"); 3204 } 3205 3206 /* 3207 * We stash the bytes into the OMF writer record buffer, receiving a 3208 * pointer to the start of it so we can make adjustments if necessary. 3209 */ 3210 uint8_t *pbCopy; 3211 if (!omfWriter_LEDataBegin(pThis, pThis->paSegments[i].iSegDef, off, cbChunk, cbData, pbData, &pbCopy)) 3212 return false; 3213 3214 /* 3215 * Convert fiuxps. 3216 */ 3217 for (uint32_t iReloc = 0; iReloc < cChunkRelocs; iReloc++) 3218 { 3219 /* Get the OMF and ELF data for the symbol the reloc references. */ 3220 uint32_t const uType = ELF64_R_TYPE(paRelocs[iReloc].r_info); 3221 uint32_t const iSymbol = ELF64_R_SYM(paRelocs[iReloc].r_info); 3222 Elf64_Sym const * const pElfSym = &paSymbols[iSymbol]; 3223 POMFSYMBOL const pOmfSym = &pThis->paSymbols[iSymbol]; 3224 const char * const pszSymName = &pElfStuff->pchStrTab[pElfSym->st_name]; 3225 3226 /* Calc fixup location in the pending chunk and setup a flexible pointer to it. */ 3227 uint16_t offDataRec = (uint16_t)(paRelocs[iReloc].r_offset - off); 3228 RTPTRUNION uLoc; 3229 uLoc.pu8 = &pbCopy[offDataRec]; 3230 3231 /* OMF fixup data initialized with typical defaults. */ 3232 bool fSelfRel = true; 3233 uint8_t bLocation = OMF_FIX_LOC_32BIT_OFFSET; 3234 uint8_t bFrame = OMF_FIX_F_GRPDEF; 3235 uint16_t idxFrame = pThis->idxGrpFlat; 3236 uint8_t bTarget; 3237 uint16_t idxTarget; 3238 bool fTargetDisp; 3239 uint32_t offTargetDisp; 3240 switch (pOmfSym->enmType) 3241 { 3242 case OMFSYMTYPE_INTERNAL: 3243 case OMFSYMTYPE_PUBDEF: 3244 bTarget = OMF_FIX_T_SEGDEF; 3245 idxTarget = pOmfSym->idxSegDef; 3246 fTargetDisp = true; 3247 offTargetDisp = pElfSym->st_value; 3248 break; 3249 3250 case OMFSYMTYPE_SEGDEF: 3251 bTarget = OMF_FIX_T_SEGDEF_NO_DISP; 3252 idxTarget = pOmfSym->idxSegDef; 3253 fTargetDisp = false; 3254 offTargetDisp = 0; 3255 break; 3256 3257 case OMFSYMTYPE_EXTDEF: 3258 bTarget = OMF_FIX_T_EXTDEF_NO_DISP; 3259 idxTarget = pOmfSym->idx; 3260 fTargetDisp = false; 3261 offTargetDisp = 0; 3262 break; 3263 3264 default: 3265 return error(pThis->pszSrc, "Relocation in segment #%u '%s' references ignored or invalid symbol (%s)\n", 3266 i, pszSegNm, pszSymName); 3267 } 3268 3269 /* Do COFF relocation type conversion. */ 3270 switch (uType) 3271 { 3272 case R_X86_64_64: 3273 { 3274 int64_t iAddend = paRelocs[iReloc].r_addend; 3275 if (iAddend > _1G || iAddend < -_1G) 3276 fRet = error(pThis->pszSrc, "R_X86_64_64 with large addend (%" ELF_FMT_D64 ") at %#x in segment #%u '%s'\n", 3277 iAddend, paRelocs[iReloc].r_offset, i, pszSegNm); 3278 *uLoc.pu64 = iAddend; 3279 fSelfRel = false; 3280 break; 3281 } 3282 3283 case R_X86_64_32: 3284 case R_X86_64_32S: /* signed, unsigned, whatever. */ 3285 fSelfRel = false; 3286 /* fall thru */ 3287 case R_X86_64_PC32: 3288 { 3289 /* defaults are ok, just handle the addend. */ 3290 int32_t iAddend = paRelocs[iReloc].r_addend; 3291 if (iAddend != paRelocs[iReloc].r_addend) 3292 fRet = error(pThis->pszSrc, "R_X86_64_PC32 with large addend (%d) at %#x in segment #%u '%s'\n", 3293 iAddend, paRelocs[iReloc].r_offset, i, pszSegNm); 3294 *uLoc.pu32 = iAddend; 3295 break; 3296 } 3297 3298 case R_X86_64_NONE: 3299 continue; /* Ignore this one */ 3300 3301 case R_X86_64_GOT32: 3302 case R_X86_64_PLT32: 3303 case R_X86_64_COPY: 3304 case R_X86_64_GLOB_DAT: 3305 case R_X86_64_JMP_SLOT: 3306 case R_X86_64_RELATIVE: 3307 case R_X86_64_GOTPCREL: 3308 case R_X86_64_16: 3309 case R_X86_64_PC16: 3310 case R_X86_64_8: 3311 case R_X86_64_PC8: 3312 case R_X86_64_DTPMOD64: 3313 case R_X86_64_DTPOFF64: 3314 case R_X86_64_TPOFF64: 3315 case R_X86_64_TLSGD: 3316 case R_X86_64_TLSLD: 3317 case R_X86_64_DTPOFF32: 3318 case R_X86_64_GOTTPOFF: 3319 case R_X86_64_TPOFF32: 3320 default: 3321 return error(pThis->pszSrc, "Unsupported fixup type %#x (%s) at rva=%#x in section #%u '%s' against '%s'\n", 3322 uType, g_apszElfAmd64RelTypes[uType], paRelocs[iReloc].r_offset, i, pszSegNm, pszSymName); 3323 } 3324 3325 /* Add the fixup. */ 3326 if (idxFrame == UINT16_MAX) 3327 error(pThis->pszSrc, "idxFrame=UINT16_MAX for %s type=%s\n", pszSymName, g_apszElfAmd64RelTypes[uType]); 3328 fRet = omfWriter_LEDataAddFixup(pThis, offDataRec, fSelfRel, bLocation, bFrame, idxFrame, 3329 bTarget, idxTarget, fTargetDisp, offTargetDisp) && fRet; 3330 } 3331 3332 /* 3333 * Write the LEDATA and associated FIXUPPs. 3334 */ 3335 if (!omfWriter_LEDataEnd(pThis)) 3336 return false; 3337 3338 /* 3339 * Advance. 3340 */ 3341 paRelocs += cChunkRelocs; 3342 cRelocs -= cChunkRelocs; 3343 if (cbData > cbChunk) 3344 { 3345 cbData -= cbChunk; 3346 pbData += cbChunk; 3347 } 3348 else 3349 cbData = 0; 3350 off += cbChunk; 3351 cbVirtData -= cbChunk; 3352 } 3353 } 3354 3355 return fRet; 3356 } 3357 3358 3359 static bool convertMachoToOmf(const char *pszFile, uint8_t const *pbFile, size_t cbFile, FILE *pDst) 3360 { 3361 /* 3362 * Validate the source file a little. 3363 */ 3364 ELFDETAILS ElfStuff; 3365 if (!validateElf(pszFile, pbFile, cbFile, &ElfStuff)) 3366 return false; 3367 3368 /* 3369 * Instantiate the OMF writer. 3370 */ 3371 POMFWRITER pThis = omfWriter_Create(pszFile, ElfStuff.pEhdr->e_shnum, ElfStuff.cSymbols, pDst); 3372 if (!pThis) 3373 return false; 3374 3375 /* 3376 * Write the OMF object file. 3377 */ 3378 if (omfWriter_BeginModule(pThis, pszFile)) 3379 { 3380 Elf64_Ehdr const *pEhdr = (Elf64_Ehdr const *)pbFile; 3381 Elf64_Shdr const *paShdrs = (Elf64_Shdr const *)&pbFile[pEhdr->e_shoff]; 3382 const char *pszStrTab = (const char *)&pbFile[paShdrs[pEhdr->e_shstrndx].sh_offset]; 3383 3384 if ( convertElfSectionsToSegDefsAndGrpDefs(pThis, &ElfStuff) 3385 && convertElfSymbolsToPubDefsAndExtDefs(pThis, &ElfStuff) 3386 && omfWriter_LinkPassSeparator(pThis) 3387 && convertElfSectionsToLeDataAndFixupps(pThis, &ElfStuff, pbFile, cbFile) 3388 && omfWriter_EndModule(pThis) ) 3389 { 3390 3391 omfWriter_Destroy(pThis); 3392 return true; 3393 } 3394 } 3395 3396 omfWriter_Destroy(pThis); 3397 return false; 3398 } 3399 3400 #endif /* !MACHO_TO_OMF_CONVERSION */ 3401 2585 3402 2586 3403 /********************************************************************************************************************************* … … 2852 3669 && pbFile[3] == ELFMAG3) 2853 3670 { 2854 #ifdef ELF_TO_OMF_CONVERSION2855 3671 if (writefile(szOrgFile, pvFile, cbFile)) 2856 3672 { … … 2862 3678 } 2863 3679 } 2864 #else2865 fRc = writefile(szOrgFile, pvFile, cbFile)2866 && convertelf(pszFile, pbFile, cbFile)2867 && writefile(pszFile, pvFile, cbFile);2868 #endif2869 3680 } 2870 3681 else if ( cbFile > sizeof(IMAGE_FILE_HEADER)
Note:
See TracChangeset
for help on using the changeset viewer.