comparison tools/objlink.c @ 1679:7b0c76cd7686

Clean up and improve error handling.
author Matti Hamalainen <ccr@tnsp.org>
date Thu, 31 May 2018 13:18:44 +0300
parents bddedc2e0ebb
children bd68c9adc7ca
comparison
equal deleted inserted replaced
1678:bddedc2e0ebb 1679:7b0c76cd7686
198 } 198 }
199 199
200 200
201 /* Memory block handling 201 /* Memory block handling
202 */ 202 */
203 void reserveMemBlock(int startAddr, int endAddr, const char *blockName, int blockType) 203 BOOL dmReserveMemBlock(int startAddr, int endAddr, const char *blockName, int blockType)
204 { 204 {
205 if (startAddr > endAddr) 205 if (startAddr > endAddr)
206 { 206 {
207 dmErrorMsg("ERROR! Block '%s' has startAddr=$%.4x > endAddr=$%.4x!\n", 207 dmErrorMsg("ERROR! Block '%s' has startAddr=$%.4x > endAddr=$%.4x!\n",
208 blockName, startAddr, endAddr); 208 blockName, startAddr, endAddr);
209 exit(4); 209 return FALSE;
210 } 210 }
211 211
212 if (nmemBlocks < MAX_FILENAMES) 212 if (nmemBlocks < MAX_FILENAMES)
213 { 213 {
214 memBlocks[nmemBlocks].start = startAddr; 214 memBlocks[nmemBlocks].start = startAddr;
215 memBlocks[nmemBlocks].end = endAddr; 215 memBlocks[nmemBlocks].end = endAddr;
216 memBlocks[nmemBlocks].name = dm_strdup(blockName); 216 memBlocks[nmemBlocks].name = dm_strdup(blockName);
217 memBlocks[nmemBlocks].type = blockType; 217 memBlocks[nmemBlocks].type = blockType;
218 nmemBlocks++; 218 nmemBlocks++;
219 return TRUE;
219 } 220 }
220 else 221 else
221 { 222 {
222 dmErrorMsg("Maximum number of memBlock definitions (%d) exceeded!\n", 223 dmErrorMsg("Maximum number of memBlock definitions (%d) exceeded!\n",
223 MAX_FILENAMES); 224 MAX_FILENAMES);
224 exit(4); 225 return FALSE;
225 } 226 }
226 } 227 }
227 228
228 229
229 int compareMemBlock(const void *cva, const void *cvb) 230 int dmCompareMemBlock(const void *cva, const void *cvb)
230 { 231 {
231 const DMMemBlock *a = cva, *b = cvb; 232 const DMMemBlock *a = cva, *b = cvb;
232 return a->start - b->start; 233 return a->start - b->start;
233 } 234 }
234 235
235 236
236 BOOL dmParseSection(const char *arg, unsigned int *sectStart, unsigned int *sectEnd, char **sectName, BOOL canHasName) 237 BOOL dmParseSection(const char *arg, unsigned int *sectStart, unsigned int *sectEnd, char **sectName, BOOL canHasName)
237 { 238 {
238 char sectMode, *sep, *str, *namesep; 239 char sectMode, *sep, *str, *namesep;
239 unsigned int tmpi; 240 unsigned int tmpi;
241 BOOL res = FALSE;
240 242
241 // Define reserved section 243 // Define reserved section
242 // Create a copy of the argument 244 // Create a copy of the argument
243 if ((str = dm_strdup(arg)) == NULL) 245 if ((str = dm_strdup(arg)) == NULL)
244 { 246 {
245 dmErrorMsg("Could not allocate temporary string!\n"); 247 dmErrorMsg("Could not allocate temporary string!\n");
246 exit(128); 248 goto out;
247 } 249 }
248 250
249 // Get start address 251 // Get start address
250 if ((sep = strchr(str, '-')) == NULL && 252 if ((sep = strchr(str, '-')) == NULL &&
251 (sep = strchr(str, ':')) == NULL) 253 (sep = strchr(str, ':')) == NULL)
252 { 254 {
253 dmErrorMsg("Section definition '%s' invalid.\n", arg); 255 dmErrorMsg("Section definition '%s' invalid.\n", arg);
254 goto error; 256 goto out;
255 } 257 }
256 sectMode = *sep; 258 sectMode = *sep;
257 *sep = 0; 259 *sep = 0;
258 260
259 // Get value 261 // Get value
260 if (!dmGetIntVal(str, sectStart)) 262 if (!dmGetIntVal(str, sectStart))
261 { 263 {
262 dmErrorMsg("Section start address '%s' in '%s' invalid.\n", str, arg); 264 dmErrorMsg("Section start address '%s' in '%s' invalid.\n", str, arg);
263 goto error; 265 goto out;
264 } 266 }
265 267
266 // Check for name 268 // Check for name
267 namesep = strchr(sep + 1, ','); 269 namesep = strchr(sep + 1, ',');
268 if (canHasName && namesep != NULL) 270 if (canHasName && namesep != NULL)
271 namesep++; 273 namesep++;
272 if (*namesep == 0) 274 if (*namesep == 0)
273 { 275 {
274 dmErrorMsg("Section definition '%s' name is empty. Either specify name or leave it out.\n", 276 dmErrorMsg("Section definition '%s' name is empty. Either specify name or leave it out.\n",
275 arg); 277 arg);
276 goto error; 278 goto out;
277 } 279 }
278 *sectName = dm_strdup(namesep); 280 *sectName = dm_strdup(namesep);
279 } 281 }
280 else 282 else
281 if (namesep != NULL) 283 if (namesep != NULL)
282 { 284 {
283 dmErrorMsg("Section definition does not allow a name, syntax error in '%s' at '%s'.\n", 285 dmErrorMsg("Section definition does not allow a name, syntax error in '%s' at '%s'.\n",
284 arg, namesep); 286 arg, namesep);
285 goto error; 287 goto out;
286 } 288 }
287 289
288 // Get end address or length 290 // Get end address or length
289 if (!dmGetIntVal(sep + 1, &tmpi)) 291 if (!dmGetIntVal(sep + 1, &tmpi))
290 { 292 {
291 dmErrorMsg("Section %s '%s' in '%s' invalid.\n", 293 dmErrorMsg("Section %s '%s' in '%s' invalid.\n",
292 sectMode == '-' ? "end address" : "length", 294 sectMode == '-' ? "end address" : "length",
293 sep + 1, arg); 295 sep + 1, arg);
294 goto error; 296 goto out;
295 } 297 }
296 298
297 if (sectMode == ':') 299 if (sectMode == ':')
298 { 300 {
299 *sectEnd = *sectStart + tmpi - 1; 301 *sectEnd = *sectStart + tmpi - 1;
302 { 304 {
303 if (tmpi < *sectStart) 305 if (tmpi < *sectStart)
304 { 306 {
305 dmErrorMsg("Section start address > end address in '%s'.\n", 307 dmErrorMsg("Section start address > end address in '%s'.\n",
306 arg); 308 arg);
307 goto error; 309 goto out;
308 } 310 }
309 *sectEnd = tmpi; 311 *sectEnd = tmpi;
310 } 312 }
311 313
314 res = TRUE;
315
316 out:
312 dmFree(str); 317 dmFree(str);
313 return TRUE; 318 return res;
314
315 error:
316 dmFree(str);
317 return FALSE;
318 } 319 }
319 320
320 321
321 BOOL dmParseInputFile(char *arg, const int type1, const int type2, const char *desc, BOOL requireAddr) 322 BOOL dmParseInputFile(char *arg, const int type1, const int type2, const char *desc, BOOL requireAddr)
322 { 323 {
460 // Allocate memory block 461 // Allocate memory block
461 sectLen = sectEnd - sectStart + 1; 462 sectLen = sectEnd - sectStart + 1;
462 dmMsg(1, "Reserve $%.4x - $%.4x ($%x, %d bytes) as '%s'\n", 463 dmMsg(1, "Reserve $%.4x - $%.4x ($%x, %d bytes) as '%s'\n",
463 sectStart, sectEnd, sectLen, sectLen, sectName); 464 sectStart, sectEnd, sectLen, sectLen, sectName);
464 465
465 reserveMemBlock(sectStart, sectEnd, sectName, MTYPE_RES); 466 if (!dmReserveMemBlock(sectStart, sectEnd, sectName, MTYPE_RES))
467 return FALSE;
466 } 468 }
467 break; 469 break;
468 470
469 case 13: 471 case 13:
470 { 472 {
567 } 569 }
568 570
569 dmPrint(1, " .. OK\n"); 571 dmPrint(1, " .. OK\n");
570 572
571 // Add to list of blocks 573 // Add to list of blocks
572 reserveMemBlock(loadAddr, endAddr, filename, MTYPE_RES); 574 if (!dmReserveMemBlock(loadAddr, endAddr, filename, MTYPE_RES))
575 res = DMERR_MALLOC;
573 576
574 out: 577 out:
575 if (fh != NULL) 578 if (fh != NULL)
576 fclose(fh); 579 fclose(fh);
577 580
623 } 626 }
624 627
625 dmPrint(1, " .. OK\n"); 628 dmPrint(1, " .. OK\n");
626 629
627 // Add info to list 630 // Add info to list
628 reserveMemBlock(destAddr, endAddr, filename, MTYPE_RES); 631 if (!dmReserveMemBlock(destAddr, endAddr, filename, MTYPE_RES))
632 res = DMERR_MALLOC;
629 633
630 out: 634 out:
631 if (fh != NULL) 635 if (fh != NULL)
632 fclose(fh); 636 fclose(fh);
633 637
782 dmVerbosity = 1; 786 dmVerbosity = 1;
783 787
784 // Parse arguments 788 // Parse arguments
785 if (!dmArgsProcess(argc, argv, optList, optListN, 789 if (!dmArgsProcess(argc, argv, optList, optListN,
786 argHandleOpt, NULL, OPTH_BAILOUT)) 790 argHandleOpt, NULL, OPTH_BAILOUT))
787 exit(1); 791 goto out;
788 792
789 if (nsrcFiles < 1) 793 if (nsrcFiles < 1)
790 { 794 {
791 dmErrorMsg("Nothing to do. (try --help)\n"); 795 dmErrorMsg("Nothing to do. (try --help)\n");
792 exit(0); 796 goto out;
793 } 797 }
794 798
795 // Allocate memory 799 // Allocate memory
796 memModel = &memoryModels[optMemModel]; 800 memModel = &memoryModels[optMemModel];
797 dmMsg(1, "Using memory model #%d '%s', %d bytes.\n", 801 dmMsg(1, "Using memory model #%d '%s', %d bytes.\n",
798 optMemModel, memModel->name, memModel->size); 802 optMemModel, memModel->name, memModel->size);
799 803
800 memory = (Uint8 *) dmMalloc(memModel->size + 32); 804 if ((memory = (Uint8 *) dmMalloc(memModel->size + 32)) == NULL)
801 if (memory == NULL) 805 {
802 { 806 dmErrorMsg("Could not allocate memory for memory model!\n");
803 dmErrorMsg("Could not allocate memory.\n"); 807 goto out;
804 exit(2);
805 } 808 }
806 809
807 // Initialize memory 810 // Initialize memory
808 dmMsg(1, "Initializing memory with "); 811 dmMsg(1, "Initializing memory with ");
809 812
851 854
852 // Add memory model blocks 855 // Add memory model blocks
853 dmMsg(1, "Applying memory model restrictions...\n"); 856 dmMsg(1, "Applying memory model restrictions...\n");
854 for (int i = 0; i < memModel->nmemBlocks; i++) 857 for (int i = 0; i < memModel->nmemBlocks; i++)
855 { 858 {
856 reserveMemBlock( 859 if (!dmReserveMemBlock(
857 memModel->memBlocks[i].start, 860 memModel->memBlocks[i].start,
858 memModel->memBlocks[i].end, 861 memModel->memBlocks[i].end,
859 memModel->memBlocks[i].name, 862 memModel->memBlocks[i].name,
860 memModel->memBlocks[i].type); 863 memModel->memBlocks[i].type))
864 goto out;
861 } 865 }
862 866
863 // Sort the blocks 867 // Sort the blocks
864 qsort(memBlocks, nmemBlocks, sizeof(DMMemBlock), compareMemBlock); 868 qsort(memBlocks, nmemBlocks, sizeof(DMMemBlock), dmCompareMemBlock);
865 869
866 // Check for overlapping conflicts 870 // Check for overlapping conflicts
867 hasOverlaps = FALSE; 871 hasOverlaps = FALSE;
868 for (int i = 0; i < nmemBlocks; i++) 872 for (int i = 0; i < nmemBlocks; i++)
869 for (int j = 0; j < nmemBlocks; j++) 873 for (int j = 0; j < nmemBlocks; j++)
884 } 888 }
885 889
886 if (!optAllowOverlap && hasOverlaps) 890 if (!optAllowOverlap && hasOverlaps)
887 { 891 {
888 dmErrorMsg("Error occured, overlaps not allowed.\n"); 892 dmErrorMsg("Error occured, overlaps not allowed.\n");
889 exit(5); 893 goto out;
890 } 894 }
891 895
892 // Find out start and end-addresses 896 // Find out start and end-addresses
893 startAddr = memModel->size; 897 startAddr = memModel->size;
894 totalSize = endAddr = 0; 898 totalSize = endAddr = 0;
907 } 911 }
908 } 912 }
909 913
910 if (startAddr >= memModel->size || endAddr < startAddr) 914 if (startAddr >= memModel->size || endAddr < startAddr)
911 { 915 {
912 dmErrorMsg("Invalid saveblock addresses (start=$%.4x, end=$%.4x)!\n", startAddr, endAddr); 916 dmErrorMsg("Invalid saveblock addresses (start=$%.4x, end=$%.4x)!\n",
913 exit(8); 917 startAddr, endAddr);
918 goto out;
914 } 919 }
915 920
916 // Output linkfile 921 // Output linkfile
917 if (optLinkFileName) 922 if (optLinkFileName)
918 { 923 {
920 if ((dfile = fopen(optLinkFileName, "wb")) == NULL) 925 if ((dfile = fopen(optLinkFileName, "wb")) == NULL)
921 { 926 {
922 int err = dmGetErrno(); 927 int err = dmGetErrno();
923 dmErrorMsg("Error creating file '%s' #%d: %s.\n", 928 dmErrorMsg("Error creating file '%s' #%d: %s.\n",
924 optLinkFileName, err, dmErrorStr(err)); 929 optLinkFileName, err, dmErrorStr(err));
925 exit(1); 930 goto out;
926 } 931 }
927 932
928 switch (optLinkFileFormat) 933 switch (optLinkFileFormat)
929 { 934 {
930 case FMT_GENERIC: 935 case FMT_GENERIC:
971 else if ((dfile = fopen(optDestName, "wb")) == NULL) 976 else if ((dfile = fopen(optDestName, "wb")) == NULL)
972 { 977 {
973 int err = dmGetErrno(); 978 int err = dmGetErrno();
974 dmErrorMsg("Error creating output file '%s' #%d: %s.\n", 979 dmErrorMsg("Error creating output file '%s' #%d: %s.\n",
975 optDestName, err, dmErrorStr(err)); 980 optDestName, err, dmErrorStr(err));
976 exit(1); 981 goto out;
977 } 982 }
978 else 983 else
979 dmPrint(1, "to '%s'\n", optDestName); 984 dmPrint(1, "to '%s'\n", optDestName);
980 985
981 // Save loading address 986 // Save loading address
999 if (fwrite(&memory[startAddr], dataSize, 1, dfile) < 1) 1004 if (fwrite(&memory[startAddr], dataSize, 1, dfile) < 1)
1000 { 1005 {
1001 int err = dmGetErrno(); 1006 int err = dmGetErrno();
1002 dmErrorMsg("Error writing to file #%d: %s.\n", 1007 dmErrorMsg("Error writing to file #%d: %s.\n",
1003 err, dmErrorStr(err)); 1008 err, dmErrorStr(err));
1004 } 1009 goto out;
1005 1010 }
1006 fclose(dfile); 1011
1007 1012 // Describe the memory layout
1008 // Describe
1009 if (optDescribe) 1013 if (optDescribe)
1010 dmDescribeMemory(stdout); 1014 dmDescribeMemory(dfile != stdout ? stdout : stderr);
1015
1016 out:
1017 if (dfile != NULL && dfile != stdout)
1018 fclose(dfile);
1011 1019
1012 return 0; 1020 return 0;
1013 } 1021 }