@@ -508,6 +508,7 @@ int elf_add_reloc(struct elf *elf, struct section *sec, unsigned long offset,
508508 list_add_tail (& reloc -> list , & sec -> reloc -> reloc_list );
509509 elf_hash_add (reloc , & reloc -> hash , reloc_hash (reloc ));
510510
511+ sec -> reloc -> sh .sh_size += sec -> reloc -> sh .sh_entsize ;
511512 sec -> reloc -> changed = true;
512513
513514 return 0 ;
@@ -977,63 +978,63 @@ static struct section *elf_create_reloc_section(struct elf *elf,
977978 }
978979}
979980
980- static int elf_rebuild_rel_reloc_section (struct section * sec , int nr )
981+ static int elf_rebuild_rel_reloc_section (struct section * sec )
981982{
982983 struct reloc * reloc ;
983- int idx = 0 , size ;
984+ int idx = 0 ;
984985 void * buf ;
985986
986987 /* Allocate a buffer for relocations */
987- size = nr * sizeof (GElf_Rel );
988- buf = malloc (size );
988+ buf = malloc (sec -> sh .sh_size );
989989 if (!buf ) {
990990 perror ("malloc" );
991991 return -1 ;
992992 }
993993
994994 sec -> data -> d_buf = buf ;
995- sec -> data -> d_size = size ;
995+ sec -> data -> d_size = sec -> sh . sh_size ;
996996 sec -> data -> d_type = ELF_T_REL ;
997997
998- sec -> sh .sh_size = size ;
999-
1000998 idx = 0 ;
1001999 list_for_each_entry (reloc , & sec -> reloc_list , list ) {
10021000 reloc -> rel .r_offset = reloc -> offset ;
10031001 reloc -> rel .r_info = GELF_R_INFO (reloc -> sym -> idx , reloc -> type );
1004- gelf_update_rel (sec -> data , idx , & reloc -> rel );
1002+ if (!gelf_update_rel (sec -> data , idx , & reloc -> rel )) {
1003+ WARN_ELF ("gelf_update_rel" );
1004+ return -1 ;
1005+ }
10051006 idx ++ ;
10061007 }
10071008
10081009 return 0 ;
10091010}
10101011
1011- static int elf_rebuild_rela_reloc_section (struct section * sec , int nr )
1012+ static int elf_rebuild_rela_reloc_section (struct section * sec )
10121013{
10131014 struct reloc * reloc ;
1014- int idx = 0 , size ;
1015+ int idx = 0 ;
10151016 void * buf ;
10161017
10171018 /* Allocate a buffer for relocations with addends */
1018- size = nr * sizeof (GElf_Rela );
1019- buf = malloc (size );
1019+ buf = malloc (sec -> sh .sh_size );
10201020 if (!buf ) {
10211021 perror ("malloc" );
10221022 return -1 ;
10231023 }
10241024
10251025 sec -> data -> d_buf = buf ;
1026- sec -> data -> d_size = size ;
1026+ sec -> data -> d_size = sec -> sh . sh_size ;
10271027 sec -> data -> d_type = ELF_T_RELA ;
10281028
1029- sec -> sh .sh_size = size ;
1030-
10311029 idx = 0 ;
10321030 list_for_each_entry (reloc , & sec -> reloc_list , list ) {
10331031 reloc -> rela .r_offset = reloc -> offset ;
10341032 reloc -> rela .r_addend = reloc -> addend ;
10351033 reloc -> rela .r_info = GELF_R_INFO (reloc -> sym -> idx , reloc -> type );
1036- gelf_update_rela (sec -> data , idx , & reloc -> rela );
1034+ if (!gelf_update_rela (sec -> data , idx , & reloc -> rela )) {
1035+ WARN_ELF ("gelf_update_rela" );
1036+ return -1 ;
1037+ }
10371038 idx ++ ;
10381039 }
10391040
@@ -1042,16 +1043,9 @@ static int elf_rebuild_rela_reloc_section(struct section *sec, int nr)
10421043
10431044static int elf_rebuild_reloc_section (struct elf * elf , struct section * sec )
10441045{
1045- struct reloc * reloc ;
1046- int nr ;
1047-
1048- nr = 0 ;
1049- list_for_each_entry (reloc , & sec -> reloc_list , list )
1050- nr ++ ;
1051-
10521046 switch (sec -> sh .sh_type ) {
1053- case SHT_REL : return elf_rebuild_rel_reloc_section (sec , nr );
1054- case SHT_RELA : return elf_rebuild_rela_reloc_section (sec , nr );
1047+ case SHT_REL : return elf_rebuild_rel_reloc_section (sec );
1048+ case SHT_RELA : return elf_rebuild_rela_reloc_section (sec );
10551049 default : return -1 ;
10561050 }
10571051}
@@ -1111,12 +1105,6 @@ int elf_write(struct elf *elf)
11111105 /* Update changed relocation sections and section headers: */
11121106 list_for_each_entry (sec , & elf -> sections , list ) {
11131107 if (sec -> changed ) {
1114- if (sec -> base &&
1115- elf_rebuild_reloc_section (elf , sec )) {
1116- WARN ("elf_rebuild_reloc_section" );
1117- return -1 ;
1118- }
1119-
11201108 s = elf_getscn (elf -> elf , sec -> idx );
11211109 if (!s ) {
11221110 WARN_ELF ("elf_getscn" );
@@ -1127,6 +1115,12 @@ int elf_write(struct elf *elf)
11271115 return -1 ;
11281116 }
11291117
1118+ if (sec -> base &&
1119+ elf_rebuild_reloc_section (elf , sec )) {
1120+ WARN ("elf_rebuild_reloc_section" );
1121+ return -1 ;
1122+ }
1123+
11301124 sec -> changed = false;
11311125 elf -> changed = true;
11321126 }
0 commit comments