GNU Binutils with patches for OS216
修訂 | 2b35fb28f397a26c0da03f7579116d28af2af824 (tree) |
---|---|
時間 | 2015-10-21 23:16:35 |
作者 | Ronald Hoogenbllon <rhoogenboom@irde...> |
Commiter | Nick Clifton |
Add ability for objcopy to insert new symbols into a binary.
PR binutils/19104
binutils * objcopy.c (command_line_switch): Add OPTION_ADD_SYMBOL.
(copy_options): Add add-symbol.
(copy_usage): Likewise.
(parse_symflags): New function.
(need_sym_before): New function.
(create_new_symbol): New function.
(filter_symbols): Add code to insert new symbols.
(copy_main): Process OPTION_ADD_SYMBOL.
* doc/binutils.texi: Document new feature.
* NEWS: Add note about the new feature.
tests * binutils-all/add-symbol.d: New test.
* binutils-all/objcopy.exp: Run the new test.
@@ -1,3 +1,17 @@ | ||
1 | +2015-10-21 Ronald Hoogenbllon <rhoogenboom@irdeto.com> | |
2 | + | |
3 | + PR binutils/19104 | |
4 | + * objcopy.c (command_line_switch): Add OPTION_ADD_SYMBOL. | |
5 | + (copy_options): Add add-symbol. | |
6 | + (copy_usage): Likewise. | |
7 | + (parse_symflags): New function. | |
8 | + (need_sym_before): New function. | |
9 | + (create_new_symbol): New function. | |
10 | + (filter_symbols): Add code to insert new symbols. | |
11 | + (copy_main): Process OPTION_ADD_SYMBOL. | |
12 | + * doc/binutils.texi: Document new feature. | |
13 | + * NEWS: Add note about the new feature. | |
14 | + | |
1 | 15 | 2015-10-18 Paul Pluzhnikov <ppluzhnikov@google.com> |
2 | 16 | |
3 | 17 | PR binutils/19147 |
@@ -1,5 +1,8 @@ | ||
1 | 1 | -*- text -*- |
2 | 2 | |
3 | +* Add option to objcopy to insert new symbols into a file: | |
4 | + --add-symbol <name>=[<section>:]<value>[,<flags>] | |
5 | + | |
3 | 6 | * Add support for the ARC EM/HS, and ARC600/700 architectures. |
4 | 7 | |
5 | 8 | * Extend objcopy --compress-debug-sections option to support |
@@ -1106,6 +1106,7 @@ objcopy [@option{-F} @var{bfdname}|@option{--target=}@var{bfdname}] | ||
1106 | 1106 | [@option{--localize-symbols=}@var{filename}] |
1107 | 1107 | [@option{--globalize-symbols=}@var{filename}] |
1108 | 1108 | [@option{--weaken-symbols=}@var{filename}] |
1109 | + [@option{--add-symbol} @var{name}=[@var{section}:]@var{value}[,@var{flags}] | |
1109 | 1110 | [@option{--alt-machine-code=}@var{index}] |
1110 | 1111 | [@option{--prefix-symbols=}@var{string}] |
1111 | 1112 | [@option{--prefix-sections=}@var{string}] |
@@ -1504,6 +1505,18 @@ command line. In this case, pass the original section name to | ||
1504 | 1505 | @option{--update-section}, and the original and new section names to |
1505 | 1506 | @option{--rename-section}. |
1506 | 1507 | |
1508 | +@item --add-symbol @var{name}=[@var{section}:]@var{value}[,@var{flags}] | |
1509 | +Add a new symbol named @var{name} while copying the file. This option may be | |
1510 | +specified multiple times. If the @var{section} is given, the symbol will be | |
1511 | +associated with and relative to that section, otherwise it will be an ABS | |
1512 | +symbol. Specifying an undefined section will result in a fatal error. There | |
1513 | +is no check for the value, it will be taken as specified. Symbol flags can | |
1514 | +be specified and not all flags will be meaningful for all object file | |
1515 | +formats. By default, the symbol will be global. The special flag | |
1516 | +'before=@var{othersym}' will insert the new symbol in front of the specified | |
1517 | +@var{othersym}, otherwise the symbol(s) will be added at the end of the | |
1518 | +symbol table in the order they appear. | |
1519 | + | |
1507 | 1520 | @item --rename-section @var{oldname}=@var{newname}[,@var{flags}] |
1508 | 1521 | Rename a section from @var{oldname} to @var{newname}, optionally |
1509 | 1522 | changing the section's flags to @var{flags} in the process. This has |
@@ -50,7 +50,7 @@ static short pe_minor_subsystem_version = -1; | ||
50 | 50 | |
51 | 51 | struct is_specified_symbol_predicate_data |
52 | 52 | { |
53 | - const char *name; | |
53 | + const char * name; | |
54 | 54 | bfd_boolean found; |
55 | 55 | }; |
56 | 56 |
@@ -62,6 +62,16 @@ struct redefine_node | ||
62 | 62 | struct redefine_node *next; |
63 | 63 | }; |
64 | 64 | |
65 | +struct addsym_node | |
66 | +{ | |
67 | + struct addsym_node *next; | |
68 | + char * symdef; | |
69 | + long symval; | |
70 | + flagword flags; | |
71 | + char * section; | |
72 | + char * othersym; | |
73 | +}; | |
74 | + | |
65 | 75 | typedef struct section_rename |
66 | 76 | { |
67 | 77 | const char * old_name; |
@@ -88,26 +98,26 @@ static int deterministic = -1; /* Enable deterministic archives. */ | ||
88 | 98 | static int status = 0; /* Exit status. */ |
89 | 99 | |
90 | 100 | enum strip_action |
91 | - { | |
92 | - STRIP_UNDEF, | |
93 | - STRIP_NONE, /* Don't strip. */ | |
94 | - STRIP_DEBUG, /* Strip all debugger symbols. */ | |
95 | - STRIP_UNNEEDED, /* Strip unnecessary symbols. */ | |
96 | - STRIP_NONDEBUG, /* Strip everything but debug info. */ | |
97 | - STRIP_DWO, /* Strip all DWO info. */ | |
98 | - STRIP_NONDWO, /* Strip everything but DWO info. */ | |
99 | - STRIP_ALL /* Strip all symbols. */ | |
100 | - }; | |
101 | +{ | |
102 | + STRIP_UNDEF, | |
103 | + STRIP_NONE, /* Don't strip. */ | |
104 | + STRIP_DEBUG, /* Strip all debugger symbols. */ | |
105 | + STRIP_UNNEEDED, /* Strip unnecessary symbols. */ | |
106 | + STRIP_NONDEBUG, /* Strip everything but debug info. */ | |
107 | + STRIP_DWO, /* Strip all DWO info. */ | |
108 | + STRIP_NONDWO, /* Strip everything but DWO info. */ | |
109 | + STRIP_ALL /* Strip all symbols. */ | |
110 | +}; | |
101 | 111 | |
102 | 112 | /* Which symbols to remove. */ |
103 | 113 | static enum strip_action strip_symbols = STRIP_UNDEF; |
104 | 114 | |
105 | 115 | enum locals_action |
106 | - { | |
107 | - LOCALS_UNDEF, | |
108 | - LOCALS_START_L, /* Discard locals starting with L. */ | |
109 | - LOCALS_ALL /* Discard all locals. */ | |
110 | - }; | |
116 | +{ | |
117 | + LOCALS_UNDEF, | |
118 | + LOCALS_START_L, /* Discard locals starting with L. */ | |
119 | + LOCALS_ALL /* Discard all locals. */ | |
120 | +}; | |
111 | 121 | |
112 | 122 | /* Which local symbols to remove. Overrides STRIP_ALL. */ |
113 | 123 | static enum locals_action discard_locals; |
@@ -232,6 +242,8 @@ static htab_t globalize_specific_htab = NULL; | ||
232 | 242 | static htab_t keepglobal_specific_htab = NULL; |
233 | 243 | static htab_t weaken_specific_htab = NULL; |
234 | 244 | static struct redefine_node *redefine_sym_list = NULL; |
245 | +static struct addsym_node *add_sym_list = NULL, **add_sym_tail = &add_sym_list; | |
246 | +static int add_symbols = 0; | |
235 | 247 | |
236 | 248 | /* If this is TRUE, we weaken global symbols (set BSF_WEAK). */ |
237 | 249 | static bfd_boolean weaken = FALSE; |
@@ -254,11 +266,11 @@ static int reverse_bytes = 0; | ||
254 | 266 | /* For Coff objects, we may want to allow or disallow long section names, |
255 | 267 | or preserve them where found in the inputs. Debug info relies on them. */ |
256 | 268 | enum long_section_name_handling |
257 | - { | |
258 | - DISABLE, | |
259 | - ENABLE, | |
260 | - KEEP | |
261 | - }; | |
269 | +{ | |
270 | + DISABLE, | |
271 | + ENABLE, | |
272 | + KEEP | |
273 | +}; | |
262 | 274 | |
263 | 275 | /* The default long section handling mode is to preserve them. |
264 | 276 | This is also the only behaviour for 'strip'. */ |
@@ -266,68 +278,69 @@ static enum long_section_name_handling long_section_names = KEEP; | ||
266 | 278 | |
267 | 279 | /* 150 isn't special; it's just an arbitrary non-ASCII char value. */ |
268 | 280 | enum command_line_switch |
269 | - { | |
270 | - OPTION_ADD_SECTION=150, | |
271 | - OPTION_UPDATE_SECTION, | |
272 | - OPTION_DUMP_SECTION, | |
273 | - OPTION_CHANGE_ADDRESSES, | |
274 | - OPTION_CHANGE_LEADING_CHAR, | |
275 | - OPTION_CHANGE_START, | |
276 | - OPTION_CHANGE_SECTION_ADDRESS, | |
277 | - OPTION_CHANGE_SECTION_LMA, | |
278 | - OPTION_CHANGE_SECTION_VMA, | |
279 | - OPTION_CHANGE_WARNINGS, | |
280 | - OPTION_COMPRESS_DEBUG_SECTIONS, | |
281 | - OPTION_DEBUGGING, | |
282 | - OPTION_DECOMPRESS_DEBUG_SECTIONS, | |
283 | - OPTION_GAP_FILL, | |
284 | - OPTION_NO_CHANGE_WARNINGS, | |
285 | - OPTION_PAD_TO, | |
286 | - OPTION_REMOVE_LEADING_CHAR, | |
287 | - OPTION_SET_SECTION_FLAGS, | |
288 | - OPTION_SET_START, | |
289 | - OPTION_STRIP_UNNEEDED, | |
290 | - OPTION_WEAKEN, | |
291 | - OPTION_REDEFINE_SYM, | |
292 | - OPTION_REDEFINE_SYMS, | |
293 | - OPTION_SREC_LEN, | |
294 | - OPTION_SREC_FORCES3, | |
295 | - OPTION_STRIP_SYMBOLS, | |
296 | - OPTION_STRIP_UNNEEDED_SYMBOL, | |
297 | - OPTION_STRIP_UNNEEDED_SYMBOLS, | |
298 | - OPTION_KEEP_SYMBOLS, | |
299 | - OPTION_LOCALIZE_HIDDEN, | |
300 | - OPTION_LOCALIZE_SYMBOLS, | |
301 | - OPTION_LONG_SECTION_NAMES, | |
302 | - OPTION_GLOBALIZE_SYMBOL, | |
303 | - OPTION_GLOBALIZE_SYMBOLS, | |
304 | - OPTION_KEEPGLOBAL_SYMBOLS, | |
305 | - OPTION_WEAKEN_SYMBOLS, | |
306 | - OPTION_RENAME_SECTION, | |
307 | - OPTION_ALT_MACH_CODE, | |
308 | - OPTION_PREFIX_SYMBOLS, | |
309 | - OPTION_PREFIX_SECTIONS, | |
310 | - OPTION_PREFIX_ALLOC_SECTIONS, | |
311 | - OPTION_FORMATS_INFO, | |
312 | - OPTION_ADD_GNU_DEBUGLINK, | |
313 | - OPTION_ONLY_KEEP_DEBUG, | |
314 | - OPTION_KEEP_FILE_SYMBOLS, | |
315 | - OPTION_READONLY_TEXT, | |
316 | - OPTION_WRITABLE_TEXT, | |
317 | - OPTION_PURE, | |
318 | - OPTION_IMPURE, | |
319 | - OPTION_EXTRACT_SYMBOL, | |
320 | - OPTION_REVERSE_BYTES, | |
321 | - OPTION_FILE_ALIGNMENT, | |
322 | - OPTION_HEAP, | |
323 | - OPTION_IMAGE_BASE, | |
324 | - OPTION_SECTION_ALIGNMENT, | |
325 | - OPTION_STACK, | |
326 | - OPTION_INTERLEAVE_WIDTH, | |
327 | - OPTION_SUBSYSTEM, | |
328 | - OPTION_EXTRACT_DWO, | |
329 | - OPTION_STRIP_DWO | |
330 | - }; | |
281 | +{ | |
282 | + OPTION_ADD_SECTION=150, | |
283 | + OPTION_ADD_GNU_DEBUGLINK, | |
284 | + OPTION_ADD_SYMBOL, | |
285 | + OPTION_ALT_MACH_CODE, | |
286 | + OPTION_CHANGE_ADDRESSES, | |
287 | + OPTION_CHANGE_LEADING_CHAR, | |
288 | + OPTION_CHANGE_SECTION_ADDRESS, | |
289 | + OPTION_CHANGE_SECTION_LMA, | |
290 | + OPTION_CHANGE_SECTION_VMA, | |
291 | + OPTION_CHANGE_START, | |
292 | + OPTION_CHANGE_WARNINGS, | |
293 | + OPTION_COMPRESS_DEBUG_SECTIONS, | |
294 | + OPTION_DEBUGGING, | |
295 | + OPTION_DECOMPRESS_DEBUG_SECTIONS, | |
296 | + OPTION_DUMP_SECTION, | |
297 | + OPTION_EXTRACT_DWO, | |
298 | + OPTION_EXTRACT_SYMBOL, | |
299 | + OPTION_FILE_ALIGNMENT, | |
300 | + OPTION_FORMATS_INFO, | |
301 | + OPTION_GAP_FILL, | |
302 | + OPTION_GLOBALIZE_SYMBOL, | |
303 | + OPTION_GLOBALIZE_SYMBOLS, | |
304 | + OPTION_HEAP, | |
305 | + OPTION_IMAGE_BASE, | |
306 | + OPTION_IMPURE, | |
307 | + OPTION_INTERLEAVE_WIDTH, | |
308 | + OPTION_KEEPGLOBAL_SYMBOLS, | |
309 | + OPTION_KEEP_FILE_SYMBOLS, | |
310 | + OPTION_KEEP_SYMBOLS, | |
311 | + OPTION_LOCALIZE_HIDDEN, | |
312 | + OPTION_LOCALIZE_SYMBOLS, | |
313 | + OPTION_LONG_SECTION_NAMES, | |
314 | + OPTION_NO_CHANGE_WARNINGS, | |
315 | + OPTION_ONLY_KEEP_DEBUG, | |
316 | + OPTION_PAD_TO, | |
317 | + OPTION_PREFIX_ALLOC_SECTIONS, | |
318 | + OPTION_PREFIX_SECTIONS, | |
319 | + OPTION_PREFIX_SYMBOLS, | |
320 | + OPTION_PURE, | |
321 | + OPTION_READONLY_TEXT, | |
322 | + OPTION_REDEFINE_SYM, | |
323 | + OPTION_REDEFINE_SYMS, | |
324 | + OPTION_REMOVE_LEADING_CHAR, | |
325 | + OPTION_RENAME_SECTION, | |
326 | + OPTION_REVERSE_BYTES, | |
327 | + OPTION_SECTION_ALIGNMENT, | |
328 | + OPTION_SET_SECTION_FLAGS, | |
329 | + OPTION_SET_START, | |
330 | + OPTION_SREC_FORCES3, | |
331 | + OPTION_SREC_LEN, | |
332 | + OPTION_STACK, | |
333 | + OPTION_STRIP_DWO, | |
334 | + OPTION_STRIP_SYMBOLS, | |
335 | + OPTION_STRIP_UNNEEDED, | |
336 | + OPTION_STRIP_UNNEEDED_SYMBOL, | |
337 | + OPTION_STRIP_UNNEEDED_SYMBOLS, | |
338 | + OPTION_SUBSYSTEM, | |
339 | + OPTION_UPDATE_SECTION, | |
340 | + OPTION_WEAKEN, | |
341 | + OPTION_WEAKEN_SYMBOLS, | |
342 | + OPTION_WRITABLE_TEXT | |
343 | +}; | |
331 | 344 | |
332 | 345 | /* Options to handle if running as "strip". */ |
333 | 346 |
@@ -345,16 +358,16 @@ static struct option strip_options[] = | ||
345 | 358 | {"keep-file-symbols", no_argument, 0, OPTION_KEEP_FILE_SYMBOLS}, |
346 | 359 | {"keep-symbol", required_argument, 0, 'K'}, |
347 | 360 | {"only-keep-debug", no_argument, 0, OPTION_ONLY_KEEP_DEBUG}, |
361 | + {"output-file", required_argument, 0, 'o'}, | |
348 | 362 | {"output-format", required_argument, 0, 'O'}, /* Obsolete */ |
349 | 363 | {"output-target", required_argument, 0, 'O'}, |
350 | - {"output-file", required_argument, 0, 'o'}, | |
351 | 364 | {"preserve-dates", no_argument, 0, 'p'}, |
352 | 365 | {"remove-section", required_argument, 0, 'R'}, |
353 | 366 | {"strip-all", no_argument, 0, 's'}, |
354 | 367 | {"strip-debug", no_argument, 0, 'S'}, |
355 | 368 | {"strip-dwo", no_argument, 0, OPTION_STRIP_DWO}, |
356 | - {"strip-unneeded", no_argument, 0, OPTION_STRIP_UNNEEDED}, | |
357 | 369 | {"strip-symbol", required_argument, 0, 'N'}, |
370 | + {"strip-unneeded", no_argument, 0, OPTION_STRIP_UNNEEDED}, | |
358 | 371 | {"target", required_argument, 0, 'F'}, |
359 | 372 | {"verbose", no_argument, 0, 'v'}, |
360 | 373 | {"version", no_argument, 0, 'V'}, |
@@ -368,10 +381,10 @@ static struct option copy_options[] = | ||
368 | 381 | { |
369 | 382 | {"add-gnu-debuglink", required_argument, 0, OPTION_ADD_GNU_DEBUGLINK}, |
370 | 383 | {"add-section", required_argument, 0, OPTION_ADD_SECTION}, |
371 | - {"update-section", required_argument, 0, OPTION_UPDATE_SECTION}, | |
384 | + {"add-symbol", required_argument, 0, OPTION_ADD_SYMBOL}, | |
385 | + {"adjust-section-vma", required_argument, 0, OPTION_CHANGE_SECTION_ADDRESS}, | |
372 | 386 | {"adjust-start", required_argument, 0, OPTION_CHANGE_START}, |
373 | 387 | {"adjust-vma", required_argument, 0, OPTION_CHANGE_ADDRESSES}, |
374 | - {"adjust-section-vma", required_argument, 0, OPTION_CHANGE_SECTION_ADDRESS}, | |
375 | 388 | {"adjust-warnings", no_argument, 0, OPTION_CHANGE_WARNINGS}, |
376 | 389 | {"alt-machine-code", required_argument, 0, OPTION_ALT_MACH_CODE}, |
377 | 390 | {"binary-architecture", required_argument, 0, 'B'}, |
@@ -393,11 +406,14 @@ static struct option copy_options[] = | ||
393 | 406 | {"enable-deterministic-archives", no_argument, 0, 'D'}, |
394 | 407 | {"extract-dwo", no_argument, 0, OPTION_EXTRACT_DWO}, |
395 | 408 | {"extract-symbol", no_argument, 0, OPTION_EXTRACT_SYMBOL}, |
409 | + {"file-alignment", required_argument, 0, OPTION_FILE_ALIGNMENT}, | |
396 | 410 | {"format", required_argument, 0, 'F'}, /* Obsolete */ |
397 | 411 | {"gap-fill", required_argument, 0, OPTION_GAP_FILL}, |
398 | 412 | {"globalize-symbol", required_argument, 0, OPTION_GLOBALIZE_SYMBOL}, |
399 | 413 | {"globalize-symbols", required_argument, 0, OPTION_GLOBALIZE_SYMBOLS}, |
414 | + {"heap", required_argument, 0, OPTION_HEAP}, | |
400 | 415 | {"help", no_argument, 0, 'h'}, |
416 | + {"image-base", required_argument, 0 , OPTION_IMAGE_BASE}, | |
401 | 417 | {"impure", no_argument, 0, OPTION_IMPURE}, |
402 | 418 | {"info", no_argument, 0, OPTION_FORMATS_INFO}, |
403 | 419 | {"input-format", required_argument, 0, 'I'}, /* Obsolete */ |
@@ -420,9 +436,9 @@ static struct option copy_options[] = | ||
420 | 436 | {"output-format", required_argument, 0, 'O'}, /* Obsolete */ |
421 | 437 | {"output-target", required_argument, 0, 'O'}, |
422 | 438 | {"pad-to", required_argument, 0, OPTION_PAD_TO}, |
423 | - {"prefix-symbols", required_argument, 0, OPTION_PREFIX_SYMBOLS}, | |
424 | - {"prefix-sections", required_argument, 0, OPTION_PREFIX_SECTIONS}, | |
425 | 439 | {"prefix-alloc-sections", required_argument, 0, OPTION_PREFIX_ALLOC_SECTIONS}, |
440 | + {"prefix-sections", required_argument, 0, OPTION_PREFIX_SECTIONS}, | |
441 | + {"prefix-symbols", required_argument, 0, OPTION_PREFIX_SYMBOLS}, | |
426 | 442 | {"preserve-dates", no_argument, 0, 'p'}, |
427 | 443 | {"pure", no_argument, 0, OPTION_PURE}, |
428 | 444 | {"readonly-text", no_argument, 0, OPTION_READONLY_TEXT}, |
@@ -432,19 +448,23 @@ static struct option copy_options[] = | ||
432 | 448 | {"remove-section", required_argument, 0, 'R'}, |
433 | 449 | {"rename-section", required_argument, 0, OPTION_RENAME_SECTION}, |
434 | 450 | {"reverse-bytes", required_argument, 0, OPTION_REVERSE_BYTES}, |
451 | + {"section-alignment", required_argument, 0, OPTION_SECTION_ALIGNMENT}, | |
435 | 452 | {"set-section-flags", required_argument, 0, OPTION_SET_SECTION_FLAGS}, |
436 | 453 | {"set-start", required_argument, 0, OPTION_SET_START}, |
437 | - {"srec-len", required_argument, 0, OPTION_SREC_LEN}, | |
438 | 454 | {"srec-forceS3", no_argument, 0, OPTION_SREC_FORCES3}, |
455 | + {"srec-len", required_argument, 0, OPTION_SREC_LEN}, | |
456 | + {"stack", required_argument, 0, OPTION_STACK}, | |
439 | 457 | {"strip-all", no_argument, 0, 'S'}, |
440 | 458 | {"strip-debug", no_argument, 0, 'g'}, |
441 | 459 | {"strip-dwo", no_argument, 0, OPTION_STRIP_DWO}, |
460 | + {"strip-symbol", required_argument, 0, 'N'}, | |
461 | + {"strip-symbols", required_argument, 0, OPTION_STRIP_SYMBOLS}, | |
442 | 462 | {"strip-unneeded", no_argument, 0, OPTION_STRIP_UNNEEDED}, |
443 | 463 | {"strip-unneeded-symbol", required_argument, 0, OPTION_STRIP_UNNEEDED_SYMBOL}, |
444 | 464 | {"strip-unneeded-symbols", required_argument, 0, OPTION_STRIP_UNNEEDED_SYMBOLS}, |
445 | - {"strip-symbol", required_argument, 0, 'N'}, | |
446 | - {"strip-symbols", required_argument, 0, OPTION_STRIP_SYMBOLS}, | |
465 | + {"subsystem", required_argument, 0, OPTION_SUBSYSTEM}, | |
447 | 466 | {"target", required_argument, 0, 'F'}, |
467 | + {"update-section", required_argument, 0, OPTION_UPDATE_SECTION}, | |
448 | 468 | {"verbose", no_argument, 0, 'v'}, |
449 | 469 | {"version", no_argument, 0, 'V'}, |
450 | 470 | {"weaken", no_argument, 0, OPTION_WEAKEN}, |
@@ -452,12 +472,6 @@ static struct option copy_options[] = | ||
452 | 472 | {"weaken-symbols", required_argument, 0, OPTION_WEAKEN_SYMBOLS}, |
453 | 473 | {"wildcard", no_argument, 0, 'w'}, |
454 | 474 | {"writable-text", no_argument, 0, OPTION_WRITABLE_TEXT}, |
455 | - {"file-alignment", required_argument, 0, OPTION_FILE_ALIGNMENT}, | |
456 | - {"heap", required_argument, 0, OPTION_HEAP}, | |
457 | - {"image-base", required_argument, 0 , OPTION_IMAGE_BASE}, | |
458 | - {"section-alignment", required_argument, 0, OPTION_SECTION_ALIGNMENT}, | |
459 | - {"stack", required_argument, 0, OPTION_STACK}, | |
460 | - {"subsystem", required_argument, 0, OPTION_SUBSYSTEM}, | |
461 | 475 | {0, no_argument, 0, 0} |
462 | 476 | }; |
463 | 477 |
@@ -585,6 +599,7 @@ copy_usage (FILE *stream, int exit_status) | ||
585 | 599 | --globalize-symbols <file> --globalize-symbol for all in <file>\n\ |
586 | 600 | --keep-global-symbols <file> -G for all symbols listed in <file>\n\ |
587 | 601 | --weaken-symbols <file> -W for all symbols listed in <file>\n\ |
602 | + --add-symbol <name>=[<section>:]<value>[,<flags>] Add a symbol\n\ | |
588 | 603 | --alt-machine-code <index> Use the target's <index>'th alternative machine\n\ |
589 | 604 | --writable-text Mark the output text as writable\n\ |
590 | 605 | --readonly-text Make the output text write protected\n\ |
@@ -727,6 +742,78 @@ parse_flags (const char *s) | ||
727 | 742 | return ret; |
728 | 743 | } |
729 | 744 | |
745 | +/* Parse symbol flags into a flagword, with a fatal error if the | |
746 | + string can't be parsed. */ | |
747 | + | |
748 | +static flagword | |
749 | +parse_symflags (const char *s, char **other) | |
750 | +{ | |
751 | + flagword ret; | |
752 | + const char *snext; | |
753 | + int len; | |
754 | + | |
755 | + ret = BSF_NO_FLAGS; | |
756 | + | |
757 | + do | |
758 | + { | |
759 | + snext = strchr (s, ','); | |
760 | + if (snext == NULL) | |
761 | + len = strlen (s); | |
762 | + else | |
763 | + { | |
764 | + len = snext - s; | |
765 | + ++snext; | |
766 | + } | |
767 | + | |
768 | +#define PARSE_FLAG(fname,fval) \ | |
769 | + else if (len == (int) sizeof fname - 1 && strncasecmp (fname, s, len) == 0) \ | |
770 | + ret |= fval | |
771 | + | |
772 | +#define PARSE_OTHER(fname,fval) \ | |
773 | + else if (len >= (int) sizeof fname && strncasecmp (fname, s, sizeof fname - 1) == 0) \ | |
774 | + fval = strndup (s + sizeof fname - 1, len - sizeof fname + 1) | |
775 | + | |
776 | + if (0) ; | |
777 | + PARSE_FLAG ("local", BSF_LOCAL); | |
778 | + PARSE_FLAG ("global", BSF_GLOBAL); | |
779 | + PARSE_FLAG ("export", BSF_EXPORT); | |
780 | + PARSE_FLAG ("debug", BSF_DEBUGGING); | |
781 | + PARSE_FLAG ("function", BSF_FUNCTION); | |
782 | + PARSE_FLAG ("weak", BSF_WEAK); | |
783 | + PARSE_FLAG ("section", BSF_SECTION_SYM); | |
784 | + PARSE_FLAG ("constructor", BSF_CONSTRUCTOR); | |
785 | + PARSE_FLAG ("warning", BSF_WARNING); | |
786 | + PARSE_FLAG ("indirect", BSF_INDIRECT); | |
787 | + PARSE_FLAG ("file", BSF_FILE); | |
788 | + PARSE_FLAG ("object", BSF_OBJECT); | |
789 | + PARSE_FLAG ("synthetic", BSF_SYNTHETIC); | |
790 | + PARSE_FLAG ("indirect-function", BSF_GNU_INDIRECT_FUNCTION | BSF_FUNCTION); | |
791 | + PARSE_FLAG ("unique-object", BSF_GNU_UNIQUE | BSF_OBJECT); | |
792 | + PARSE_OTHER ("before=", *other); | |
793 | + | |
794 | +#undef PARSE_FLAG | |
795 | +#undef PARSE_OTHER | |
796 | + else | |
797 | + { | |
798 | + char *copy; | |
799 | + | |
800 | + copy = (char *) xmalloc (len + 1); | |
801 | + strncpy (copy, s, len); | |
802 | + copy[len] = '\0'; | |
803 | + non_fatal (_("unrecognized symbol flag `%s'"), copy); | |
804 | + fatal (_("supported flags: %s"), | |
805 | + "local, global, export, debug, function, weak, section, " | |
806 | + "constructor, warning, indirect, file, object, synthetic, " | |
807 | + "indirect-function, unique-object, before=<othersym>"); | |
808 | + } | |
809 | + | |
810 | + s = snext; | |
811 | + } | |
812 | + while (s != NULL); | |
813 | + | |
814 | + return ret; | |
815 | +} | |
816 | + | |
730 | 817 | /* Find and optionally add an entry in the change_sections list. |
731 | 818 | |
732 | 819 | We need to be careful in how we match section names because of the support |
@@ -1213,6 +1300,49 @@ is_hidden_symbol (asymbol *sym) | ||
1213 | 1300 | return FALSE; |
1214 | 1301 | } |
1215 | 1302 | |
1303 | +static bfd_boolean | |
1304 | +need_sym_before (struct addsym_node **node, const char *sym) | |
1305 | +{ | |
1306 | + int count; | |
1307 | + struct addsym_node *ptr = add_sym_list; | |
1308 | + | |
1309 | + /* 'othersym' symbols are at the front of the list. */ | |
1310 | + for (count = 0; count < add_symbols; count++) | |
1311 | + { | |
1312 | + if (!ptr->othersym) | |
1313 | + break; | |
1314 | + else if (strcmp (ptr->othersym, sym) == 0) | |
1315 | + { | |
1316 | + free (ptr->othersym); | |
1317 | + ptr->othersym = ""; /* Empty name is hopefully never a valid symbol name. */ | |
1318 | + *node = ptr; | |
1319 | + return TRUE; | |
1320 | + } | |
1321 | + ptr = ptr->next; | |
1322 | + } | |
1323 | + return FALSE; | |
1324 | +} | |
1325 | + | |
1326 | +static asymbol * | |
1327 | +create_new_symbol (struct addsym_node *ptr, bfd *obfd) | |
1328 | +{ | |
1329 | + asymbol *sym = bfd_make_empty_symbol(obfd); | |
1330 | + | |
1331 | + bfd_asymbol_name(sym) = ptr->symdef; | |
1332 | + sym->value = ptr->symval; | |
1333 | + sym->flags = ptr->flags; | |
1334 | + if (ptr->section) | |
1335 | + { | |
1336 | + asection *sec = bfd_get_section_by_name (obfd, ptr->section); | |
1337 | + if (!sec) | |
1338 | + fatal (_("Section %s not found"), ptr->section); | |
1339 | + sym->section = sec; | |
1340 | + } | |
1341 | + else | |
1342 | + sym->section = bfd_abs_section_ptr; | |
1343 | + return sym; | |
1344 | +} | |
1345 | + | |
1216 | 1346 | /* Choose which symbol entries to copy; put the result in OSYMS. |
1217 | 1347 | We don't copy in place, because that confuses the relocs. |
1218 | 1348 | Return the number of symbols to print. */ |
@@ -1238,6 +1368,14 @@ filter_symbols (bfd *abfd, bfd *obfd, asymbol **osyms, | ||
1238 | 1368 | |
1239 | 1369 | undefined = bfd_is_und_section (bfd_get_section (sym)); |
1240 | 1370 | |
1371 | + if (add_sym_list) | |
1372 | + { | |
1373 | + struct addsym_node *ptr; | |
1374 | + | |
1375 | + if (need_sym_before (&ptr, name)) | |
1376 | + to[dst_count++] = create_new_symbol (ptr, obfd); | |
1377 | + } | |
1378 | + | |
1241 | 1379 | if (redefine_sym_list) |
1242 | 1380 | { |
1243 | 1381 | char *old_name, *new_name; |
@@ -1394,6 +1532,23 @@ filter_symbols (bfd *abfd, bfd *obfd, asymbol **osyms, | ||
1394 | 1532 | to[dst_count++] = sym; |
1395 | 1533 | } |
1396 | 1534 | } |
1535 | + if (add_sym_list) | |
1536 | + { | |
1537 | + struct addsym_node *ptr = add_sym_list; | |
1538 | + | |
1539 | + for (src_count = 0; src_count < add_symbols; src_count++) | |
1540 | + { | |
1541 | + if (ptr->othersym) | |
1542 | + { | |
1543 | + if (strcmp (ptr->othersym, "")) | |
1544 | + fatal (_("'before=%s' not found"), ptr->othersym); | |
1545 | + } | |
1546 | + else | |
1547 | + to[dst_count++] = create_new_symbol (ptr, obfd); | |
1548 | + | |
1549 | + ptr = ptr->next; | |
1550 | + } | |
1551 | + } | |
1397 | 1552 | |
1398 | 1553 | to[dst_count] = NULL; |
1399 | 1554 |
@@ -2179,7 +2334,8 @@ copy_object (bfd *ibfd, bfd *obfd, const bfd_arch_info_type *input_arch) | ||
2179 | 2334 | || change_leading_char |
2180 | 2335 | || remove_leading_char |
2181 | 2336 | || redefine_sym_list |
2182 | - || weaken) | |
2337 | + || weaken | |
2338 | + || add_symbols) | |
2183 | 2339 | { |
2184 | 2340 | /* Mark symbols used in output relocations so that they |
2185 | 2341 | are kept, even if they are local labels or static symbols. |
@@ -2193,7 +2349,7 @@ copy_object (bfd *ibfd, bfd *obfd, const bfd_arch_info_type *input_arch) | ||
2193 | 2349 | bfd_map_over_sections (ibfd, |
2194 | 2350 | mark_symbols_used_in_relocations, |
2195 | 2351 | isympp); |
2196 | - osympp = (asymbol **) xmalloc ((symcount + 1) * sizeof (asymbol *)); | |
2352 | + osympp = (asymbol **) xmalloc ((symcount + add_symbols + 1) * sizeof (asymbol *)); | |
2197 | 2353 | symcount = filter_symbols (ibfd, obfd, osympp, isympp, symcount); |
2198 | 2354 | } |
2199 | 2355 |
@@ -3920,6 +4076,53 @@ copy_main (int argc, char *argv[]) | ||
3920 | 4076 | "--dump-section"); |
3921 | 4077 | break; |
3922 | 4078 | |
4079 | + case OPTION_ADD_SYMBOL: | |
4080 | + { | |
4081 | + char *s, *t; | |
4082 | + struct addsym_node *newsym = xmalloc (sizeof *newsym); | |
4083 | + | |
4084 | + newsym->next = NULL; | |
4085 | + s = strchr (optarg, '='); | |
4086 | + if (s == NULL) | |
4087 | + fatal (_("bad format for %s"), "--add-symbol"); | |
4088 | + t = strchr (s + 1, ':'); | |
4089 | + | |
4090 | + newsym->symdef = strndup (optarg, s - optarg); | |
4091 | + if (t) | |
4092 | + { | |
4093 | + newsym->section = strndup (s + 1, t - (s + 1)); | |
4094 | + newsym->symval = strtol (t + 1, NULL, 0); | |
4095 | + } | |
4096 | + else | |
4097 | + { | |
4098 | + newsym->section = NULL; | |
4099 | + newsym->symval = strtol (s + 1, NULL, 0); | |
4100 | + t = s; | |
4101 | + } | |
4102 | + | |
4103 | + t = strchr (t + 1, ','); | |
4104 | + if (t) | |
4105 | + newsym->flags = parse_symflags (t+1, &newsym->othersym); | |
4106 | + else | |
4107 | + newsym->flags = BSF_GLOBAL; | |
4108 | + | |
4109 | + /* Keep 'othersym' symbols at the front of the list. */ | |
4110 | + if (newsym->othersym) | |
4111 | + { | |
4112 | + newsym->next = add_sym_list; | |
4113 | + if (!add_sym_list) | |
4114 | + add_sym_tail = &newsym->next; | |
4115 | + add_sym_list = newsym; | |
4116 | + } | |
4117 | + else | |
4118 | + { | |
4119 | + *add_sym_tail = newsym; | |
4120 | + add_sym_tail = &newsym->next; | |
4121 | + } | |
4122 | + add_symbols++; | |
4123 | + } | |
4124 | + break; | |
4125 | + | |
3923 | 4126 | case OPTION_CHANGE_START: |
3924 | 4127 | change_start = parse_vma (optarg, "--change-start"); |
3925 | 4128 | break; |
@@ -1,3 +1,9 @@ | ||
1 | +2015-10-21 Ronald Hoogenbllon <rhoogenboom@irdeto.com> | |
2 | + | |
3 | + PR binutils/19104 | |
4 | + * binutils-all/add-symbol.d: New test. | |
5 | + * binutils-all/objcopy.exp: Run the new test. | |
6 | + | |
1 | 7 | 2015-10-15 Alan Modra <amodra@gmail.com> |
2 | 8 | |
3 | 9 | * binutils-all/objcopy.exp: Delete trailing whitespace. Use |
@@ -0,0 +1,16 @@ | ||
1 | +#PROG: objcopy | |
2 | +#name: objcopy add-symbol | |
3 | +#source: symbols.s | |
4 | +#objcopy: --add-symbol NEW=0x1234 --add-symbol NEW_DATA=.data:0x4321,local | |
5 | +#objdump: --syms | |
6 | +# MIPS targets swap the order of the symbols in the output. | |
7 | +#not-target: mips-*-* tx39-*-* | |
8 | + | |
9 | +.*: +file format .* | |
10 | + | |
11 | +SYMBOL TABLE: | |
12 | +#... | |
13 | +0+04321 l[ ]+.data[ ]+0+00 NEW_DATA | |
14 | +#... | |
15 | +0+01234 g[ ]+\*ABS\*[ ]+0+00 NEW | |
16 | +#pass |
@@ -1097,6 +1097,7 @@ if [is_elf_format] { | ||
1097 | 1097 | run_dump_test "testranges-ia64" |
1098 | 1098 | |
1099 | 1099 | run_dump_test "add-section" |
1100 | + run_dump_test "add-symbol" | |
1100 | 1101 | run_dump_test "add-empty-section" |
1101 | 1102 | |
1102 | 1103 | run_dump_test "exclude-1a" |