| OLD | NEW |
| 1 /* Object file "section" support for the BFD library. | 1 /* Object file "section" support for the BFD library. |
| 2 Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, | 2 Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, |
| 3 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 | 3 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, |
| 4 2012 |
| 4 Free Software Foundation, Inc. | 5 Free Software Foundation, Inc. |
| 5 Written by Cygnus Support. | 6 Written by Cygnus Support. |
| 6 | 7 |
| 7 This file is part of BFD, the Binary File Descriptor library. | 8 This file is part of BFD, the Binary File Descriptor library. |
| 8 | 9 |
| 9 This program is free software; you can redistribute it and/or modify | 10 This program is free software; you can redistribute it and/or modify |
| 10 it under the terms of the GNU General Public License as published by | 11 it under the terms of the GNU General Public License as published by |
| 11 the Free Software Foundation; either version 3 of the License, or | 12 the Free Software Foundation; either version 3 of the License, or |
| 12 (at your option) any later version. | 13 (at your option) any later version. |
| 13 | 14 |
| (...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 375 .#define COMPRESS_SECTION_DONE 1 | 376 .#define COMPRESS_SECTION_DONE 1 |
| 376 .#define DECOMPRESS_SECTION_SIZED 2 | 377 .#define DECOMPRESS_SECTION_SIZED 2 |
| 377 . | 378 . |
| 378 . {* The following flags are used by the ELF linker. *} | 379 . {* The following flags are used by the ELF linker. *} |
| 379 . | 380 . |
| 380 . {* Mark sections which have been allocated to segments. *} | 381 . {* Mark sections which have been allocated to segments. *} |
| 381 . unsigned int segment_mark : 1; | 382 . unsigned int segment_mark : 1; |
| 382 . | 383 . |
| 383 . {* Type of sec_info information. *} | 384 . {* Type of sec_info information. *} |
| 384 . unsigned int sec_info_type:3; | 385 . unsigned int sec_info_type:3; |
| 385 .#define ELF_INFO_TYPE_NONE 0 | 386 .#define SEC_INFO_TYPE_NONE 0 |
| 386 .#define ELF_INFO_TYPE_STABS 1 | 387 .#define SEC_INFO_TYPE_STABS 1 |
| 387 .#define ELF_INFO_TYPE_MERGE 2 | 388 .#define SEC_INFO_TYPE_MERGE 2 |
| 388 .#define ELF_INFO_TYPE_EH_FRAME 3 | 389 .#define SEC_INFO_TYPE_EH_FRAME 3 |
| 389 .#define ELF_INFO_TYPE_JUST_SYMS 4 | 390 .#define SEC_INFO_TYPE_JUST_SYMS 4 |
| 390 . | 391 . |
| 391 . {* Nonzero if this section uses RELA relocations, rather than REL. *} | 392 . {* Nonzero if this section uses RELA relocations, rather than REL. *} |
| 392 . unsigned int use_rela_p:1; | 393 . unsigned int use_rela_p:1; |
| 393 . | 394 . |
| 394 . {* Bits used by various backends. The generic code doesn't touch | 395 . {* Bits used by various backends. The generic code doesn't touch |
| 395 . these fields. *} | 396 . these fields. *} |
| 396 . | 397 . |
| 397 . unsigned int sec_flg0:1; | 398 . unsigned int sec_flg0:1; |
| 398 . unsigned int sec_flg1:1; | 399 . unsigned int sec_flg1:1; |
| 399 . unsigned int sec_flg2:1; | 400 . unsigned int sec_flg2:1; |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 509 . | 510 . |
| 510 . void *used_by_bfd; | 511 . void *used_by_bfd; |
| 511 . | 512 . |
| 512 . {* If this is a constructor section then here is a list of the | 513 . {* If this is a constructor section then here is a list of the |
| 513 . relocations created to relocate items within it. *} | 514 . relocations created to relocate items within it. *} |
| 514 . struct relent_chain *constructor_chain; | 515 . struct relent_chain *constructor_chain; |
| 515 . | 516 . |
| 516 . {* The BFD which owns the section. *} | 517 . {* The BFD which owns the section. *} |
| 517 . bfd *owner; | 518 . bfd *owner; |
| 518 . | 519 . |
| 519 . {* INPUT_SECTION_FLAGS if specified in the linker script. *} | |
| 520 . struct flag_info *section_flag_info; | |
| 521 . | |
| 522 . {* A symbol which points at this section only. *} | 520 . {* A symbol which points at this section only. *} |
| 523 . struct bfd_symbol *symbol; | 521 . struct bfd_symbol *symbol; |
| 524 . struct bfd_symbol **symbol_ptr_ptr; | 522 . struct bfd_symbol **symbol_ptr_ptr; |
| 525 . | 523 . |
| 526 . {* Early in the link process, map_head and map_tail are used to build | 524 . {* Early in the link process, map_head and map_tail are used to build |
| 527 . a list of input sections attached to an output section. Later, | 525 . a list of input sections attached to an output section. Later, |
| 528 . output sections use these fields for a list of bfd_link_order | 526 . output sections use these fields for a list of bfd_link_order |
| 529 . structs. *} | 527 . structs. *} |
| 530 . union { | 528 . union { |
| 531 . struct bfd_link_order *link_order; | 529 . struct bfd_link_order *link_order; |
| 532 . struct bfd_section *s; | 530 . struct bfd_section *s; |
| 533 . } map_head, map_tail; | 531 . } map_head, map_tail; |
| 534 .} asection; | 532 .} asection; |
| 535 . | 533 . |
| 536 .{* Relax table contains information about instructions which can | 534 .{* Relax table contains information about instructions which can |
| 537 . be removed by relaxation -- replacing a long address with a | 535 . be removed by relaxation -- replacing a long address with a |
| 538 . short address. *} | 536 . short address. *} |
| 539 .struct relax_table { | 537 .struct relax_table { |
| 540 . {* Address where bytes may be deleted. *} | 538 . {* Address where bytes may be deleted. *} |
| 541 . bfd_vma addr; | 539 . bfd_vma addr; |
| 542 . | 540 . |
| 543 . {* Number of bytes to be deleted. *} | 541 . {* Number of bytes to be deleted. *} |
| 544 . int size; | 542 . int size; |
| 545 .}; | 543 .}; |
| 546 . | 544 . |
| 547 .{* These sections are global, and are managed by BFD. The application | 545 .{* These sections are global, and are managed by BFD. The application |
| 548 . and target back end are not permitted to change the values in | 546 . and target back end are not permitted to change the values in |
| 549 . these sections. New code should use the section_ptr macros rather | 547 . these sections. *} |
| 550 . than referring directly to the const sections. The const sections | 548 .extern asection std_section[4]; |
| 551 . may eventually vanish. *} | 549 . |
| 552 .#define BFD_ABS_SECTION_NAME "*ABS*" | 550 .#define BFD_ABS_SECTION_NAME "*ABS*" |
| 553 .#define BFD_UND_SECTION_NAME "*UND*" | 551 .#define BFD_UND_SECTION_NAME "*UND*" |
| 554 .#define BFD_COM_SECTION_NAME "*COM*" | 552 .#define BFD_COM_SECTION_NAME "*COM*" |
| 555 .#define BFD_IND_SECTION_NAME "*IND*" | 553 .#define BFD_IND_SECTION_NAME "*IND*" |
| 556 . | 554 . |
| 557 .{* The absolute section. *} | 555 .{* Pointer to the common section. *} |
| 558 .extern asection bfd_abs_section; | 556 .#define bfd_com_section_ptr (&std_section[0]) |
| 559 .#define bfd_abs_section_ptr ((asection *) &bfd_abs_section) | 557 .{* Pointer to the undefined section. *} |
| 558 .#define bfd_und_section_ptr (&std_section[1]) |
| 559 .{* Pointer to the absolute section. *} |
| 560 .#define bfd_abs_section_ptr (&std_section[2]) |
| 561 .{* Pointer to the indirect section. *} |
| 562 .#define bfd_ind_section_ptr (&std_section[3]) |
| 563 . |
| 564 .#define bfd_is_und_section(sec) ((sec) == bfd_und_section_ptr) |
| 560 .#define bfd_is_abs_section(sec) ((sec) == bfd_abs_section_ptr) | 565 .#define bfd_is_abs_section(sec) ((sec) == bfd_abs_section_ptr) |
| 561 .{* Pointer to the undefined section. *} | |
| 562 .extern asection bfd_und_section; | |
| 563 .#define bfd_und_section_ptr ((asection *) &bfd_und_section) | |
| 564 .#define bfd_is_und_section(sec) ((sec) == bfd_und_section_ptr) | |
| 565 .{* Pointer to the common section. *} | |
| 566 .extern asection bfd_com_section; | |
| 567 .#define bfd_com_section_ptr ((asection *) &bfd_com_section) | |
| 568 .{* Pointer to the indirect section. *} | |
| 569 .extern asection bfd_ind_section; | |
| 570 .#define bfd_ind_section_ptr ((asection *) &bfd_ind_section) | |
| 571 .#define bfd_is_ind_section(sec) ((sec) == bfd_ind_section_ptr) | 566 .#define bfd_is_ind_section(sec) ((sec) == bfd_ind_section_ptr) |
| 572 . | 567 . |
| 573 .#define bfd_is_const_section(SEC) \ | 568 .#define bfd_is_const_section(SEC) \ |
| 574 . ( ((SEC) == bfd_abs_section_ptr) \ | 569 . ( ((SEC) == bfd_abs_section_ptr) \ |
| 575 . || ((SEC) == bfd_und_section_ptr) \ | 570 . || ((SEC) == bfd_und_section_ptr) \ |
| 576 . || ((SEC) == bfd_com_section_ptr) \ | 571 . || ((SEC) == bfd_com_section_ptr) \ |
| 577 . || ((SEC) == bfd_ind_section_ptr)) | 572 . || ((SEC) == bfd_ind_section_ptr)) |
| 578 . | 573 . |
| 579 .{* Macros to handle insertion and deletion of a bfd's sections. These | 574 .{* Macros to handle insertion and deletion of a bfd's sections. These |
| 580 . only handle the list pointers, ie. do not adjust section_count, | 575 . only handle the list pointers, ie. do not adjust section_count, |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 675 . \ | 670 . \ |
| 676 . {* segment_mark, sec_info_type, use_rela_p, *} \ | 671 . {* segment_mark, sec_info_type, use_rela_p, *} \ |
| 677 . 0, 0, 0, \ | 672 . 0, 0, 0, \ |
| 678 . \ | 673 . \ |
| 679 . {* sec_flg0, sec_flg1, sec_flg2, sec_flg3, sec_flg4, sec_flg5, *} \ | 674 . {* sec_flg0, sec_flg1, sec_flg2, sec_flg3, sec_flg4, sec_flg5, *} \ |
| 680 . 0, 0, 0, 0, 0, 0, \ | 675 . 0, 0, 0, 0, 0, 0, \ |
| 681 . \ | 676 . \ |
| 682 . {* vma, lma, size, rawsize, compressed_size, relax, relax_count, *} \ | 677 . {* vma, lma, size, rawsize, compressed_size, relax, relax_count, *} \ |
| 683 . 0, 0, 0, 0, 0, 0, 0, \ | 678 . 0, 0, 0, 0, 0, 0, 0, \ |
| 684 . \ | 679 . \ |
| 685 . {* output_offset, output_section, alignment_power, *}» \ | 680 . {* output_offset, output_section, alignment_power, *}» \ |
| 686 . 0, (struct bfd_section *) &SEC, 0,» » » \ | 681 . 0, &SEC, 0,»» » » » \ |
| 687 . \ | 682 . \ |
| 688 . {* relocation, orelocation, reloc_count, filepos, rel_filepos, *} \ | 683 . {* relocation, orelocation, reloc_count, filepos, rel_filepos, *} \ |
| 689 . NULL, NULL, 0, 0, 0, \ | 684 . NULL, NULL, 0, 0, 0, \ |
| 690 . \ | 685 . \ |
| 691 . {* line_filepos, userdata, contents, lineno, lineno_count, *} \ | 686 . {* line_filepos, userdata, contents, lineno, lineno_count, *} \ |
| 692 . 0, NULL, NULL, NULL, 0, \ | 687 . 0, NULL, NULL, NULL, 0, \ |
| 693 . \ | 688 . \ |
| 694 . {* entsize, kept_section, moving_line_filepos, *} \ | 689 . {* entsize, kept_section, moving_line_filepos, *} \ |
| 695 . 0, NULL, 0, \ | 690 . 0, NULL, 0, \ |
| 696 . \ | 691 . \ |
| 697 . {* target_index, used_by_bfd, constructor_chain, owner, *} \ | 692 . {* target_index, used_by_bfd, constructor_chain, owner, *} \ |
| 698 . 0, NULL, NULL, NULL, \ | 693 . 0, NULL, NULL, NULL, \ |
| 699 . \ | 694 . \ |
| 700 . {* flag_info, *} \ | |
| 701 . NULL, \ | |
| 702 . \ | |
| 703 . {* symbol, symbol_ptr_ptr, *} \ | 695 . {* symbol, symbol_ptr_ptr, *} \ |
| 704 . (struct bfd_symbol *) SYM, &SEC.symbol, \ | 696 . (struct bfd_symbol *) SYM, &SEC.symbol, \ |
| 705 . \ | 697 . \ |
| 706 . {* map_head, map_tail *} \ | 698 . {* map_head, map_tail *} \ |
| 707 . { NULL }, { NULL } \ | 699 . { NULL }, { NULL } \ |
| 708 . } | 700 . } |
| 709 . | 701 . |
| 710 */ | 702 */ |
| 711 | 703 |
| 712 /* We use a macro to initialize the static asymbol structures because | 704 /* We use a macro to initialize the static asymbol structures because |
| 713 traditional C does not permit us to initialize a union member while | 705 traditional C does not permit us to initialize a union member while |
| 714 gcc warns if we don't initialize it. */ | 706 gcc warns if we don't initialize it. */ |
| 715 /* the_bfd, name, value, attr, section [, udata] */ | 707 /* the_bfd, name, value, attr, section [, udata] */ |
| 716 #ifdef __STDC__ | 708 #ifdef __STDC__ |
| 717 #define GLOBAL_SYM_INIT(NAME, SECTION) \ | 709 #define GLOBAL_SYM_INIT(NAME, SECTION) \ |
| 718 { 0, NAME, 0, BSF_SECTION_SYM, (asection *) SECTION, { 0 }} | 710 { 0, NAME, 0, BSF_SECTION_SYM, SECTION, { 0 }} |
| 719 #else | 711 #else |
| 720 #define GLOBAL_SYM_INIT(NAME, SECTION) \ | 712 #define GLOBAL_SYM_INIT(NAME, SECTION) \ |
| 721 { 0, NAME, 0, BSF_SECTION_SYM, (asection *) SECTION } | 713 { 0, NAME, 0, BSF_SECTION_SYM, SECTION } |
| 722 #endif | 714 #endif |
| 723 | 715 |
| 724 /* These symbols are global, not specific to any BFD. Therefore, anything | 716 /* These symbols are global, not specific to any BFD. Therefore, anything |
| 725 that tries to change them is broken, and should be repaired. */ | 717 that tries to change them is broken, and should be repaired. */ |
| 726 | 718 |
| 727 static const asymbol global_syms[] = | 719 static const asymbol global_syms[] = |
| 728 { | 720 { |
| 729 GLOBAL_SYM_INIT (BFD_COM_SECTION_NAME, &bfd_com_section), | 721 GLOBAL_SYM_INIT (BFD_COM_SECTION_NAME, bfd_com_section_ptr), |
| 730 GLOBAL_SYM_INIT (BFD_UND_SECTION_NAME, &bfd_und_section), | 722 GLOBAL_SYM_INIT (BFD_UND_SECTION_NAME, bfd_und_section_ptr), |
| 731 GLOBAL_SYM_INIT (BFD_ABS_SECTION_NAME, &bfd_abs_section), | 723 GLOBAL_SYM_INIT (BFD_ABS_SECTION_NAME, bfd_abs_section_ptr), |
| 732 GLOBAL_SYM_INIT (BFD_IND_SECTION_NAME, &bfd_ind_section) | 724 GLOBAL_SYM_INIT (BFD_IND_SECTION_NAME, bfd_ind_section_ptr) |
| 733 }; | 725 }; |
| 734 | 726 |
| 735 #define STD_SECTION(SEC, FLAGS, NAME, IDX)» » » » \ | 727 #define STD_SECTION(NAME, IDX, FLAGS) \ |
| 736 asection SEC = BFD_FAKE_SECTION(SEC, FLAGS, &global_syms[IDX],» \ | 728 BFD_FAKE_SECTION(std_section[IDX], FLAGS, &global_syms[IDX], NAME, IDX) |
| 737 » » » » NAME, IDX) | |
| 738 | 729 |
| 739 STD_SECTION (bfd_com_section, SEC_IS_COMMON, BFD_COM_SECTION_NAME, 0); | 730 asection std_section[] = { |
| 740 STD_SECTION (bfd_und_section, 0, BFD_UND_SECTION_NAME, 1); | 731 STD_SECTION (BFD_COM_SECTION_NAME, 0, SEC_IS_COMMON), |
| 741 STD_SECTION (bfd_abs_section, 0, BFD_ABS_SECTION_NAME, 2); | 732 STD_SECTION (BFD_UND_SECTION_NAME, 1, 0), |
| 742 STD_SECTION (bfd_ind_section, 0, BFD_IND_SECTION_NAME, 3); | 733 STD_SECTION (BFD_ABS_SECTION_NAME, 2, 0), |
| 734 STD_SECTION (BFD_IND_SECTION_NAME, 3, 0) |
| 735 }; |
| 743 #undef STD_SECTION | 736 #undef STD_SECTION |
| 744 | 737 |
| 745 /* Initialize an entry in the section hash table. */ | 738 /* Initialize an entry in the section hash table. */ |
| 746 | 739 |
| 747 struct bfd_hash_entry * | 740 struct bfd_hash_entry * |
| 748 bfd_section_hash_newfunc (struct bfd_hash_entry *entry, | 741 bfd_section_hash_newfunc (struct bfd_hash_entry *entry, |
| 749 struct bfd_hash_table *table, | 742 struct bfd_hash_table *table, |
| 750 const char *string) | 743 const char *string) |
| 751 { | 744 { |
| 752 /* Allocate the structure if it has not already been allocated by a | 745 /* Allocate the structure if it has not already been allocated by a |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 845 } | 838 } |
| 846 | 839 |
| 847 /* | 840 /* |
| 848 FUNCTION | 841 FUNCTION |
| 849 bfd_get_section_by_name | 842 bfd_get_section_by_name |
| 850 | 843 |
| 851 SYNOPSIS | 844 SYNOPSIS |
| 852 asection *bfd_get_section_by_name (bfd *abfd, const char *name); | 845 asection *bfd_get_section_by_name (bfd *abfd, const char *name); |
| 853 | 846 |
| 854 DESCRIPTION | 847 DESCRIPTION |
| 855 » Run through @var{abfd} and return the one of the | 848 » Return the most recently created section attached to @var{abfd} |
| 856 » <<asection>>s whose name matches @var{name}, otherwise <<NULL>>. | 849 » named @var{name}. Return NULL if no such section exists. |
| 857 » @xref{Sections}, for more information. | |
| 858 | |
| 859 » This should only be used in special cases; the normal way to process | |
| 860 » all sections of a given name is to use <<bfd_map_over_sections>> and | |
| 861 » <<strcmp>> on the name (or better yet, base it on the section flags | |
| 862 » or something else) for each section. | |
| 863 */ | 850 */ |
| 864 | 851 |
| 865 asection * | 852 asection * |
| 866 bfd_get_section_by_name (bfd *abfd, const char *name) | 853 bfd_get_section_by_name (bfd *abfd, const char *name) |
| 867 { | 854 { |
| 868 struct section_hash_entry *sh; | 855 struct section_hash_entry *sh; |
| 869 | 856 |
| 870 sh = section_hash_lookup (&abfd->section_htab, name, FALSE, FALSE); | 857 sh = section_hash_lookup (&abfd->section_htab, name, FALSE, FALSE); |
| 871 if (sh != NULL) | 858 if (sh != NULL) |
| 872 return &sh->section; | 859 return &sh->section; |
| 873 | 860 |
| 874 return NULL; | 861 return NULL; |
| 875 } | 862 } |
| 876 | 863 |
| 877 /* | 864 /* |
| 878 FUNCTION | 865 FUNCTION |
| 866 bfd_get_next_section_by_name |
| 867 |
| 868 SYNOPSIS |
| 869 asection *bfd_get_next_section_by_name (asection *sec); |
| 870 |
| 871 DESCRIPTION |
| 872 Given @var{sec} is a section returned by @code{bfd_get_section_by_name}, |
| 873 return the next most recently created section attached to the same |
| 874 BFD with the same name. Return NULL if no such section exists. |
| 875 */ |
| 876 |
| 877 asection * |
| 878 bfd_get_next_section_by_name (asection *sec) |
| 879 { |
| 880 struct section_hash_entry *sh; |
| 881 const char *name; |
| 882 unsigned long hash; |
| 883 |
| 884 sh = ((struct section_hash_entry *) |
| 885 ((char *) sec - offsetof (struct section_hash_entry, section))); |
| 886 |
| 887 hash = sh->root.hash; |
| 888 name = sec->name; |
| 889 for (sh = (struct section_hash_entry *) sh->root.next; |
| 890 sh != NULL; |
| 891 sh = (struct section_hash_entry *) sh->root.next) |
| 892 if (sh->root.hash == hash |
| 893 && strcmp (sh->root.string, name) == 0) |
| 894 return &sh->section; |
| 895 |
| 896 return NULL; |
| 897 } |
| 898 |
| 899 /* |
| 900 FUNCTION |
| 901 bfd_get_linker_section |
| 902 |
| 903 SYNOPSIS |
| 904 asection *bfd_get_linker_section (bfd *abfd, const char *name); |
| 905 |
| 906 DESCRIPTION |
| 907 Return the linker created section attached to @var{abfd} |
| 908 named @var{name}. Return NULL if no such section exists. |
| 909 */ |
| 910 |
| 911 asection * |
| 912 bfd_get_linker_section (bfd *abfd, const char *name) |
| 913 { |
| 914 asection *sec = bfd_get_section_by_name (abfd, name); |
| 915 |
| 916 while (sec != NULL && (sec->flags & SEC_LINKER_CREATED) == 0) |
| 917 sec = bfd_get_next_section_by_name (sec); |
| 918 return sec; |
| 919 } |
| 920 |
| 921 /* |
| 922 FUNCTION |
| 879 bfd_get_section_by_name_if | 923 bfd_get_section_by_name_if |
| 880 | 924 |
| 881 SYNOPSIS | 925 SYNOPSIS |
| 882 asection *bfd_get_section_by_name_if | 926 asection *bfd_get_section_by_name_if |
| 883 (bfd *abfd, | 927 (bfd *abfd, |
| 884 const char *name, | 928 const char *name, |
| 885 bfd_boolean (*func) (bfd *abfd, asection *sect, void *obj), | 929 bfd_boolean (*func) (bfd *abfd, asection *sect, void *obj), |
| 886 void *obj); | 930 void *obj); |
| 887 | 931 |
| 888 DESCRIPTION | 932 DESCRIPTION |
| (...skipping 690 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1579 DESCRIPTION | 1623 DESCRIPTION |
| 1580 Remove all members of @var{group} from the output. | 1624 Remove all members of @var{group} from the output. |
| 1581 */ | 1625 */ |
| 1582 | 1626 |
| 1583 bfd_boolean | 1627 bfd_boolean |
| 1584 bfd_generic_discard_group (bfd *abfd ATTRIBUTE_UNUSED, | 1628 bfd_generic_discard_group (bfd *abfd ATTRIBUTE_UNUSED, |
| 1585 asection *group ATTRIBUTE_UNUSED) | 1629 asection *group ATTRIBUTE_UNUSED) |
| 1586 { | 1630 { |
| 1587 return TRUE; | 1631 return TRUE; |
| 1588 } | 1632 } |
| OLD | NEW |