00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include <stdio.h>
00017 #include <stdlib.h>
00018 #include <string.h>
00019
00020 #include "list.h"
00021 #include "objectFile.h"
00022
00023
00024 #define SO_LINKER "ld"
00025 #define SO_DUMPER "objdump"
00026 #define SO_DPARAM "-rh"
00027 #define SO_DFILE ".-"
00028 #define SO_REMOVER "objcopy"
00029 #define SO_RRMV "-R"
00030 #define SO_PIPE ">"
00032 static const char* hlp = "Usage: deadstrip [options] file...\n"
00033 "Options:\n"
00034 " --help display this HELP\n"
00035 " --dcmd Dumps the ComManD line\n"
00036 " --ddis Dumps DIScarted sections\n"
00037 " --duse Dumps USEd sections\n"
00038 " --dmap Dump the dependency MAP\n"
00039 " --linker <filename> use alternative LINKER (default: "SO_LINKER")\n"
00040 " --dnrm Do Not ReMove any sections\n"
00041 " --save <item> SAVE an item and its dependencies\n"
00042 " > just pass the decorated variable/function name, not the section\n"
00043 " > the main function gets saved by default\n"
00044 "\n"
00045 "Version 1.1\n"
00046 "Last compiled on "__DATE__".\n";
00047
00048 #define SO_DUMP_CMDLN 1
00049 #define SO_DUMP_DISCARTED 2
00050 #define SO_DUMP_USED 4
00051 #define SO_OBJECTS 8
00052 #define SO_HELP 16
00053 #define SO_DUMP_MAP 32
00054 #define SO_DNRM 64
00055 #define SO_COLLECT 128
00056
00057
00058 #define SO_SC(tar, txt) \
00059 {\
00060 const char* data = txt;\
00061 while ((*tar = *data++))\
00062 ++tar;\
00063 }
00064
00065 int main(int argc, const char* argv[])
00066 {
00067 const char* linker = SO_LINKER, dumper[] = SO_DUMPER " " SO_DPARAM;
00068 char** largs = (char**) malloc(sizeof(char*) * argc);
00069 int i = argc, li = 0, llen = strlen(linker) + 2, olen = sizeof(dumper)
00070 + sizeof(SO_PIPE SO_DFILE), len;
00071 unsigned long flags = 0;
00072 list *lObject = newList(), *lSeed = newList();
00073
00074
00075
00076 listAdd(lSeed, "main");
00077
00078
00079
00080 while (--i > 0)
00081 {
00082 ++argv;
00083 if (**argv == '-')
00084 {
00085 flags &= ~SO_COLLECT;
00086 if (argv[0][1] == '-')
00087 {
00088 if (!strcmp(*argv, "--save"))
00089 {
00090 ++argv;
00091
00092 if (--i)
00093 listAdd(lSeed, *argv);
00094
00095 continue;
00096 }
00097 else if (!strcmp(*argv, "--help"))
00098 {
00099 flags |= SO_HELP;
00100 continue;
00101 }
00102 else if (!strcmp(*argv, "--dcmd"))
00103 {
00104 flags |= SO_DUMP_CMDLN;
00105 continue;
00106 }
00107 else if (!strcmp(*argv, "--ddis"))
00108 {
00109 flags |= SO_DUMP_DISCARTED;
00110 continue;
00111 }
00112 else if (!strcmp(*argv, "--duse"))
00113 {
00114 flags |= SO_DUMP_USED;
00115 continue;
00116 }
00117 else if (!strcmp(*argv, "--dmap"))
00118 {
00119 flags |= SO_DUMP_MAP;
00120 continue;
00121 }
00122 else if (!strcmp(*argv, "--linker"))
00123 {
00124 ++argv;
00125 if (--i)
00126 {
00127 llen += strlen(*argv) - strlen(linker);
00128 linker = *argv;
00129 }
00130 continue;
00131 }
00132 else if (!strcmp(*argv, "--dnrm"))
00133 {
00134 flags |= SO_DNRM;
00135 continue;
00136 }
00137 }
00138 else if (!strncmp(*argv, "-o", sizeof("-o") - 1))
00139 {
00140 flags |= SO_COLLECT | SO_OBJECTS;
00141
00142
00143
00144 if (!argv[0][sizeof("-o") - 1])
00145 {
00146
00147 llen += sizeof("-o");
00148 largs[li++] = (char*) *argv;
00149 continue;
00150 }
00151 }
00152 }
00153
00154 len = strlen(*argv) + 1;
00155
00156
00157
00158 if (flags & SO_COLLECT)
00159 {
00160 listAdd(lObject, objectFileCreate(*argv));
00161 olen += len;
00162 }
00163
00164
00165 llen += len;
00166 largs[li++] = (char*) *argv;
00167 }
00168
00169 argv -= argc - 1;
00170 largs[li] = 0;
00171
00172 if (flags & SO_HELP)
00173 printf(hlp);
00174
00175
00176
00177 if (flags & SO_OBJECTS)
00178 {
00179
00180 listStart(lObject);
00181 listNext(lObject);
00182 olen -= strlen(objectFileGetName((objectFile*) listGet(lObject))) + 1;
00183 listRemove(lObject);
00184
00185
00186
00187 if (listIsEmpty(lObject))
00188 {
00189 fprintf(stderr, "ERROR: You can't link an executable without "
00190 "providing object files.");
00191 return -1;
00192 }
00193
00194
00195
00196
00197 {
00198 char* cmdLn = (char*) malloc(sizeof(char) * olen);
00199
00200 SO_SC(cmdLn, dumper);
00201 SO_SC(cmdLn, " ");
00202
00203 listStart(lObject);
00204 while (listNext(lObject))
00205 {
00206 SO_SC(cmdLn, objectFileGetName((objectFile*)listGet(lObject)));
00207 SO_SC(cmdLn, " ");
00208 }
00209
00210 SO_SC(cmdLn, SO_PIPE SO_DFILE);
00211 cmdLn -= olen - 1;
00212
00213 system(cmdLn);
00214 free(cmdLn);
00215 }
00216
00217
00218 {
00219 FILE* objDump = fopen(SO_DFILE, "r");
00220
00221 if (objDump)
00222 {
00223
00224
00225 listStart(lObject);
00226 while (listNext(lObject))
00227 {
00228 objectFile* obj = (objectFile*) listGet(lObject);
00229 objectFileCollect(obj, objDump);
00230 }
00231
00232
00233 rewind(objDump);
00234 objectFileCompute(lObject, objDump);
00235
00236
00237 listStart(lSeed);
00238 while (listNext(lSeed))
00239 objectFileColorize((const char*) listGet(lSeed), 1);
00240
00241 fclose(objDump);
00242 remove(SO_DFILE);
00243 }
00244 else
00245 fprintf(stderr, "ERROR: Couldn't compute dependency graph, because "
00246 "dumpfile could not be opened.\n");
00247 }
00248
00249
00250 if (!(flags & SO_DNRM))
00251 {
00252 char* cmdLn = 0;
00253
00254 listStart(lObject);
00255 while (listNext(lObject))
00256 {
00257 objectFile* obj = (objectFile*) listGet(lObject);
00258 const char* file = objectFileGetName(obj);
00259 unsigned long size = sizeof(SO_REMOVER " ") + strlen(file);
00260 list* nonDepends = (list*) objectFileGetUnused(obj);
00261
00262 if (listIsEmpty(nonDepends))
00263 continue;
00264
00265
00266 listStart(nonDepends);
00267 while (listNext(nonDepends))
00268 size += sizeof(SO_RRMV " ") + strlen((char*) listGet(nonDepends));
00269
00270 cmdLn = (char*) realloc(cmdLn, size);
00271 SO_SC(cmdLn, SO_REMOVER " ");
00272
00273 listStart(nonDepends);
00274 while (listNext(nonDepends))
00275 {
00276 SO_SC(cmdLn, SO_RRMV " ");
00277 SO_SC(cmdLn, (char*)listGet(nonDepends));
00278 SO_SC(cmdLn, " ");
00279 }
00280 SO_SC(cmdLn, file);
00281 cmdLn -= size - 1;
00282
00283 system(cmdLn);
00284 deleteList(nonDepends);
00285 }
00286
00287 free(cmdLn);
00288 }
00289
00290
00291
00292 {
00293 char* cmdLn = (char*) malloc(sizeof(char) * llen);
00294
00295 SO_SC(cmdLn, linker);
00296 SO_SC(cmdLn, " ");
00297
00298 i = 0;
00299 while (i < li)
00300 {
00301 SO_SC(cmdLn, largs[i]);
00302 SO_SC(cmdLn, " ");
00303 ++i;
00304 }
00305 cmdLn -= llen - 1;
00306
00307 system(cmdLn);
00308 free(cmdLn);
00309 }
00310 }
00311 else if (!(flags & SO_HELP))
00312 printf(hlp);
00313
00314
00315
00316 if (flags & SO_DUMP_CMDLN)
00317 {
00318 printf("\nCOMMAND LINE:\n%s ", *argv++);
00319 while (--argc)
00320 printf("%s ", *argv++);
00321 printf("\n");
00322 }
00323
00324 if (flags & SO_OBJECTS)
00325 {
00326
00327 if (flags & SO_DUMP_MAP)
00328 objectFileDumpMap(lObject);
00329
00330
00331
00332 if (flags & SO_DUMP_USED)
00333 objectFileDumpUsed(lObject);
00334
00335
00336
00337 if (flags & SO_DUMP_DISCARTED)
00338 objectFileDumpUnused(lObject);
00339 }
00340
00341
00342 free(largs);
00343 deleteList(lObject);
00344 deleteList(lSeed);
00345
00346 return 0;
00347 }