- Timestamp:
- Mar 8, 2016 1:02:13 PM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/ValidationKit/bootsectors/bs3kit/VBoxBs3ObjConverter.cpp
r59953 r59954 799 799 }; 800 800 801 static bool validateElf(const char *pszFile, uint8_t const *pbFile, size_t cbFile) 802 { 801 802 typedef struct ELFDETAILS 803 { 804 Elf64_Ehdr const *pEhdr; 805 Elf64_Shdr const *paShdrs; 806 const char *pchShStrTab; 807 uint16_t iSymSh; 808 uint16_t iStrSh; 809 } ELFDETAILS; 810 typedef ELFDETAILS *PELFDETAILS; 811 812 813 static bool validateElf(const char *pszFile, uint8_t const *pbFile, size_t cbFile, PELFDETAILS pElfStuff) 814 { 815 /* 816 * Initialize the ELF details structure. 817 */ 818 memset(pElfStuff, 0, sizeof(*pElfStuff)); 819 pElfStuff->iSymSh = UINT16_MAX; 820 pElfStuff->iStrSh = UINT16_MAX; 821 803 822 /* 804 823 * Validate the header and our other expectations. 805 824 */ 806 825 Elf64_Ehdr const *pEhdr = (Elf64_Ehdr const *)pbFile; 826 pElfStuff->pEhdr = pEhdr; 807 827 if ( pEhdr->e_ident[EI_CLASS] != ELFCLASS64 808 828 || pEhdr->e_ident[EI_DATA] != ELFDATA2LSB … … 831 851 */ 832 852 Elf64_Shdr const *paShdrs = (Elf64_Shdr const *)&pbFile[pEhdr->e_shoff]; 833 const char * pszStrTab = (const char *)&pbFile[paShdrs[pEhdr->e_shstrndx].sh_offset]; 853 pElfStuff->paShdrs = paShdrs; 854 855 Elf64_Xword const cbShStrTab = paShdrs[pEhdr->e_shstrndx].sh_size; 856 if ( paShdrs[pEhdr->e_shstrndx].sh_offset > cbFile 857 || cbShStrTab > cbFile 858 || paShdrs[pEhdr->e_shstrndx].sh_offset + cbShStrTab > cbFile) 859 return error(pszFile, 860 "Section string table is outside the file (sh_offset=%#" ELF_FMT_X64 " sh_size=%#" ELF_FMT_X64 " cbFile=%#" ELF_FMT_X64 ")\n", 861 paShdrs[pEhdr->e_shstrndx].sh_offset, paShdrs[pEhdr->e_shstrndx].sh_size, (Elf64_Xword)cbFile); 862 const char *pchShStrTab = (const char *)&pbFile[paShdrs[pEhdr->e_shstrndx].sh_offset]; 863 pElfStuff->pchShStrTab = pchShStrTab; 834 864 835 865 /* … … 837 867 */ 838 868 bool fRet = true; 869 for (uint32_t i = 1; i < pEhdr->e_shnum; i++) 870 { 871 if (paShdrs[i].sh_name >= cbShStrTab) 872 return error(pszFile, "Invalid sh_name value (%#x) for section #%u\n", paShdrs[i].sh_name, i); 873 const char *pszShNm = &pchShStrTab[paShdrs[i].sh_name]; 874 875 if ( paShdrs[i].sh_offset > cbFile 876 || paShdrs[i].sh_size > cbFile 877 || paShdrs[i].sh_offset + paShdrs[i].sh_size > cbFile) 878 return error(pszFile, "Section #%u '%s' has data outside the file: %#" ELF_FMT_X64 " LB %#" ELF_FMT_X64 " (cbFile=%#" ELF_FMT_X64 ")\n", 879 i, pszShNm, paShdrs[i].sh_offset, paShdrs[i].sh_size, (Elf64_Xword)cbFile); 880 if (g_cVerbose) 881 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" 882 " link=%u info=%#x align=%#" ELF_FMT_X64 " entsize=%#" ELF_FMT_X64 "\n", 883 i, paShdrs[i].sh_name, pszShNm, paShdrs[i].sh_type, paShdrs[i].sh_flags, 884 paShdrs[i].sh_addr, paShdrs[i].sh_offset, paShdrs[i].sh_size, 885 paShdrs[i].sh_link, paShdrs[i].sh_info, paShdrs[i].sh_addralign, paShdrs[i].sh_entsize); 886 887 if (paShdrs[i].sh_link >= pEhdr->e_shnum) 888 return error(pszFile, "Section #%u '%s' links to a section outside the section table: %#x, max %#x\n", 889 i, pszShNm, paShdrs[i].sh_link, pEhdr->e_shnum); 890 if (!RT_IS_POWER_OF_TWO(paShdrs[i].sh_addralign)) 891 return error(pszFile, "Section #%u '%s' alignment value is not a power of two: %#" ELF_FMT_X64 "\n", 892 i, pszShNm, paShdrs[i].sh_addralign); 893 if (!RT_IS_POWER_OF_TWO(paShdrs[i].sh_addralign)) 894 return error(pszFile, "Section #%u '%s' alignment value is not a power of two: %#" ELF_FMT_X64 "\n", 895 i, pszShNm, paShdrs[i].sh_addralign); 896 897 if (paShdrs[i].sh_type == SHT_RELA) 898 { 899 if (paShdrs[i].sh_entsize != sizeof(Elf64_Rela)) 900 return error(pszFile, "Expected sh_entsize to be %u not %u for section #%u (%s)\n", (unsigned)sizeof(Elf64_Rela), 901 paShdrs[i].sh_entsize, i, pszShNm); 902 uint32_t const cRelocs = paShdrs[i].sh_size / sizeof(Elf64_Rela); 903 if (cRelocs * sizeof(Elf64_Rela) != paShdrs[i].sh_size) 904 return error(pszFile, "Uneven relocation entry count in #%u (%s): sh_size=%#" ELF_FMT_X64 "\n", (unsigned)sizeof(Elf64_Rela), 905 paShdrs[i].sh_entsize, i, pszShNm, paShdrs[i].sh_size); 906 if ( paShdrs[i].sh_offset > cbFile 907 || paShdrs[i].sh_size >= cbFile 908 || paShdrs[i].sh_offset + paShdrs[i].sh_size > cbFile) 909 return error(pszFile, "The content of section #%u '%s' is outside the file (%#" ELF_FMT_X64 " LB %#" ELF_FMT_X64 ", cbFile=%#lx)\n", 910 i, pszShNm, paShdrs[i].sh_offset, paShdrs[i].sh_size, (unsigned long)cbFile); 911 912 Elf64_Rela const *paRelocs = (Elf64_Rela *)&pbFile[paShdrs[i].sh_offset]; 913 for (uint32_t j = 0; j < cRelocs; j++) 914 { 915 uint8_t const bType = ELF64_R_TYPE(paRelocs[j].r_info); 916 if (RT_UNLIKELY(bType >= R_X86_64_COUNT)) 917 fRet = error(pszFile, 918 "%#018" ELF_FMT_X64 " %#018" ELF_FMT_X64 " unknown fix up %#x (%+" ELF_FMT_D64 ")\n", 919 paRelocs[j].r_offset, paRelocs[j].r_info, bType, paRelocs[j].r_addend); 920 } 921 } 922 else if (paShdrs[i].sh_type == SHT_SYMTAB) 923 { 924 if (pElfStuff->iSymSh == UINT16_MAX) 925 { 926 pElfStuff->iSymSh = (uint16_t)i; 927 if (paShdrs[i].sh_entsize == sizeof(Elf64_Sym)) 928 { 929 930 } 931 else 932 fRet = error(pszFile, "Unsupported symbol table entry size: #%u (expected #%u)\n", 933 i, pszShNm, paShdrs[i].sh_entsize, sizeof(Elf64_Sym)); 934 } 935 else 936 fRet = error(pszFile, "2nd symbol table found #%u '%s' (previous #u)\n", i, pszShNm, pElfStuff->iSymSh); 937 } 938 else if (paShdrs[i].sh_type == SHT_REL) 939 fRet = error(pszFile, "Did not expect SHT_REL sections (#%u '%s')\n", i, pszShNm); 940 } 941 return fRet; 942 } 943 944 945 #ifdef ELF_TO_OMF_CONVERSION 946 947 static bool convertElfToOmf(const char *pszFile, uint8_t const *pbFile, size_t cbFile, FILE *pDst) 948 { 949 /* 950 * Validate the source file a little. 951 */ 952 ELFDETAILS ElfStuff; 953 if (!validateElf(pszFile, pbFile, cbFile, &ElfStuff)) 954 return false; 955 956 /* 957 * Instantiate the OMF writer. 958 */ 959 PIMAGE_FILE_HEADER pHdr = (PIMAGE_FILE_HEADER)pbFile; 960 POMFWRITER pThis = omfWriter_Create(pszFile, pHdr->NumberOfSections, pHdr->NumberOfSymbols, pDst); 961 if (!pThis) 962 return false; 963 964 /* 965 * Write the OMF object file. 966 */ 967 if (omfWriter_BeginModule(pThis, pszFile)) 968 { 969 Elf64_Ehdr const *pEhdr = (Elf64_Ehdr const *)pbFile; 970 Elf64_Shdr const *paShdrs = (Elf64_Shdr const *)&pbFile[pEhdr->e_shoff]; 971 const char *pszStrTab = (const char *)&pbFile[paShdrs[pEhdr->e_shstrndx].sh_offset]; 972 973 if ( convertElfSectionsToSegDefsAndGrpDefs(pThis, paShdrs, pHdr->NumberOfSections) 974 //&& convertElfSymbolsToPubDefsAndExtDefs(pThis, paSymTab, pHdr->NumberOfSymbols, pchStrTab, paShdrs) 975 && omfWriter_LinkPassSeparator(pThis) 976 //&& convertElfSectionsToLeDataAndFixupps(pThis, pbFile, cbFile, paShdrs, pHdr->NumberOfSections, 977 // paSymTab, pHdr->NumberOfSymbols, pchStrTab) 978 && omfWriter_EndModule(pThis) ) 979 { 980 981 omfWriter_Destroy(pThis); 982 return true; 983 } 984 } 985 986 omfWriter_Destroy(pThis); 987 return false; 988 } 989 990 #else /* !ELF_TO_OMF_CONVERSION */ 991 992 static bool convertelf(const char *pszFile, uint8_t *pbFile, size_t cbFile) 993 { 994 /* 995 * Validate the header and our other expectations. 996 */ 997 ELFDETAILS ElfStuff; 998 if (!validateElf(pszFile, pbFile, cbFile, &ElfStuff)) 999 return false; 1000 1001 /* 1002 * Locate the section name string table. 1003 * We assume it's okay as we only reference it in verbose mode. 1004 */ 1005 Elf64_Ehdr const *pEhdr = (Elf64_Ehdr const *)pbFile; 1006 Elf64_Shdr const *paShdrs = (Elf64_Shdr const *)&pbFile[pEhdr->e_shoff]; 1007 const char *pszStrTab = (const char *)&pbFile[paShdrs[pEhdr->e_shstrndx].sh_offset]; 1008 1009 /* 1010 * Work the section table. 1011 */ 839 1012 for (uint32_t i = 1; i < pEhdr->e_shnum; i++) 840 1013 { … … 847 1020 if (paShdrs[i].sh_type == SHT_RELA) 848 1021 { 849 if (paShdrs[i].sh_entsize != sizeof(Elf64_Rela))850 return error(pszFile, "Expected sh_entsize to be %u not %u for section #%u (%s)\n", (unsigned)sizeof(Elf64_Rela),851 paShdrs[i].sh_entsize, i, &pszStrTab[paShdrs[i].sh_name]);852 uint32_t const cRelocs = paShdrs[i].sh_size / sizeof(Elf64_Rela);853 if (cRelocs * sizeof(Elf64_Rela) != paShdrs[i].sh_size)854 return error(pszFile, "Uneven relocation entry count in #%u (%s): sh_size=%#" ELF_FMT_X64 "\n", (unsigned)sizeof(Elf64_Rela),855 paShdrs[i].sh_entsize, i, &pszStrTab[paShdrs[i].sh_name], paShdrs[i].sh_size);856 if ( paShdrs[i].sh_offset > cbFile857 || paShdrs[i].sh_size >= cbFile858 || paShdrs[i].sh_offset + paShdrs[i].sh_size > cbFile)859 return error(pszFile, "The content of section #%u '%s' is outside the file (%#" ELF_FMT_X64 " LB %#" ELF_FMT_X64 ", cbFile=%#lx)\n",860 i, &pszStrTab[paShdrs[i].sh_name], paShdrs[i].sh_offset, paShdrs[i].sh_size, (unsigned long)cbFile);861 862 Elf64_Rela const *paRelocs = (Elf64_Rela *)&pbFile[paShdrs[i].sh_offset];863 for (uint32_t j = 0; j < cRelocs; j++)864 {865 uint8_t const bType = ELF64_R_TYPE(paRelocs[j].r_info);866 if (RT_UNLIKELY(bType >= R_X86_64_COUNT))867 fRet = error(pszFile,868 "%#018" ELF_FMT_X64 " %#018" ELF_FMT_X64 " unknown fix up %#x (%+" ELF_FMT_D64 ")\n",869 paRelocs[j].r_offset, paRelocs[j].r_info, bType, paRelocs[j].r_addend);870 }871 }872 else if (paShdrs[i].sh_type == SHT_REL)873 fRet = error(pszFile, "Did not expect SHT_REL sections (#%u '%s')\n", i, &pszStrTab[paShdrs[i].sh_name]);874 }875 return fRet;876 }877 878 879 880 static bool convertelf(const char *pszFile, uint8_t *pbFile, size_t cbFile)881 {882 /*883 * Validate the header and our other expectations.884 */885 if (!validateElf(pszFile, pbFile, cbFile))886 return false;887 888 /*889 * Locate the section name string table.890 * We assume it's okay as we only reference it in verbose mode.891 */892 Elf64_Ehdr const *pEhdr = (Elf64_Ehdr const *)pbFile;893 Elf64_Shdr const *paShdrs = (Elf64_Shdr const *)&pbFile[pEhdr->e_shoff];894 const char * pszStrTab = (const char *)&pbFile[paShdrs[pEhdr->e_shstrndx].sh_offset];895 896 /*897 * Work the section table.898 */899 for (uint32_t i = 1; i < pEhdr->e_shnum; i++)900 {901 if (g_cVerbose)902 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"903 " link=%u info=%#x align=%#" ELF_FMT_X64 " entsize=%#" ELF_FMT_X64 "\n",904 i, paShdrs[i].sh_name, &pszStrTab[paShdrs[i].sh_name], paShdrs[i].sh_type, paShdrs[i].sh_flags,905 paShdrs[i].sh_addr, paShdrs[i].sh_offset, paShdrs[i].sh_size,906 paShdrs[i].sh_link, paShdrs[i].sh_info, paShdrs[i].sh_addralign, paShdrs[i].sh_entsize);907 if (paShdrs[i].sh_type == SHT_RELA)908 {909 1022 Elf64_Rela *paRelocs = (Elf64_Rela *)&pbFile[paShdrs[i].sh_offset]; 910 1023 uint32_t const cRelocs = paShdrs[i].sh_size / sizeof(Elf64_Rela); … … 931 1044 } 932 1045 1046 #endif /* !ELF_TO_OMF_CONVERSION */ 933 1047 934 1048 … … 1746 1860 && convertCoffSectionsToLeDataAndFixupps(pThis, pbFile, cbFile, paShdrs, pHdr->NumberOfSections, 1747 1861 paSymTab, pHdr->NumberOfSymbols, pchStrTab) 1748 1749 1862 && omfWriter_EndModule(pThis) ) 1750 1863 { … … 1757 1870 omfWriter_Destroy(pThis); 1758 1871 return false; 1759 1760 1872 } 1761 1873 … … 2029 2141 && pbFile[2] == ELFMAG2 2030 2142 && pbFile[3] == ELFMAG3) 2031 /** @todo convertElfToOmf(). */ 2143 { 2144 #ifdef ELF_TO_OMF_CONVERSION 2145 if (writefile(szOrgFile, pvFile, cbFile)) 2146 { 2147 FILE *pDst = openfile(pszFile, true /*fWrite*/); 2148 if (pDst) 2149 { 2150 fRc = convertElfToOmf(pszFile, pbFile, cbFile, pDst); 2151 fRc = fclose(pDst) == 0 && fRc; 2152 } 2153 } 2154 #else 2032 2155 fRc = writefile(szOrgFile, pvFile, cbFile) 2033 2156 && convertelf(pszFile, pbFile, cbFile) 2034 2157 && writefile(pszFile, pvFile, cbFile); 2158 #endif 2159 } 2035 2160 else if ( cbFile > sizeof(IMAGE_FILE_HEADER) 2036 2161 && RT_MAKE_U16(pbFile[0], pbFile[1]) == IMAGE_FILE_MACHINE_AMD64
Note:
See TracChangeset
for help on using the changeset viewer.