vita-toolchain

git clone https://git.neptards.moe/neptards/vita-toolchain.git
Log | Files | Refs | README | LICENSE

vita-elf-export.c (4899B)


      1 #include <stdio.h>
      2 #include <yaml.h>
      3 
      4 #include "vita-export.h"
      5 #include "yamlemitter.h"
      6 
      7 static void show_usage(void)
      8 {
      9 	fprintf(stderr, "usage: vita-elf-export mod-type elf exports imports\n"
     10 					"\tmod-type: valid values: 'u'/'user' for user mode, else 'k'/'kernel' for kernel mode\n"
     11 					"\telf: path to the elf produced by the toolchain to be used by vita-elf-create\n"
     12 					"\texports: path to the config yaml file specifying the module information and exports\n"
     13 					"\timports: path to write the import yaml generated by this tool\n");
     14 }
     15 
     16 char* hextostr(int x){
     17 	static char buf[20];
     18 	sprintf(buf,"0x%x",x);
     19 	return buf;
     20 }
     21 
     22 char* booltostr(int x){
     23 	return x ? "true" : "false";
     24 }
     25 
     26 int pack_export_symbols(yaml_emitter_t * emitter, yaml_event_t *event, vita_export_symbol **symbols, size_t symbol_n)
     27 {
     28 
     29 	if(!yamlemitter_mapping_start(emitter, event))
     30 		return 0;
     31 		
     32 	for (int i = 0; i < symbol_n; ++i)
     33 	{		
     34 
     35 		if(!yamlemitter_key_value(emitter, event, symbols[i]->name, hextostr(symbols[i]->nid)))
     36 			return 0;
     37 			
     38 	}
     39 	
     40 	yaml_mapping_end_event_initialize(event);
     41 	if (!yaml_emitter_emit(emitter, event))
     42 		return 0;
     43 	
     44 	return -1;
     45 	
     46 }
     47 
     48 int main(int argc, char *argv[])
     49 {
     50 	if (argc != 5)
     51 	{
     52 		show_usage();
     53 		return EXIT_FAILURE;
     54 	}
     55 	
     56 	const char *type = argv[1];
     57 	const char *elf_path = argv[2];
     58 	const char *export_path = argv[3];
     59 	const char *import_path = argv[4];
     60 	char buffer[100];
     61 
     62 	
     63 	int is_kernel = 0;
     64 	
     65 	// check if kernel or user
     66 	if (strcmp(type, "kernel") == 0 || strcmp(type, "k") == 0)
     67 	{
     68 		is_kernel = 1;
     69 	}
     70 	else if (strcmp(type, "user") == 0 || strcmp(type, "u") == 0)
     71 	{
     72 		is_kernel = 0;
     73 	}
     74 	else
     75 	{
     76 		fprintf(stderr, "error: invalid mod-type '%s'. see usage for more info\n", type);
     77 		return EXIT_FAILURE;
     78 	}
     79 	
     80 	// load our exports
     81 	vita_export_t *exports = vita_exports_load(export_path, elf_path, 0);
     82 	
     83 	if (!exports)
     84 		return EXIT_FAILURE;
     85 	
     86 	yaml_emitter_t emitter;
     87 	yaml_event_t event;
     88 
     89 	/* Create the Emitter object. */
     90 	yaml_emitter_initialize(&emitter);
     91 	
     92 	FILE *fp = fopen(import_path, "w");
     93 
     94 	if (!fp)
     95 	{
     96 		// TODO: handle this
     97 		fprintf(stderr, "could not open '%s' for writing\n", import_path);
     98 		return EXIT_FAILURE;
     99 	}
    100 
    101 	yaml_emitter_set_output_file(&emitter, fp);
    102 
    103 	/* Create and emit the STREAM-START event. */
    104 	if(!yamlemitter_stream_start(&emitter, &event))
    105 		goto error;
    106 		
    107 	if(!yamlemitter_document_start(&emitter, &event))
    108 		goto error;
    109 		
    110 	if(!yamlemitter_mapping_start(&emitter, &event))
    111 		goto error;
    112 		
    113 	if(!yamlemitter_key(&emitter, &event,"modules"))
    114 		goto error;
    115 		
    116 	if(!yamlemitter_mapping_start(&emitter, &event))
    117 		goto error;
    118 			
    119 	if(!yamlemitter_key(&emitter, &event,exports->name))
    120 		goto error;
    121 
    122 	if(!yamlemitter_mapping_start(&emitter, &event))
    123 		goto error;
    124 	
    125 	if(!yamlemitter_key_value(&emitter, &event,"nid",hextostr(exports->nid)))
    126 		goto error;
    127 		
    128 	if(!yamlemitter_key(&emitter, &event,"libraries"))
    129 		goto error;
    130 					
    131 	if(!yamlemitter_mapping_start(&emitter, &event))
    132 		goto error;
    133 	
    134 	for (int i = 0; i < exports->module_n; ++i)
    135 	{
    136 		vita_library_export *lib = exports->modules[i];
    137 		
    138 		int kernel_lib = is_kernel;
    139 		
    140 		if (lib->syscall)
    141 		{
    142 			if (is_kernel)
    143 			{
    144 				kernel_lib = 0;
    145 			}
    146 			else
    147 			{
    148 				fprintf(stderr, "error: got syscall flag for user module. did you mean to pass as kernel module?");
    149 				return EXIT_FAILURE;
    150 			}
    151 		}
    152 		
    153 		if(!yamlemitter_key(&emitter, &event, lib->name))
    154 			goto error;
    155 		
    156 		if(!yamlemitter_mapping_start(&emitter, &event))
    157 			goto error;
    158 			
    159 		if(!yamlemitter_key_value(&emitter, &event,"nid",hextostr(lib->nid)))
    160 			goto error;
    161 		
    162 		if(!yamlemitter_key_value(&emitter, &event,"kernel",booltostr(kernel_lib)))
    163 			goto error;
    164 		
    165 		
    166 		if(lib->function_n){
    167 			
    168 			if(!yamlemitter_key(&emitter, &event, "functions"))
    169 				goto error;
    170 					
    171 			if(!pack_export_symbols(&emitter, &event, lib->functions, lib->function_n))
    172 				goto error;
    173 		}
    174 		
    175 		if(lib->variable_n){
    176 			
    177 			if(!yamlemitter_key(&emitter, &event, "variables"))
    178 				goto error;
    179 				
    180 			if(!pack_export_symbols(&emitter, &event, lib->variables, lib->variable_n))
    181 				goto error;
    182 		}
    183 		
    184 		yaml_mapping_end_event_initialize(&event);
    185 		if (!yaml_emitter_emit(&emitter, &event))
    186 			goto error;
    187 			
    188 	}
    189 	
    190 	if(!yamlemitter_mapping_end(&emitter, &event))
    191 		goto error;
    192 	
    193 	if(!yamlemitter_mapping_end(&emitter, &event))
    194 		goto error;
    195 
    196 	if(!yamlemitter_mapping_end(&emitter, &event))
    197 		goto error;
    198 	
    199 	if(!yamlemitter_mapping_end(&emitter, &event))
    200 		goto error;
    201 
    202 	if(!yamlemitter_document_end(&emitter, &event))
    203 		goto error;
    204 		
    205 	if(!yamlemitter_stream_end(&emitter, &event))
    206 		goto error;
    207 
    208 	/* On error. */
    209 error:
    210 	fclose(fp);
    211 	/* Destroy the Emitter object. */
    212 	yaml_emitter_delete(&emitter);
    213 	// TODO: free exports, free json
    214 	return 0;
    215 }