📄 objcvt.c
字号:
/* * Copyright (C) 1996-1998 by the Board of Trustees * of Leland Stanford Junior University. * * This file is part of the SimOS distribution. * See LICENSE file for terms of the license. * */#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <a.out.h>#include <malloc.h>#include <string.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <sys/file.h>#include <elf.h>#include <libelf.h>/* #define DEBUG */#define ELFLIB_BUG 1/* *---------------------------------------------------------------------- * * objcvt main program -- * * Convert an Irix object file to run under Sinos * * Usage: objcvt objectFile [objectFile ..,] * * Results: * exit status is the count of errors encounterd. * * Side effects: * Files are updated in place. * *---------------------------------------------------------------------- */intmain(argc,argv) int argc; char **argv;{ int argNum, errors, changed = 0; if (argc < 2) { fprintf(stderr,"Usage: %s objectFile [objectFile ...]\n", argv[0]); exit(1); } if (elf_version(EV_CURRENT) == EV_NONE) { fprintf(stderr, "%s: Linked with wrong ELF library\n", argv[0]); exit(2); } errors = 0; for (argNum = 1; argNum < argc; argNum++) { int fd, cmd; Elf *elf, *arf; Elf32_Ehdr *ehdr; Elf32_Shdr *shdr; Elf_Scn *scn; Elf_Data *data; register int i, numWordsToCheck; register unsigned int *textSeg; fd = open(argv[argNum],O_RDWR); if (fd < 0) { perror(argv[argNum]); errors++; continue; } arf = elf_begin(fd, ELF_C_RDWR, (Elf *)0); if((arf == (Elf *) NULL) || ((elf_kind(arf) != ELF_K_ELF) && (elf_kind(arf) != ELF_K_AR))) { fprintf(stderr, "%s: \"%s\" is not an ELF object\n", argv[0], argv[argNum]); errors++; (void) close(fd); continue; } cmd = ELF_C_RDWR; while ((elf = elf_begin(fd, cmd, arf)) != 0) { if ((ehdr = elf32_getehdr(elf)) == 0) { fprintf(stderr, "%s: \"%s\" does not have a header.\n", argv[0], argv[argNum]); errors++; continue; } scn = 0; while ((scn = elf_nextscn(elf, scn)) != 0) { char *name; name = NULL; if ((shdr = elf32_getshdr(scn)) != NULL) name = elf_strptr(elf, ehdr->e_shstrndx, (size_t)shdr->sh_name); if ((name != NULL) & (strcmp(name, ELF_TEXT) == 0)) { break; } } if (scn == NULL) { err: fprintf(stderr,"%s: \"%s\" does not have a text section.\n", argv[0], argv[argNum]); errors++; (void) close(fd); } data = NULL; if ((data = elf_getdata(scn, data)) == 0 || data->d_size == 0) { goto err; } textSeg = (unsigned int *) data->d_buf; /* * Look for IRIX system call routines. Currently the system * calls * lookup something like: * li v0, NNN * syscall * bne a3,zero,XXX * nop * */ /* * Start looking for the syscall instruction. We can ignore * the last * couple of words since its not a system * call routine. */ changed = 0; numWordsToCheck = data->d_size/sizeof(textSeg[0]) - 2; for(i = 0; i < numWordsToCheck; i++) { if ((textSeg[i] == 0x0000000c) && (i > 0)) { /* syscall */ /* li v0,NNN*/ if (((textSeg[i-1] & ~0x7fff) == 0x24020000) && /* bne a3,zero,XXX*/ ((textSeg[i+1] & ~0xffff) == 0x14e00000)) { int syscallnum = textSeg[i-1] & 0x7fff;#ifdef DEBUG printf("File %s - Converting syscall %d @ TEXT+0x%x\n", argv[argNum], syscallnum, i*4);#endif textSeg[i] = 0x8c020003; /* lw v0,3(zero) * This causes a SIGBUS */ changed = 1; i += 1; } else if (textSeg[i-1] == (0x24020000 + 1088)) { /* * Special case sigreturns */#ifdef DEBUG printf("File %s - Special casing sigreturn @ TEXT+0x%x\n", argv[argNum], i*4);#endif textSeg[i] = 0x8c020003; /* lw v0,3(zero) */ changed = 1; i += 1; } else if (textSeg[i-1] == 0x8fa20018) { /* * Special case stupid _sprocsp routine. */ textSeg[i] = 0x8c020003; /* lw v0,3(zero) */ changed = 1; i += 1; } else { /* * Complain about traps if there not system calls */ fprintf(stderr, "File %s - Found \"syscall\" @ TEXT+0x%x\n", argv[argNum],i*4); } } } if (changed) { #ifndef ELFLIB_BUG elf_flagdata(data, ELF_C_SET, ELF_F_DIRTY); if (elf_update(elf, ELF_C_WRITE) == -1) { fprintf(stderr, "%s: Error processing %s\n", argv[0], argv[argNum]); errors++; }#else if ((lseek(fd, shdr->sh_offset, SEEK_SET) != shdr->sh_offset) || (write(fd, data->d_buf, data->d_size) != data->d_size)) { perror(argv[argNum]); fprintf(stderr, "%s: Error processing %s\n", argv[0], argv[argNum]); errors++; }#endif } cmd = elf_next(elf); elf_end(elf); } error: elf_end(elf); } if (!changed) exit(-1); exit(errors); return 0; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -