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 }