/****************************************************************** * * - O mapa de relocacao deve usar o bit 1 para relativo e o bit 0 * para absoluto * * - Todos os valores relativos sao enderecos que ocupam 2 bytes e * devem ser tratados como tal * * - Dentro do mapa de relocacao, bit mais significativo dentro de * um mesmo byte significa byte anterior no codigo executavel * * - O tamanho do mapa de relocacao eh dado pelo tamanho do codigo * gerado em bytes dividido por 8 * * - Caso nao resulte em numero inteiro de bytes, completar com zeros * ateh que o mapa de bits tenha um tamanho multiplo de 8 * * * * long assinatura = 0x12345678; * long tamanho_do_cabecalho_em_bytes = 16; * long tamanho_do_codigo_gerado_em_bytes; * long tamanho_do_mapa_de_relocacao_em_bytes; * * char codigo_gerado [ tamanho_do_codigo_gerado_em_bytes ]; * * char mapa_de_relocacao [ tamanho_do_mapa_de_relocacao_em_bytes ]; * * * ***********************************************************************/ #include #include #include #include #include #define a_r( byt, pos) ( ((byt) & masc[(pos)]) == 0 ? 'a' : 'r' ) int masc[8] = { 0x0080, 0x0040, 0x0020, 0x0010, 0x0008, 0x0004, 0x0002, 0x0001 }; /*----------------------------*/ struct descritor { long assinatura; long tam_cabecalho_bytes; long tam_codigo_gerado_bytes; long tam_mapa_relocacao_bytes; }; /*----------------------------*/ struct descritor desc; char *codigo_gerado; char *mapa_relocacao; /*----------------------------*/ void naoleu( char *s) { printf("\n### Nao conseguiu ler o %s do arquivo.\n", s); exit(1); } void naotinha( char *s) { printf("\n### Arquivo terminou antes do %s.\n", s); exit(1); } void errocampo( char *s) { printf("\n### Erro no campo >>>%s<<< do arquivo.\n", s); exit(1); } void errogeral( char *s) { printf("\n### %s.\n", s); exit(1); } /*----------------------------*/ void main( int argc, char *argv[]) { int fd; long lidos; int x, i; if( argc != 2 ) { printf("Uso: so1-991 \n"); exit(1); } if( (fd=open( argv[1], O_BINARY | O_RDONLY)) == -1 ) { printf("Nao conseguiu abrir o arquivo %s.\n", argv[1]); exit(1); } else printf("Abriu arquivo %s.\n", argv[1]); /*-------------------*/ /* Descritor inicial */ /*-------------------*/ lidos = read( fd, &desc, sizeof( struct descritor)); if( lidos == -1 ) naoleu("descritor do arquivo"); if( lidos != sizeof(struct descritor) ) naotinha("descritor do arquivo"); if( desc.assinatura != 0x12345678L ) errocampo("assinatura"); if( desc.tam_cabecalho_bytes != 16 ) errocampo("tamanho do cabecalho em bytes"); if( desc.tam_codigo_gerado_bytes < 0L || desc.tam_codigo_gerado_bytes > 32000L ) errocampo("tamanho do codigo gerado em bytes"); x = (int)(desc.tam_codigo_gerado_bytes / 8); if( desc.tam_codigo_gerado_bytes % 8 > 0) ++x; if( desc.tam_mapa_relocacao_bytes != x ) errocampo("tamanho do mapa de relocacao em bytes"); /*------------------*/ /* Mostra descritor */ /*------------------*/ printf("Conteudo do arquivo: %s.\n", argv[1]); printf("Assinatura: %lx\n", desc.assinatura); printf("Tamanho do cabecalho em bytes: %ld.\n", desc.tam_cabecalho_bytes); printf("Tamanho do codigo gerado em bytes: %ld\n", desc.tam_codigo_gerado_bytes); printf("Tamanho do byte de relocacao em bytes: %ld.\n", desc.tam_mapa_relocacao_bytes); /*---------------*/ /* Codigo gerado */ /*---------------*/ if( (codigo_gerado = malloc( (int)desc.tam_codigo_gerado_bytes)) == NULL ) errogeral("Faltou memoria para codigo gerado"); lidos = read( fd, codigo_gerado, (int)desc.tam_codigo_gerado_bytes); if( lidos == -1 ) naoleu("codigo gerado"); if( lidos != desc.tam_codigo_gerado_bytes ) naotinha("codigo gerado"); /*-------------------*/ /* Mapa de relocacao */ /*-------------------*/ if( (mapa_relocacao = malloc( (int)desc.tam_mapa_relocacao_bytes)) == NULL ) errogeral("Faltou memoria para mapa de relocacao"); lidos = read( fd, mapa_relocacao, (int)desc.tam_mapa_relocacao_bytes); if( lidos == -1 ) naoleu("mapa de relocao"); if( lidos != desc.tam_mapa_relocacao_bytes ) naotinha("mapa de relocacao"); /*------------------------------------------*/ /* Mostra codigo gerado + mapa de relocacao */ /*------------------------------------------*/ i = 0; while( i