Annotation of nono/vm/ram.cpp, revision 1.1.1.5

1.1       root        1: //
                      2: // nono
1.1.1.3   root        3: // Copyright (C) 2020 nono project
                      4: // Licensed under nono-license.txt
1.1       root        5: //
                      6: 
                      7: #include "ram.h"
1.1.1.2   root        8: #include "aout.h"
                      9: #include "elf.h"
                     10: #include "iodevstream.h"
                     11: #include "mainapp.h"
                     12: #include <fcntl.h>
                     13: #include <sys/stat.h>
                     14: #include <sys/mman.h>
                     15: #include <zlib.h>
1.1       root       16: 
                     17: //
                     18: // メインメモリ
                     19: //
1.1.1.4   root       20: 
                     21: std::unique_ptr<RAMDevice> gRAM;
                     22: 
1.1       root       23: // RAM はロングワード単位でホストバイトオーダ配置なので、
                     24: // バイトアクセス、ワードアクセス時は HLB(), HLW() マクロを使用のこと。
1.1.1.2   root       25: std::unique_ptr<uint8[]> ram;
1.1.1.4   root       26: 
                     27: // RAM 容量(バイト単位)であり ram[] の確保したバイト数
1.1       root       28: int ram_size;
                     29: 
                     30: RAMDevice::RAMDevice()
                     31: {
                     32:        logname = "ram";
                     33:        devname = "MainRAM";
                     34:        devaddr = 0;
                     35: 
                     36:        ram_size = 0;
1.1.1.4   root       37: 
                     38:        // アクセスウェイト
                     39:        switch (gMainApp.GetVMType()) {
                     40:         case VMTYPE_LUNA88K:
                     41:                // 取扱説明書p.21 に、CMMU からのアクセスタイムが
                     42:                // リード(4byte)で 200ns、バーストリード(16byte)で 320ns
                     43:                // ライト(4byte)で 160ns、バーストライト(16byte)で 280ns とある。
                     44:                // 25MHz は 40ns/clockで、この数値は CMMU からのアクセス全体の時間
                     45:                // らしいので、ここで加算するウェイトはそれから 2クロック引いたもの。
                     46:                read_wait  = 3;
                     47:                write_wait = 2;
                     48:                break;
                     49:         case VMTYPE_LUNA1:
                     50:                // LUNA-I は1ウェイト。
                     51:                read_wait  = 1;
                     52:                write_wait = 1;
                     53:                break;
                     54: 
                     55:         case VMTYPE_X68030:
                     56:         default:
                     57:                // X68030 ではシステムポートが設定するのでここでは不要。
                     58:                break;
                     59:        }
1.1       root       60: }
                     61: 
                     62: RAMDevice::~RAMDevice()
                     63: {
                     64:        ram_size = 0;
                     65: }
                     66: 
                     67: bool
                     68: RAMDevice::Init()
                     69: {
1.1.1.4   root       70:        int ram_size_MB;
                     71: 
                     72:        const ConfigItem& item = gConfig->Find("ram-size");
                     73:        ram_size_MB = item.AsInt();
1.1.1.3   root       74:        // XXX 上限は適当。
                     75:        // LUNA は空間は 1024MB 分あるが末尾に Null と BusErr 領域が必要なはずで
                     76:        // メモリの上限は 1023MB くらいのはず。
1.1.1.4   root       77:        if (ram_size_MB < 1 || ram_size_MB > 1023) {
1.1.1.3   root       78:                item.Err();
                     79:                return false;
1.1       root       80:        }
1.1.1.3   root       81: 
1.1.1.4   root       82:        ram_size = ram_size_MB * 1024 * 1024;
1.1.1.2   root       83:        ram.reset(new uint8[ram_size]);
1.1       root       84: 
                     85:        return true;
                     86: }
                     87: 
1.1.1.4   root       88: void
                     89: RAMDevice::ResetHard()
                     90: {
                     91:        // X68030 ではリセットで戻るはず。(LUNA は固定なので関係ない)
                     92:        if (gMainApp.GetVMType() == VMTYPE_X68030) {
                     93:                read_wait  = 0;
                     94:                write_wait = 0;
                     95:        }
                     96: }
                     97: 
1.1       root       98: uint64
                     99: RAMDevice::Read8(uint32 addr)
                    100: {
1.1.1.4   root      101:        gMPU->AddCycle(read_wait);
1.1       root      102:        uint32 data;
                    103:        data = ram[HLB(addr)];
                    104:        return data;
                    105: }
                    106: 
                    107: uint64
                    108: RAMDevice::Read16(uint32 addr)
                    109: {
1.1.1.4   root      110:        gMPU->AddCycle(read_wait);
1.1       root      111:        uint32 data;
                    112:        data = *(uint16 *)&ram[HLW(addr)];
                    113:        return data;
                    114: }
                    115: 
                    116: uint64
                    117: RAMDevice::Read32(uint32 addr)
                    118: {
1.1.1.4   root      119:        gMPU->AddCycle(read_wait);
1.1       root      120:        uint32 data;
                    121:        data = *(uint32 *)&ram[addr];
                    122:        return data;
                    123: }
                    124: 
                    125: uint64
                    126: RAMDevice::Write8(uint32 addr, uint32 data)
                    127: {
1.1.1.4   root      128:        gMPU->AddCycle(write_wait);
1.1       root      129:        ram[HLB(addr)] = data;
                    130:        return 0;
                    131: }
                    132: 
                    133: uint64
                    134: RAMDevice::Write16(uint32 addr, uint32 data)
                    135: {
1.1.1.4   root      136:        gMPU->AddCycle(write_wait);
1.1       root      137:        *(uint16 *)&ram[HLW(addr)] = data;
                    138:        return 0;
                    139: }
                    140: 
                    141: uint64
                    142: RAMDevice::Write32(uint32 addr, uint32 data)
                    143: {
1.1.1.4   root      144:        gMPU->AddCycle(write_wait);
1.1       root      145:        *(uint32 *)&ram[addr] = data;
                    146:        return 0;
                    147: }
                    148: 
                    149: uint64
                    150: RAMDevice::Peek8(uint32 addr)
                    151: {
                    152:        return ram[HLB(addr)];
                    153: }
1.1.1.2   root      154: 
1.1.1.4   root      155: // アクセスウェイトを設定 (X68030 でシステムポートから呼ばれる)
                    156: void
                    157: RAMDevice::SetWait(uint32 wait)
                    158: {
                    159:        read_wait  = wait;
                    160:        write_wait = wait;
                    161: }
                    162: 
1.1.1.2   root      163: // filepath で指定されるホストの実行ファイルをゲストにロードする。
                    164: // ファイルのフォーマットは自動で認識する。
                    165: // target_mid は machine id で、実体は a.out の値を流用してはいるが
                    166: // ELF であってもこちらで読み替える。
                    167: // 戻り値はエントリポイントアドレス。エラーなら 0 を返す。
                    168: uint32
                    169: RAMDevice::LoadFile(const char *filepath, uint32 target_mid)
                    170: {
                    171:        uint8 *file;
                    172:        struct stat st;
                    173:        size_t filesize;
                    174:        uint32 entry;
                    175:        int fd;
                    176: 
                    177:        fd = open(filepath, O_RDONLY);
                    178:        if (fd == -1) {
                    179:                warn("LoadFile \"%s\" open failed", filepath);
                    180:                return 0;
                    181:        }
                    182: 
                    183:        if (fstat(fd, &st) == -1) {
                    184:                warn("LoadFile \"%s\" fstat failed", filepath);
                    185:                close(fd);
                    186:                return 0;
                    187:        }
                    188: 
                    189:        if (!S_ISREG(st.st_mode)) {
                    190:                warnx("LoadFile \"%s\" not a regular file", filepath);
                    191:                close(fd);
                    192:                return 0;
                    193:        }
                    194: 
                    195:        // 今の所マジック判定は最初の4バイトで出来るので
                    196:        if (st.st_size < 4) {
                    197:                warnx("LoadFile \"%s\" file too short", filepath);
                    198:                close(fd);
                    199:                return 0;
                    200:        }
                    201:        filesize = st.st_size;
                    202: 
                    203:        file = (uint8 *)mmap(NULL, filesize, PROT_READ, MAP_PRIVATE, fd, 0);
                    204:        if (file == MAP_FAILED) {
                    205:                warn("LoadFile \"%s\" mmap failed", filepath);
                    206:                close(fd);
                    207:                return 0;
                    208:        }
                    209: 
                    210:        // 先頭3バイトの gzip マジックを調べる
                    211:        if (file[0] == 0x1f && file[1] == 0x8b && file[2] == 0x08) {
                    212:                // gzip
                    213:                entry = LoadGzFile(filepath, file, filesize, target_mid);
                    214:        } else {
                    215:                // 通常ファイル
                    216:                entry = LoadFile(filepath, file, filesize, target_mid);
                    217:        }
                    218: 
                    219:        munmap(file, filesize);
                    220:        close(fd);
                    221:        return entry;
                    222: }
                    223: 
                    224: // gzip を展開してゲストにロードする。
                    225: uint32
                    226: RAMDevice::LoadGzFile(const char *filepath,
                    227:        const uint8 *infile, size_t infilesize, uint32 target_mid)
                    228: {
                    229:        z_stream z {};
                    230:        uint32 decompsize;
                    231:        int rv;
                    232: 
                    233:        // gzip なら(?) ファイルの末尾4バイトが (LE で?) 展開後サイズ(?)。
1.1.1.3   root      234:        decompsize = le32toh(*(const uint32 *)&infile[infilesize - 4]);
1.1.1.2   root      235:        std::unique_ptr<uint8[]> dstbuf(new uint8[decompsize]);
                    236: 
                    237:        // gzip 展開
                    238:        // (uncompress() の方が楽そうに見えるが gzip 形式に対応してないらしい)
                    239:        z.zalloc = Z_NULL;
                    240:        z.zfree = Z_NULL;
                    241:        z.opaque = Z_NULL;
                    242:        rv = inflateInit2(&z, 47);
                    243:        if (rv != Z_OK) {
                    244:                warnx("LoadGzFile \"%s\" inflateInit2 failed %d", filepath, rv);
                    245:                return 0;
                    246:        }
                    247: 
1.1.1.3   root      248:        z.next_in = const_cast<Bytef *>(infile);
1.1.1.2   root      249:        z.avail_in = infilesize - 4;
                    250:        z.next_out = dstbuf.get();
                    251:        z.avail_out = decompsize;
                    252:        rv = inflate(&z, Z_NO_FLUSH);
                    253:        if (rv != Z_OK) {
                    254:                warnx("LoadGzFile \"%s\" inflate failed %d", filepath, rv);
                    255:                return 0;
                    256:        }
                    257: 
                    258:        inflateEnd(&z);
                    259: 
                    260:        // 展開できたのでロード
                    261:        return LoadFile(filepath, dstbuf.get(), decompsize, target_mid);
                    262: }
                    263: 
                    264: // file, filesize で示されるバッファを実行ファイルとみなしてゲストにロードする。
                    265: // ファイルのフォーマットは自動で認識する。
                    266: // target_mid は machine id で、実体は a.out の値を流用してはいるが
                    267: // ELF であってもこちらで読み替える。
                    268: // name はここではエラーメッセージとかの表示用でしかない。
                    269: // 戻り値はエントリポイントアドレス。エラーなら 0 を返す。
                    270: uint32
                    271: RAMDevice::LoadFile(const char *name, const uint8 *file, size_t filesize,
                    272:        uint32 target_mid)
                    273: {
                    274:        uint32 entry = 0;
                    275: 
                    276:        // フォーマットだけ判定して分岐
1.1.1.3   root      277:        const Elf32_Ehdr *ehdr = (const Elf32_Ehdr *)file;
                    278:        const aout_header *aout = (const aout_header *)file;
1.1.1.2   root      279:        if (memcmp(ehdr->e_ident, "\177ELF", 4) == 0) {
                    280:                entry = Load_elf32(name, file, filesize, target_mid);
                    281:        } else if ((be32toh(aout->magic) & 0xffff) == AOUT_OMAGIC) {
                    282:                entry = Load_aout(name, file, filesize, target_mid);
                    283:        } else {
                    284:                warnx("LoadFile \"%s\" unknown executable file format", name);
                    285:        }
                    286: 
                    287:        return entry;
                    288: }
                    289: 
                    290: // ホストの a.out をゲストの RAM に読み込む。
                    291: // 戻り値はエントリポイントアドレス。エラーなら 0 を返す。
                    292: uint32
                    293: RAMDevice::Load_aout(const char *name, const uint8 *file, size_t filesize,
                    294:        uint32 target_mid)
                    295: {
                    296:        aout_header aout;
                    297:        int copylen;
                    298: 
                    299:        if (filesize < sizeof(aout)) {
                    300:                warnx("Load_aout \"%s\" file too short", name);
                    301:                return 0;
                    302:        }
                    303: 
                    304:        // ヘッダを読み込む
                    305:        // BigEndian しかターゲットにしてないので最初から全部変換しとく
1.1.1.3   root      306:        aout.magic       = be32toh(((const aout_header *)file)->magic);
                    307:        aout.textsize    = be32toh(((const aout_header *)file)->textsize);
                    308:        aout.datasize    = be32toh(((const aout_header *)file)->datasize);
                    309:        aout.bsssize     = be32toh(((const aout_header *)file)->bsssize);
                    310:        aout.symsize     = be32toh(((const aout_header *)file)->symsize);
                    311:        aout.entry       = be32toh(((const aout_header *)file)->entry);
                    312:        aout.textrelsize = be32toh(((const aout_header *)file)->textrelsize);
                    313:        aout.datarelsize = be32toh(((const aout_header *)file)->datarelsize);
1.1.1.2   root      314: 
                    315:        // マジックをチェック
                    316:        uint32 mid = AOUT_MID(aout.magic);
                    317:        if (mid != target_mid) {
                    318:                warnx("Load_aout \"%s\" machine id mismatch (%03x expected but %03x)",
                    319:                        name, target_mid, mid);
                    320:                return 0;
                    321:        }
                    322: 
                    323:        putmsg(1, "%s textsize    = %08x", __func__, aout.textsize);
                    324:        putmsg(1, "%s datasize    = %08x", __func__, aout.datasize);
                    325:        putmsg(1, "%s bsssize     = %08x", __func__, aout.bsssize);
                    326:        putmsg(1, "%s symsize     = %08x", __func__, aout.symsize);
                    327:        putmsg(1, "%s entry       = %08x", __func__, aout.entry);
                    328:        putmsg(1, "%s textrelsize = %08x", __func__, aout.textrelsize);
                    329:        putmsg(1, "%s datarelsize = %08x", __func__, aout.datarelsize);
                    330: 
                    331:        // とりあえず再配置は無視
                    332:        if (aout.textrelsize != 0 || aout.datarelsize != 0) {
                    333:                warnx("Load_aout \"%s\" relocation not supported", name);
                    334:                return 0;
                    335:        }
                    336: 
                    337:        // OpenBSD の boot は text+data が filesize より大きくて何かおかしいが
                    338:        // OMAGIC の a.out は text+data が連続しているだけなので、とりあえず
                    339:        // 何も考えずにファイルサイズ分ロードしておく。
                    340:        copylen = aout.textsize + aout.datasize;
                    341:        if (copylen >= filesize) {
                    342:                copylen = filesize;
                    343:                warnx("warning: Load_aout \"%s\" coruppted? "
                    344:                      "(text=%u + data=%u, filesize=%d); loading %d bytes",
                    345:                        name, aout.textsize, aout.datasize, (int)filesize, copylen);
                    346:                /* FALLTHROUGH */
                    347:        }
                    348: 
                    349:        // 再配置不要なので、text + data を entry に置いて entry に飛ぶだけ
                    350:        IODeviceStream ds(this, aout.entry);
                    351:        const uint8 *src = file + sizeof(aout);
                    352:        for (int i = 0; i < copylen; i++) {
                    353:                ds.Write8(*src++);
                    354:        }
                    355: 
                    356:        return aout.entry;
                    357: }
                    358: 
                    359: // ELF フォーマットのエンディアンからホストエンディアンに変換
                    360: #define elf16toh(x)    ((ehdr->e_ident[EI_DATA] == ELFDATA2MSB) ? \
                    361:        be16toh(x) : le16toh(x))
                    362: #define elf32toh(x) ((ehdr->e_ident[EI_DATA] == ELFDATA2MSB) ? \
                    363:        be32toh(x) : le32toh(x))
                    364: 
1.1.1.5 ! root      365: // XXX このへん、そのうちきれいにする
        !           366: #define GetElfStr1(array, v)   GetElfStr(array, countof(array), v)
        !           367: static const char *
        !           368: GetElfStr(const std::pair<uint, const char *> *map, uint mapcount, uint v)
        !           369: {
        !           370:        for (int i = 0; i < mapcount; i++) {
        !           371:                if (map[i].first == v) {
        !           372:                        return map[i].second;
        !           373:                }
        !           374:        }
        !           375:        return "?";
        !           376: }
        !           377: 
        !           378: static std::pair<uint, const char *> class_str[] = {
        !           379:        { ELFCLASSNONE, "NONE" },
        !           380:        { ELFCLASS32,   "32bit" },
        !           381:        { ELFCLASS64,   "64bit" },
        !           382: };
        !           383: #define GetElfClassStr(x)      GetElfStr1(class_str, (x))
        !           384: 
        !           385: static std::pair<uint, const char *> data_str[] = {
        !           386:        { ELFDATANONE,  "NONE" },
        !           387:        { ELFDATA2LSB,  "LE" },
        !           388:        { ELFDATA2MSB,  "BE" },
        !           389: };
        !           390: #define GetElfDataStr(x)       GetElfStr1(data_str, (x))
        !           391: 
        !           392: static std::pair<uint, const char *> etype_str[] = {
        !           393:        { ET_NONE,      "ET_NONE" },
        !           394:        { ET_REL,       "ET_REL" },
        !           395:        { ET_EXEC,      "ET_EXEC" },
        !           396:        { ET_DYN,       "ET_DYN" },
        !           397:        { ET_CORE,      "ET_CORE" },
        !           398: };
        !           399: #define GetElfETypeStr(x)      GetElfStr1(etype_str, (x))
        !           400: 
        !           401: static std::pair<uint, const char *> machine_str[] = {
        !           402:        // 多いので関係分のみ
        !           403:        { EM_NONE,      "NONE" },
        !           404:        { EM_68K,       "Motorola 68000" },
        !           405:        { EM_88K,       "Motorola 88000" },
        !           406: };
        !           407: #define GetElfMachineStr(x)    GetElfStr1(machine_str, (x))
        !           408: 
        !           409: static std::pair<uint, const char *> ptype_str[] = {
        !           410:        { PT_NULL,              "PT_NULL" },
        !           411:        { PT_LOAD,              "PT_LOAD" },
        !           412:        { PT_DYNAMIC,   "PT_DYNAMIC" },
        !           413:        { PT_INTERP,    "PT_INTERP" },
        !           414:        { PT_NOTE,              "PT_NOTE" },
        !           415:        { PT_SHLIB,             "PT_SHLIB" },
        !           416:        { PT_PHDR,              "PT_PHDR" },
        !           417:        { PT_GNU_RELRO, "PT_GNU_RELRO" },       // GNU specific
        !           418:        { PT_OPENBSD_RANDOMIZE, "PT_OPENBSD_RANDOMIZE" },
        !           419:        { PT_OPENBSD_WXNEEDED,  "PT_OPENBSD_WXNEEDED" },
        !           420:        { PT_OPENBSD_BOOTDATA,  "PT_OPENBSD_BOOTDATA" },
        !           421: };
        !           422: #define GetElfPTypeStr(x)      GetElfStr1(ptype_str, (x))
        !           423: 
1.1.1.2   root      424: // ホストの a.out をゲストの RAM に読み込む。
                    425: // target_aout_mid は a.out での machine id (機種情報) で、こっちで ELF の
                    426: // machine type に読み替える。
                    427: // 戻り値はエントリポイントアドレス。エラーなら 0 を返す。
                    428: uint32
                    429: RAMDevice::Load_elf32(const char *name, const uint8 *file, size_t filesize,
                    430:        uint32 target_aout_mid)
                    431: {
                    432:        uint16 target_elf_mid;
                    433: 
                    434:        // a.out machine id から ELF machine type への読み替え
                    435:        switch (target_aout_mid) {
                    436:         case AOUT_MID_M68K:
                    437:                target_elf_mid = EM_68K;
                    438:                break;
                    439:         case AOUT_MID_M88K:
                    440:                target_elf_mid = EM_88K;
                    441:                break;
                    442:         default:
                    443:                warnx("Load_elf32 unknown target_aout_mid $%x", target_aout_mid);
                    444:                return 0;
                    445:        }
                    446: 
                    447:        // ヘッダをチェック
                    448:        const Elf32_Ehdr *ehdr = (const Elf32_Ehdr *)file;
                    449:        if (filesize < sizeof(*ehdr)) {
                    450:                warnx("Load_elf32 \"%s\" file too short", name);
                    451:                return 0;
                    452:        }
                    453:        uint16 e_type    = elf16toh(ehdr->e_type);
                    454:        uint16 e_machine = elf16toh(ehdr->e_machine);
                    455:        uint32 e_entry   = elf32toh(ehdr->e_entry);
1.1.1.5 ! root      456:        if (loglevel >= 1) {
        !           457:                uint n;
        !           458:                n = ehdr->e_ident[EI_CLASS];
        !           459:                putlog("EI_CLASS    = $%02x (%s)", n, GetElfClassStr(n));
        !           460:                n = ehdr->e_ident[EI_DATA];
        !           461:                putlog("EI_DATA     = $%02x (%s)", n, GetElfDataStr(n));
        !           462: 
        !           463:                putlog("e_type      = $%02x (%s)", e_type, GetElfETypeStr(e_type));
        !           464:                putlog("e_machine   = $%02x (%s)", e_machine,
        !           465:                        GetElfMachineStr(e_machine));
        !           466:                putlog("e_entry     = $%08x", e_entry);
        !           467:        }
1.1.1.2   root      468: 
                    469:        if (ehdr->e_ident[EI_CLASS] != ELFCLASS32) {
                    470:                warnx("Load_elf32 \"%s\" not ELF32 format", name);
                    471:                return 0;
                    472:        }
                    473:        if (e_type != ET_EXEC) {
                    474:                warnx("Load_elf32 \"%s\" not executable file", name);
                    475:                return 0;
                    476:        }
                    477:        if (e_machine != target_elf_mid) {
                    478:                warnx("Load_elf32 \"%s\" machine type mismatch "
                    479:                        "($%02x expected but $%02x)",
                    480:                        name, target_elf_mid, e_machine);
                    481:                return 0;
                    482:        }
                    483: 
                    484:        // プログラムヘッダに読み込むべき領域が示されている
                    485:        // phoff がプログラムヘッダのファイル先頭からのオフセット
                    486:        // phentsize がプログラムヘッダ1つの大きさ
                    487:        // phnum がプログラムヘッダの個数
                    488:        uint32 e_phoff     = elf32toh(ehdr->e_phoff);
                    489:        uint16 e_phentsize = elf16toh(ehdr->e_phentsize);
                    490:        uint16 e_phnum     = elf16toh(ehdr->e_phnum);
1.1.1.5 ! root      491:        if (loglevel >= 1) {
        !           492:                putlog("e_phoff     = $%08x", e_phoff);
        !           493:                putlog("e_phentsize = $%04x", e_phentsize);
        !           494:                putlog("e_phnum     = %d",    e_phnum);
        !           495:        }
1.1.1.2   root      496:        if (e_phentsize != sizeof(Elf32_Phdr)) {
                    497:                warnx("Load_elf32 \"%s\" unknown program header size 0x%x",
                    498:                        name, e_phentsize);
                    499:                return 0;
                    500:        }
                    501: 
                    502:        IODeviceStream ds(this);
                    503: 
                    504:        for (int j = 0; j < e_phnum; j++) {
                    505:                const Elf32_Phdr *phdr = &((const Elf32_Phdr*)(file + e_phoff))[j];
                    506:                // p_type が PT_LOAD なところをロードする。
                    507:                // その際 p_memsz > p_filesz なら差が BSS 領域。
                    508:                uint32 p_type   = elf32toh(phdr->p_type);       // タイプ
                    509:                uint32 p_offset = elf32toh(phdr->p_offset);     // ファイル上のオフセット
                    510:                uint32 p_vaddr  = elf32toh(phdr->p_vaddr);      // 仮想アドレス
                    511:                uint32 p_filesz = elf32toh(phdr->p_filesz);     // 読み込み元ファイルサイズ
                    512:                uint32 p_memsz  = elf32toh(phdr->p_memsz);      // 書き込み先サイズ
1.1.1.5 ! root      513:                if (loglevel >= 1) {
        !           514:                        putlog("[%d] p_type   = $%08x (%s)", j,
        !           515:                                p_type, GetElfPTypeStr(p_type));
        !           516:                        putlog("    p_offset = $%08x", p_offset);
        !           517:                        putlog("    p_vaddr  = $%08x", p_vaddr);
        !           518:                        putlog("    p_filesz = $%08x", p_filesz);
        !           519:                        putlog("    p_memsz  = $%08x", p_memsz);
        !           520:                }
1.1.1.2   root      521: 
                    522:                if (p_type == PT_LOAD) {
                    523:                        ds.SetAddr(p_vaddr);
                    524:                        const uint8 *src = file + p_offset;
                    525:                        int i = 0;
                    526:                        for (; i < p_filesz; i++) {
                    527:                                ds.Write8(*src++);
                    528:                        }
                    529:                        for (; i < p_memsz; i++) {
                    530:                                ds.Write8(0);
                    531:                        }
1.1.1.5 ! root      532:                } else if (p_type == PT_NOTE) {
        !           533:                        // ベンダー文字列みたいなのらしいので無視してよい
        !           534:                        continue;
        !           535:                } else if (p_type == PT_OPENBSD_RANDOMIZE) {
1.1.1.3   root      536:                        // XXX どうする?
                    537:                        continue;
                    538: 
1.1.1.2   root      539:                } else {
1.1.1.5 ! root      540:                        warnx("Load_elf32 \"%s\" p_type 0x%x(%s) not supported",
        !           541:                                name, p_type, GetElfPTypeStr(p_type));
1.1.1.2   root      542:                        return 0;
                    543:                }
                    544:        }
                    545: 
                    546:        return e_entry;
                    547: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.