Changeset 60044 in vbox
- Timestamp:
- Mar 15, 2016 3:31:38 PM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/ValidationKit/bootsectors/bs3kit/VBoxBs3ObjConverter.cpp
r60019 r60044 826 826 } ELFDETAILS; 827 827 typedef ELFDETAILS *PELFDETAILS; 828 typedef ELFDETAILS const *PCELFDETAILS; 828 829 829 830 … … 911 912 return error(pszFile, "Section #%u '%s' alignment value is not a power of two: %#" ELF_FMT_X64 "\n", 912 913 i, pszShNm, paShdrs[i].sh_addralign); 914 if (paShdrs[i].sh_addr != 0) 915 return error(pszFile, "Section #%u '%s' has non-zero address: %#" ELF_FMT_X64 "\n", i, pszShNm, paShdrs[i].sh_addr); 913 916 914 917 if (paShdrs[i].sh_type == SHT_RELA) … … 919 922 uint32_t const cRelocs = paShdrs[i].sh_size / sizeof(Elf64_Rela); 920 923 if (cRelocs * sizeof(Elf64_Rela) != paShdrs[i].sh_size) 921 return error(pszFile, "Uneven relocation entry count in #%u (%s): sh_size=%#" ELF_FMT_X64 "\n", (unsigned)sizeof(Elf64_Rela),922 paShdrs[i].sh_entsize,i, pszShNm, paShdrs[i].sh_size);924 return error(pszFile, "Uneven relocation entry count in #%u (%s): sh_size=%#" ELF_FMT_X64 "\n", 925 i, pszShNm, paShdrs[i].sh_size); 923 926 if ( paShdrs[i].sh_offset > cbFile 924 927 || paShdrs[i].sh_size >= cbFile … … 926 929 return error(pszFile, "The content of section #%u '%s' is outside the file (%#" ELF_FMT_X64 " LB %#" ELF_FMT_X64 ", cbFile=%#lx)\n", 927 930 i, pszShNm, paShdrs[i].sh_offset, paShdrs[i].sh_size, (unsigned long)cbFile); 931 if (paShdrs[i].sh_link != i - 1) 932 return error(pszFile, "Expected relocation section #%u (%s) to link to previous section: sh_link=%#u\n", 933 i, pszShNm, (unsigned)paShdrs[i].sh_link); 928 934 929 935 Elf64_Rela const *paRelocs = (Elf64_Rela *)&pbFile[paShdrs[i].sh_offset]; … … 977 983 #ifdef ELF_TO_OMF_CONVERSION 978 984 985 986 static bool convertElfSectionsToSegDefsAndGrpDefs(POMFWRITER pThis, PCELFDETAILS pElfStuff) 987 { 988 /* 989 * Do the list of names pass. 990 */ 991 uint16_t idxGrpFlat, idxGrpData; 992 uint16_t idxClassCode, idxClassData, idxClassDwarf; 993 if ( !omfWriter_LNamesBegin(pThis) 994 || !omfWriter_LNamesAddN(pThis, RT_STR_TUPLE("FLAT"), &idxGrpFlat) 995 || !omfWriter_LNamesAddN(pThis, RT_STR_TUPLE("BS3DATA64_GROUP"), &idxGrpData) 996 || !omfWriter_LNamesAddN(pThis, RT_STR_TUPLE("BS3CODE64"), &idxClassCode) 997 || !omfWriter_LNamesAddN(pThis, RT_STR_TUPLE("FAR_DATA"), &idxClassData) 998 || !omfWriter_LNamesAddN(pThis, RT_STR_TUPLE("DWARF"), &idxClassDwarf) 999 ) 1000 return false; 1001 1002 bool fHaveData = false; 1003 Elf64_Shdr const *pShdr = &pElfStuff->paShdrs[1]; 1004 Elf64_Half const cSections = pElfStuff->pEhdr->e_shnum; 1005 for (Elf64_Half i = 1; i < cSections; i++, pShdr++) 1006 { 1007 const char *pszName = &pElfStuff->pchShStrTab[pShdr->sh_name]; 1008 if (*pszName == '\0') 1009 return error(pThis->pszSrc, "Section #%u has an empty name!\n", i); 1010 1011 switch (pShdr->sh_type) 1012 { 1013 case SHT_PROGBITS: 1014 case SHT_NOBITS: 1015 /* We drop a few sections we don't want:. */ 1016 if ( strcmp(pszName, ".comment") != 0 /* compiler info */ 1017 && strcmp(pszName, ".note.GNU-stack") != 0 /* some empty section for hinting the linker/whatever */ 1018 && strcmp(pszName, ".eh_frame") != 0 /* unwind / exception info */ 1019 ) 1020 { 1021 pThis->paSegments[i].iSegDef = UINT16_MAX; 1022 pThis->paSegments[i].iGrpDef = UINT16_MAX; 1023 1024 /* Translate the name and determine group and class. 1025 Note! We currently strip sub-sections. */ 1026 if ( strcmp(pszName, ".text") == 0 1027 || strncmp(pszName, RT_STR_TUPLE(".text.")) == 0) 1028 { 1029 pszName = "BS3TEXT64"; 1030 pThis->paSegments[i].iGrpNm = idxGrpFlat; 1031 pThis->paSegments[i].iClassNm = idxClassCode; 1032 } 1033 else if ( strcmp(pszName, ".data") == 0 1034 || strncmp(pszName, RT_STR_TUPLE(".data.")) == 0) 1035 { 1036 pszName = "BS3DATA64"; 1037 pThis->paSegments[i].iGrpNm = idxGrpData; 1038 pThis->paSegments[i].iClassNm = idxClassData; 1039 } 1040 else if (strcmp(pszName, ".bss") == 0) 1041 { 1042 pszName = "BS3BSS64"; 1043 pThis->paSegments[i].iGrpNm = idxGrpData; 1044 pThis->paSegments[i].iClassNm = idxClassData; 1045 } 1046 else if ( strcmp(pszName, ".rodata") == 0 1047 || strncmp(pszName, RT_STR_TUPLE(".rodata.")) == 0) 1048 { 1049 pszName = "BS3DATA64CONST"; 1050 pThis->paSegments[i].iGrpNm = idxGrpData; 1051 pThis->paSegments[i].iClassNm = idxClassData; 1052 } 1053 else if (strncmp(pszName, RT_STR_TUPLE(".debug_")) == 0) 1054 { 1055 pThis->paSegments[i].iGrpNm = UINT16_MAX; 1056 pThis->paSegments[i].iClassNm = idxClassDwarf; 1057 } 1058 else 1059 { 1060 pThis->paSegments[i].iGrpNm = idxGrpData; 1061 pThis->paSegments[i].iClassNm = idxClassData; 1062 error(pThis->pszSrc, "Unknown data (?) segment: '%s'\n", pszName); 1063 } 1064 1065 /* Save the name. */ 1066 pThis->paSegments[i].pszName = strdup(pszName); 1067 if (!pThis->paSegments[i].pszName) 1068 return error(pThis->pszSrc, "Out of memory!\n"); 1069 1070 /* Add the section name. */ 1071 if (!omfWriter_LNamesAdd(pThis, pThis->paSegments[i].pszName, &pThis->paSegments[i].iSegNm)) 1072 return false; 1073 1074 fHaveData |= pThis->paSegments[i].iGrpDef == idxGrpData; 1075 break; 1076 } 1077 /* fall thru */ 1078 1079 default: 1080 pThis->paSegments[i].iSegDef = UINT16_MAX; 1081 pThis->paSegments[i].iGrpDef = UINT16_MAX; 1082 pThis->paSegments[i].iSegNm = UINT16_MAX; 1083 pThis->paSegments[i].iGrpNm = UINT16_MAX; 1084 pThis->paSegments[i].iClassNm = UINT16_MAX; 1085 pThis->paSegments[i].pszName = NULL; 1086 break; 1087 } 1088 } 1089 1090 if (!omfWriter_LNamesEnd(pThis)) 1091 return false; 1092 1093 /* 1094 * Emit segment definitions. 1095 */ 1096 uint16_t iSegDef = 1; /* Start counting at 1. */ 1097 pShdr = &pElfStuff->paShdrs[1]; 1098 for (Elf64_Half i = 1; i < cSections; i++, pShdr++) 1099 { 1100 if (pThis->paSegments[i].iSegDef == UINT16_MAX) 1101 continue; 1102 1103 uint8_t bSegAttr = 0; 1104 1105 /* The A field. */ 1106 switch (pShdr->sh_addralign) 1107 { 1108 case 0: 1109 case 1: 1110 bSegAttr |= 1 << 5; 1111 break; 1112 case 2: 1113 bSegAttr |= 2 << 5; 1114 break; 1115 case 4: 1116 bSegAttr |= 5 << 5; 1117 break; 1118 case 8: 1119 case 16: 1120 bSegAttr |= 3 << 5; 1121 break; 1122 case 32: 1123 case 64: 1124 case 128: 1125 case 256: 1126 bSegAttr |= 4 << 5; 1127 break; 1128 default: 1129 bSegAttr |= 6 << 5; /* page aligned, pharlabs extension. */ 1130 break; 1131 } 1132 1133 /* The C field. */ 1134 bSegAttr |= 2 << 2; /* public */ 1135 1136 /* The B field. We don't have 4GB segments, so leave it as zero. */ 1137 1138 /* The D field shall be set as we're doing USE32. */ 1139 bSegAttr |= 1; 1140 1141 1142 /* Done. */ 1143 if (!omfWriter_SegDef(pThis, bSegAttr, (uint32_t)pShdr->sh_size, 1144 pThis->paSegments[i].iSegNm, 1145 pThis->paSegments[i].iClassNm)) 1146 return false; 1147 pThis->paSegments[i].iSegDef = iSegDef++; 1148 } 1149 1150 /* 1151 * Flat group definition (#1) - special, no members. 1152 */ 1153 uint16_t iGrpDef = 1; 1154 if ( !omfWriter_GrpDefBegin(pThis, idxGrpFlat) 1155 || !omfWriter_GrpDefEnd(pThis)) 1156 return false; 1157 for (uint16_t i = 0; i < cSections; i++) 1158 if (pThis->paSegments[i].iGrpNm == idxGrpFlat) 1159 pThis->paSegments[i].iGrpDef = iGrpDef; 1160 pThis->idxGrpFlat = iGrpDef++; 1161 1162 /* 1163 * Data group definition (#2). 1164 */ 1165 /** @todo do we need to consider missing segments and ordering? */ 1166 uint16_t cGrpNms = 0; 1167 uint16_t aiGrpNms[2]; 1168 if (fHaveData) 1169 aiGrpNms[cGrpNms++] = idxGrpData; 1170 for (uint32_t iGrpNm = 0; iGrpNm < cGrpNms; iGrpNm++) 1171 { 1172 if (!omfWriter_GrpDefBegin(pThis, aiGrpNms[iGrpNm])) 1173 return false; 1174 for (uint16_t i = 0; i < cSections; i++) 1175 if (pThis->paSegments[i].iGrpNm == aiGrpNms[iGrpNm]) 1176 { 1177 pThis->paSegments[i].iGrpDef = iGrpDef; 1178 if (!omfWriter_GrpDefAddSegDef(pThis, pThis->paSegments[i].iSegDef)) 1179 return false; 1180 } 1181 if (!omfWriter_GrpDefEnd(pThis)) 1182 return false; 1183 iGrpDef++; 1184 } 1185 1186 return true; 1187 } 1188 1189 static bool convertElfSymbolsToPubDefsAndExtDefs(POMFWRITER pThis, PCELFDETAILS pElfStuff) 1190 { 1191 if (!pElfStuff->cSymbols) 1192 return true; 1193 1194 /* 1195 * Process the symbols the first. 1196 */ 1197 uint32_t cAbsSyms = 0; 1198 uint32_t cExtSyms = 0; 1199 uint32_t cPubSyms = 0; 1200 for (uint32_t iSeg = 0; iSeg < pThis->cSegments; iSeg++) 1201 pThis->paSegments[iSeg].cPubDefs = 0; 1202 1203 uint32_t const cSections = pElfStuff->pEhdr->e_shnum; 1204 uint32_t const cSymbols = pElfStuff->cSymbols; 1205 Elf64_Sym const * const paSymbols = pElfStuff->paSymbols; 1206 for (uint32_t iSym = 0; iSym < cSymbols; iSym++) 1207 { 1208 const uint8_t bBind = ELF64_ST_BIND(paSymbols[iSym].st_info); 1209 const uint8_t bType = ELF64_ST_TYPE(paSymbols[iSym].st_info); 1210 const char *pszSymName = &pElfStuff->pchStrTab[paSymbols[iSym].st_name]; 1211 if ( *pszSymName == '\0' 1212 && bType == STT_SECTION 1213 && paSymbols[iSym].st_shndx < cSections) 1214 pszSymName = &pElfStuff->pchShStrTab[pElfStuff->paShdrs[paSymbols[iSym].st_shndx].sh_name]; 1215 1216 pThis->paSymbols[iSym].enmType = OMFSYMTYPE_IGNORED; 1217 pThis->paSymbols[iSym].idx = UINT16_MAX; 1218 pThis->paSymbols[iSym].idxSegDef = UINT16_MAX; 1219 pThis->paSymbols[iSym].idxGrpDef = UINT16_MAX; 1220 1221 uint32_t const idxSection = paSymbols[iSym].st_shndx; 1222 if (idxSection == SHN_UNDEF) 1223 { 1224 if (bBind == STB_GLOBAL) 1225 { 1226 pThis->paSymbols[iSym].enmType = OMFSYMTYPE_EXTDEF; 1227 cExtSyms++; 1228 if (*pszSymName == '\0') 1229 return error(pThis->pszSrc, "External symbol #%u (%s) has an empty name.\n", iSym, pszSymName); 1230 } 1231 else 1232 return error(pThis->pszSrc, "Unsupported or invalid bind type %#x for undefined symbol #%u (%s)\n", 1233 bBind, iSym, pszSymName); 1234 } 1235 else if (idxSection < cSections) 1236 { 1237 pThis->paSymbols[iSym].idxSegDef = pThis->paSegments[idxSection - 1].iSegDef; 1238 pThis->paSymbols[iSym].idxGrpDef = pThis->paSegments[idxSection - 1].iGrpDef; 1239 if (bBind == STB_GLOBAL) 1240 { 1241 pThis->paSymbols[iSym].enmType = OMFSYMTYPE_PUBDEF; 1242 pThis->paSegments[idxSection].cPubDefs++; 1243 cPubSyms++; 1244 if (bType == STT_SECTION) 1245 return error(pThis->pszSrc, "Don't know how to export STT_SECTION symbol #%u (%s)\n", iSym, pszSymName); 1246 if (*pszSymName == '\0') 1247 return error(pThis->pszSrc, "Public symbol #%u (%s) has an empty name.\n", iSym, pszSymName); 1248 } 1249 else if (bType == STT_SECTION) 1250 pThis->paSymbols[iSym].enmType = OMFSYMTYPE_SEGDEF; 1251 else 1252 pThis->paSymbols[iSym].enmType = OMFSYMTYPE_INTERNAL; 1253 } 1254 else if (idxSection == SHN_ABS) 1255 { 1256 if (bType != STT_FILE) 1257 { 1258 if (bBind == STB_GLOBAL) 1259 { 1260 pThis->paSymbols[iSym].enmType = OMFSYMTYPE_PUBDEF; 1261 pThis->paSymbols[iSym].idxSegDef = 0; 1262 pThis->paSymbols[iSym].idxGrpDef = 0; 1263 cAbsSyms++; 1264 if (*pszSymName == '\0') 1265 return error(pThis->pszSrc, "Public absolute symbol #%u (%s) has an empty name.\n", iSym, pszSymName); 1266 } 1267 else 1268 return error(pThis->pszSrc, "Unsupported or invalid bind type %#x for absolute symbol #%u (%s)\n", 1269 bBind, iSym, pszSymName); 1270 } 1271 } 1272 else 1273 return error(pThis->pszSrc, "Unsupported or invalid section number %#x for symbol #%u (%s)\n", 1274 idxSection, iSym, pszSymName); 1275 } 1276 1277 /* 1278 * Emit the PUBDEFs the first time around (see order of records in TIS spec). 1279 */ 1280 uint16_t idxPubDef = 1; 1281 if (cPubSyms) 1282 { 1283 for (uint32_t iSeg = 0; iSeg < pThis->cSegments; iSeg++) 1284 if (pThis->paSegments[iSeg].cPubDefs > 0) 1285 { 1286 uint16_t const idxSegDef = pThis->paSegments[iSeg].iSegDef; 1287 if (!omfWriter_PubDefBegin(pThis, pThis->paSegments[iSeg].iGrpDef, idxSegDef)) 1288 return false; 1289 for (uint16_t iSym = 0; iSym < cSymbols; iSym++) 1290 if ( pThis->paSymbols[iSym].idxSegDef == idxSegDef 1291 && pThis->paSymbols[iSym].enmType == OMFSYMTYPE_PUBDEF) 1292 { 1293 const char *pszName = &pElfStuff->pchStrTab[paSymbols[iSym].st_name]; 1294 if (!omfWriter_PubDefAdd(pThis, paSymbols[iSym].st_value, pszName)) 1295 return false; 1296 1297 /* If the symbol doesn't start with an underscore and is a _c64 or _lm64 symbol, 1298 add an underscore prefixed alias to ease access from 16-bit and 32-bit code. */ 1299 size_t cchName = strlen(pszName); 1300 if ( *pszName != '_' 1301 && ( (cchName > 4 && strcmp(&pszName[cchName - 4], "_c64") == 0) 1302 || (cchName > 5 && strcmp(&pszName[cchName - 5], "_lm64") == 0) ) ) 1303 { 1304 char szCdeclName[512]; 1305 if (cchName > sizeof(szCdeclName) - 2) 1306 cchName = sizeof(szCdeclName) - 2; 1307 szCdeclName[0] = '_'; 1308 memcpy(&szCdeclName[1], pszName, cchName); 1309 szCdeclName[cchName + 1] = '\0'; 1310 if (!omfWriter_PubDefAdd(pThis, paSymbols[iSym].st_value, szCdeclName)) 1311 return false; 1312 } 1313 1314 pThis->paSymbols[iSym].idx = idxPubDef++; 1315 } 1316 if (!omfWriter_PubDefEnd(pThis)) 1317 return false; 1318 } 1319 } 1320 1321 if (cAbsSyms > 0) 1322 { 1323 if (!omfWriter_PubDefBegin(pThis, 0, 0)) 1324 return false; 1325 for (uint16_t iSym = 0; iSym < cSymbols; iSym++) 1326 if ( pThis->paSymbols[iSym].idxSegDef == 0 1327 && pThis->paSymbols[iSym].enmType == OMFSYMTYPE_PUBDEF) 1328 { 1329 const char *pszName = &pElfStuff->pchStrTab[paSymbols[iSym].st_name]; 1330 if (!omfWriter_PubDefAdd(pThis, paSymbols[iSym].st_value, pszName)) 1331 return false; 1332 pThis->paSymbols[iSym].idx = idxPubDef++; 1333 } 1334 if (!omfWriter_PubDefEnd(pThis)) 1335 return false; 1336 } 1337 1338 /* 1339 * Go over the symbol table and emit external definition records. 1340 */ 1341 if (!omfWriter_ExtDefBegin(pThis)) 1342 return false; 1343 uint16_t idxExtDef = 1; 1344 for (uint16_t iSym = 0; iSym < cSymbols; iSym++) 1345 if (pThis->paSymbols[iSym].enmType == OMFSYMTYPE_EXTDEF) 1346 { 1347 const char *pszName = &pElfStuff->pchStrTab[paSymbols[iSym].st_name]; 1348 if (!omfWriter_ExtDefAdd(pThis, pszName)) 1349 return false; 1350 pThis->paSymbols[iSym].idx = idxExtDef++; 1351 } 1352 1353 if (!omfWriter_ExtDefEnd(pThis)) 1354 return false; 1355 1356 return true; 1357 } 1358 1359 979 1360 static bool convertElfToOmf(const char *pszFile, uint8_t const *pbFile, size_t cbFile, FILE *pDst) 980 1361 { … … 1003 1384 const char *pszStrTab = (const char *)&pbFile[paShdrs[pEhdr->e_shstrndx].sh_offset]; 1004 1385 1005 if ( convertElfSectionsToSegDefsAndGrpDefs(pThis, paShdrs, pHdr->NumberOfSections)1006 //&& convertElfSymbolsToPubDefsAndExtDefs(pThis, paSymTab, pHdr->NumberOfSymbols, pchStrTab, paShdrs)1386 if ( convertElfSectionsToSegDefsAndGrpDefs(pThis, &ElfStuff) 1387 && convertElfSymbolsToPubDefsAndExtDefs(pThis, &ElfStuff) 1007 1388 && omfWriter_LinkPassSeparator(pThis) 1008 1389 //&& convertElfSectionsToLeDataAndFixupps(pThis, pbFile, cbFile, paShdrs, pHdr->NumberOfSections,
Note:
See TracChangeset
for help on using the changeset viewer.