VirtualBox

Changeset 60044 in vbox


Ignore:
Timestamp:
Mar 15, 2016 3:31:38 PM (9 years ago)
Author:
vboxsync
Message:

bs3kit: a bit more of the ELF -> OMF converter.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/ValidationKit/bootsectors/bs3kit/VBoxBs3ObjConverter.cpp

    r60019 r60044  
    826826} ELFDETAILS;
    827827typedef ELFDETAILS *PELFDETAILS;
     828typedef ELFDETAILS const *PCELFDETAILS;
    828829
    829830
     
    911912            return error(pszFile, "Section #%u '%s' alignment value is not a power of two: %#" ELF_FMT_X64 "\n",
    912913                         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);
    913916
    914917        if (paShdrs[i].sh_type == SHT_RELA)
     
    919922            uint32_t const cRelocs = paShdrs[i].sh_size / sizeof(Elf64_Rela);
    920923            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);
    923926            if (   paShdrs[i].sh_offset > cbFile
    924927                || paShdrs[i].sh_size  >= cbFile
     
    926929                return error(pszFile, "The content of section #%u '%s' is outside the file (%#" ELF_FMT_X64 " LB %#" ELF_FMT_X64 ", cbFile=%#lx)\n",
    927930                             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);
    928934
    929935            Elf64_Rela const  *paRelocs = (Elf64_Rela *)&pbFile[paShdrs[i].sh_offset];
     
    977983#ifdef ELF_TO_OMF_CONVERSION
    978984
     985
     986static 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
     1189static 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
    9791360static bool convertElfToOmf(const char *pszFile, uint8_t const *pbFile, size_t cbFile, FILE *pDst)
    9801361{
     
    10031384        const char       *pszStrTab = (const char *)&pbFile[paShdrs[pEhdr->e_shstrndx].sh_offset];
    10041385
    1005         if (   convertElfSectionsToSegDefsAndGrpDefs(pThis, paShdrs, pHdr->NumberOfSections)
    1006             //&& convertElfSymbolsToPubDefsAndExtDefs(pThis, paSymTab, pHdr->NumberOfSymbols, pchStrTab, paShdrs)
     1386        if (   convertElfSectionsToSegDefsAndGrpDefs(pThis, &ElfStuff)
     1387            && convertElfSymbolsToPubDefsAndExtDefs(pThis, &ElfStuff)
    10071388            && omfWriter_LinkPassSeparator(pThis)
    10081389            //&& convertElfSectionsToLeDataAndFixupps(pThis, pbFile, cbFile, paShdrs, pHdr->NumberOfSections,
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette