📄 ldrdf.c
字号:
switch (hr->r.length) { case 1: offset += *data; if (offset < -127 || offset > 128) fprintf(error_file, "warning: relocation out of range " "at %s(%02x:%08lx)\n", cur->name, (int)hr->r.segment, hr->r.offset); *data = (char) offset; break; case 2: offset += * (short *)data; if (offset < -32767 || offset > 32768) fprintf(error_file, "warning: relocation out of range " "at %s(%02x:%08lx)\n", cur->name, (int)hr->r.segment, hr->r.offset); * (short *)data = (short) offset; break; case 4: * (long *)data += offset; /* we can't easily detect overflow on this one */ break; } /* * If the relocation was relative between two symbols in * the same segment, then we're done. * * Otherwise, we need to output a new relocation record * with the references updated segment and offset... */ if (! isrelative || cur->seginfo[localseg].dest_seg != seg) { hr->r.segment = cur->seginfo[localseg].dest_seg; hr->r.offset += cur->seginfo[localseg].reloc; hr->r.refseg = seg; if (isrelative) hr->r.segment += 64; rdfaddheader(rdfheader, hr); } break; case RDFREC_IMPORT: /* import symbol */ case RDFREC_FARIMPORT: /* * scan the global symbol table for the symbol * and associate its location with the segment number * for this module */ se = symtabFind(symtab, hr->i.label); if (!se || se->segment == -1) { if (options.warnUnresolved) { switch (options.warnUnresolved) { case 1: fprintf(error_file, "warning"); break; case 2: fprintf(error_file, "error"); errorcount++; } fprintf(error_file, ": unresolved reference to `%s'" " in module `%s'\n", hr->i.label, cur->name); } /* * we need to allocate a segment number for this * symbol, and store it in the symbol table for * future reference */ if (!se) { se=malloc(sizeof(*se)); if (!se) { fprintf(stderr, "ldrdf: out of memory\n"); exit(1); } se->name = strdup(hr->i.label); se->flags = 0; se->segment = availableseg++; se->offset = 0; symtabInsert(symtab, se); } else { se->segment = availableseg++; se->offset = 0; } /* * output a header record that imports it to the * recently allocated segment number... */ newrec = *hr; newrec.i.segment = se->segment; rdfaddheader(rdfheader, &newrec); } add_seglocation(&segs, hr->i.segment, se->segment, se->offset); break; case RDFREC_GLOBAL: /* export symbol */ /* * need to insert an export for this symbol into the new * header, unless we're stripping symbols. Even if we're * stripping, put the symbol if it's marked as SYM_GLOBAL. */ if (options.strip && !(hr->e.flags & SYM_GLOBAL)) break; if (hr->e.segment == 2) { seg = 2; offset = cur->bss_reloc; } else { localseg = rdffindsegment(&cur->f, hr->e.segment); if (localseg == -1) { fprintf(stderr, "%s: exported symbol `%s' from " "unrecognised segment\n", cur->name, hr->e.label); errorcount++; break; } offset = cur->seginfo[localseg].reloc; seg = cur->seginfo[localseg].dest_seg; } hr->e.segment = seg; hr->e.offset += offset; rdfaddheader(rdfheader, hr); break; case RDFREC_MODNAME: /* module name */ /* * Insert module name record if export symbols * are not stripped. * If module name begins with '$' - insert it anyway. */ if (options.strip && hr->m.modname[0] != '$') break; rdfaddheader(rdfheader, hr); break; case RDFREC_DLL: /* DLL name */ /* * Insert DLL name if it begins with '$' */ if (hr->d.libname[0] != '$') break; rdfaddheader(rdfheader, hr); break; case RDFREC_SEGRELOC: /* segment fixup */ /* * modify the segment numbers if necessary, and * pass straight through to the output module header * * *** FIXME *** */ if (hr->r.segment == 2) { fprintf(stderr, "%s: segment fixup in BSS section\n", cur->name); errorcount++; break; } localseg = rdffindsegment(&cur->f, hr->r.segment); if (localseg == -1) { fprintf(stderr, "%s: segment fixup in unrecognised" " segment (%d)\n", cur->name, hr->r.segment); errorcount++; break; } hr->r.segment = cur->seginfo[localseg].dest_seg; hr->r.offset += cur->seginfo[localseg].reloc; if (!get_seglocation(&segs, hr->r.refseg, &seg, &offset)) { fprintf(stderr, "%s: segment fixup to undefined " "segment %04x\n", cur->name, (int)hr->r.refseg); errorcount++; break; } hr->r.refseg = seg; rdfaddheader(rdfheader, hr); break; case RDFREC_COMMON: /* Common variable */ /* Is this symbol already in the table? */ se = symtabFind(symtab, hr->c.label); if (!se) { printf("%s is not in symtab yet\n", hr->c.label); break; } /* Add segment location */ add_seglocation(&segs, hr->c.segment, se->segment, se->offset); break; } } free(header); done_seglocations(&segs); } /* * combined BSS reservation for the entire results */ newrec.type = RDFREC_BSS; newrec.b.reclen = 4; newrec.b.amount = bss_length; rdfaddheader(rdfheader, &newrec); /* * Write the header */ for (i = 0; i < nsegs; i++) { if (i == 2) continue; rdfaddsegment (rdfheader, outputseg[i].length); } rdfwriteheader(f, rdfheader); rdfdoneheader(rdfheader); /* * Step through the segments, one at a time, writing out into * the output file */ for (i = 0; i < nsegs; i++) { int16 s; long l; if (i == 2) continue; s = translateshort(outputseg[i].type); fwrite(&s, 2, 1, f); s = translateshort(outputseg[i].number); fwrite(&s, 2, 1, f); s = translateshort(outputseg[i].reserved); fwrite(&s, 2, 1, f); l = translatelong(outputseg[i].length); fwrite(&l, 4, 1, f); fwrite(outputseg[i].data, outputseg[i].length, 1, f); } fwrite("\0\0\0\0\0\0\0\0\0\0", 10, 1, f);}/* ========================================================================= * Main program */void usage(){ printf("usage:\n" " ldrdf [options] object modules ... [-llibrary ...]\n" " ldrdf -r\n" "options:\n" " -v[=n] increases verbosity by 1, or sets it to n\n" " -a nn sets segment alignment value (default 16)\n" " -s strips exported symbols\n" " -x warn about unresolved symbols\n" " -o name write output in file 'name'\n" " -j path specify objects search path\n" " -L path specify libraries search path\n" " -g file embed 'file' as a first header record with type 'generic'\n"); exit(0);}int main(int argc, char ** argv){ char * outname = "aout.rdf"; int moduleloaded = 0; char *respstrings[128] = {0, }; options.verbose = 0; options.align = 16; options.warnUnresolved = 0; options.strip = 0; error_file = stderr; argc --, argv ++; if (argc == 0) usage(); while (argc && *argv && **argv == '-' && argv[0][1] != 'l') { switch(argv[0][1]) { case 'r': printf("ldrdf (linker for RDF files) version " LDRDF_VERSION "\n"); printf( _RDOFF_H "\n"); exit(0); case 'v': if (argv[0][2] == '=') { options.verbose = argv[0][3] - '0'; if (options.verbose < 0 || options.verbose > 9) { fprintf(stderr, "ldrdf: verbosity level must be a number" " between 0 and 9\n"); exit(1); } } else options.verbose++; break; case 'a': options.align = atoi(argv[1]); if (options.align <= 0) { fprintf(stderr, "ldrdf: -a expects a positive number argument\n"); exit(1); } argv++, argc--; break; case 's': options.strip = 1; break; case 'x': options.warnUnresolved = 1; if (argv[0][2]=='e') options.warnUnresolved++; break; case 'o': outname = argv[1]; argv++, argc--; break; case 'j': if (!objpath) { options.objpath = 1; objpath = argv[1]; argv++, argc--; break; } else { fprintf(stderr,"ldrdf: more than one objects search path specified\n"); exit(1); } case 'L': if (!libpath) { options.libpath = 1; libpath = argv[1]; argv++, argc--; break; } else { fprintf(stderr,"ldrdf: more than one libraries search path specified\n"); exit(1); } case '@': { int i=0; char buf[256]; FILE *f; options.respfile = 1; if (argv[1] != NULL) f = fopen(argv[1],"r"); else { fprintf(stderr,"ldrdf: no response file name specified\n"); exit(1); } if (f == NULL) { fprintf(stderr,"ldrdf: unable to open response file\n"); exit(1); } argv++, argc--; while (fgets(buf, sizeof(buf), f) != NULL) { char *p; if (buf[0]=='\n') continue; if ((p = strchr(buf,'\n')) != NULL) *p = '\0'; if (i >= 128) { fprintf(stderr,"ldrdf: too many input files\n"); exit(1); } *(respstrings+i) = newstr(buf); argc++, i++; } break; } case '2': options.stderr_redir = 1; error_file = stdout; break; case 'g': generic_rec_file = argv[1]; argv++, argc--; break; default: usage(); } argv++, argc--; } if (options.verbose > 4) { printf("ldrdf invoked with options:\n"); printf(" section alignment: %d bytes\n", options.align); printf(" output name: `%s'\n", outname); if (options.strip) printf(" strip symbols\n"); if (options.warnUnresolved == 1) printf(" warn about unresolved symbols\n"); if (options.warnUnresolved == 2) printf(" error if unresolved symbols\n"); if (options.objpath) printf(" objects search path: %s\n",objpath); if (options.libpath) printf(" libraries search path: %s\n",libpath); printf("\n"); } symtab = symtabNew(); initsegments(); if (!symtab) { fprintf(stderr, "ldrdf: out of memory\n"); exit(1); } while (argc) { if (!*argv) argv = respstrings; if (!*argv) break; if (!strncmp(*argv, "-l", 2)) /* library */ { if(libpath) add_library(newstrcat(libpath,*argv + 2)); else add_library(*argv + 2); } else { if(objpath) loadmodule(newstrcat(objpath,*argv)); else loadmodule(*argv); moduleloaded = 1; } argv++, argc--; } if (! moduleloaded) { printf("ldrdf: nothing to do. ldrdf -h for usage\n"); return 0; } search_libraries(); if (options.verbose > 2) { printf ("symbol table:\n"); symtabDump(symtab, stdout); } write_output(outname); if (errorcount > 0) exit(1); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -