/****************************************************************** * * - 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 * * * * int assinatura = 0x1234; * int tamanho_do_cabecalho_em_bytes = 12; * int tamanho_do_codigo_gerado_em_bytes; * int tamanho_do_mapa_de_relocacao_em_bytes; * int tamanho_da_tabela_de_uso_em_entradas; * int tamanho_da_tabela_de_definicao_em_entradas; * * char codigo_gerado [ tamanho_do_codigo_gerado_em_bytes ]; * * char mapa_de_relocacao [ tamanho_do_mapa_de_relocacao_em_bytes ]; * * * struct { * char simbolo[32]; * int endereco_de_uso; * char sinal_adicao_ou_subtracao; * } tabela_de_uso[ tamanho_da_tabela_de_uso_em_entradas ]; * * * * struct { * char simbolo[32]; * int valor_do_simbolo; * int absoluto_0_ou_relativo_1; * } tabela_de_definicao[ tamanho_da_tabela_de_definicao_em_entradas]; * * * ***********************************************************************/ #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 { int assinatura; int tam_cabecalho_bytes; int tam_codigo_gerado_bytes; int tam_mapa_relocacao_bytes; int tam_tabela_uso_entradas; int tam_tabela_definicao_entradas; }; struct uso{ char simbolo[32]; int endereco_de_uso; char sinal_adicao_ou_subtracao; }; struct definicao{ char simbolo[32]; int valor_do_simbolo; int absoluto_0_ou_relativo_1; }; /*----------------------------*/ struct descritor desc; char *codigo_gerado; char *mapa_relocacao; struct uso *tabela_uso; struct definicao *tabela_definicao; /*----------------------------*/ 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, t; if( argc != 2 ) { printf("Uso: 972 \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 != 0x1234 ) errocampo("assinatura"); if( desc.tam_cabecalho_bytes != 12 ) errocampo("tamanho do cabecalho em bytes"); if( desc.tam_codigo_gerado_bytes < 0 || desc.tam_codigo_gerado_bytes > 32000 ) errocampo("tamanho do codigo gerado em bytes"); x = 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"); if( desc.tam_tabela_uso_entradas < 0 || desc.tam_tabela_uso_entradas > 1000 ) errocampo("tamanho da tabela de uso em entradas"); if( desc.tam_tabela_definicao_entradas < 0 || desc.tam_tabela_definicao_entradas > 1000 ) errocampo("tamanho da tabela de definicao em entradas"); /*------------------*/ /* Mostra descritor */ /*------------------*/ printf("Conteudo do arquivo: %s.\n", argv[1]); printf("Assinatura: %x\n", desc.assinatura); printf("Tamanho do cabecalho em bytes: %d.\n", desc.tam_cabecalho_bytes); printf("Tamanho do codigo gerado em bytes: %d\n", desc.tam_codigo_gerado_bytes); printf("Tamanho do byte de relocacao em bytes: %d.\n", desc.tam_mapa_relocacao_bytes); printf("Tamanho da tabela de uso em entradas: %d.\n", desc.tam_tabela_uso_entradas); printf("Tamanho da tabela de definicao em entradas: %d.\n", desc.tam_tabela_definicao_entradas); /*---------------*/ /* Codigo gerado */ /*---------------*/ if( (codigo_gerado = malloc( desc.tam_codigo_gerado_bytes)) == NULL ) errogeral("Faltou memoria para codigo gerado"); lidos = read( fd, codigo_gerado, 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( desc.tam_mapa_relocacao_bytes)) == NULL ) errogeral("Faltou memoria para mapa de relocacao"); lidos = read( fd, mapa_relocacao, 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 0 ) { t = desc.tam_tabela_uso_entradas * sizeof(struct uso); if( (tabela_uso = calloc( desc.tam_tabela_uso_entradas, sizeof(struct uso) )) == NULL ) errogeral("Faltou memoria para a tabela de uso"); lidos = read( fd, tabela_uso, t); if( lidos == -1 ) naoleu("tabela de uso"); if( lidos != t ) naotinha("tabela de uso"); for( i=0; i31 ) printf("Entrada %d Tab. uso com tamanho invalido.\n", i); tabela_uso[i].simbolo[31] = '\0'; } } /*----------------------*/ /* Mostra tabela de uso */ /*----------------------*/ printf("\n TABELA DE USO:\n"); for( i=0; i 0 ) { t = desc.tam_tabela_definicao_entradas * sizeof(struct definicao); if( (tabela_definicao = calloc( desc.tam_tabela_definicao_entradas, sizeof(struct definicao) )) == NULL ) errogeral("Faltou memoria para a tabela de definicao"); lidos = read( fd, tabela_definicao, t); if( lidos == -1 ) naoleu("tabela de definicao"); if( lidos != t ) naotinha("tabela de definicao"); for( i=0; i31 ) printf("Entrada %d Tab. definicao com tamanho invalido.\n", i); tabela_definicao[i].simbolo[31] = '\0'; } } /*----------------------------*/ /* Mostra tabela de definicao */ /*----------------------------*/ printf("\n TABELA DE DEFINICAO:\n"); for( i=0; i