@@ -766,6 +766,18 @@ void ElfFile<ElfFileParamNames>::writeReplacedSections(Elf_Off & curOff,
766766 }
767767 }
768768
769+ /* If there is .MIPS.abiflags section, then the PT_MIPS_ABIFLAGS
770+ segment must be sync'ed with it. */
771+ if (sectionName == " .MIPS.abiflags" ) {
772+ for (auto & phdr : phdrs) {
773+ if (rdi (phdr.p_type ) == PT_MIPS_ABIFLAGS) {
774+ phdr.p_offset = shdr.sh_offset ;
775+ phdr.p_vaddr = phdr.p_paddr = shdr.sh_addr ;
776+ phdr.p_filesz = phdr.p_memsz = shdr.sh_size ;
777+ }
778+ }
779+ }
780+
769781 curOff += roundUp (i.second .size (), sectionAlignment);
770782 }
771783
@@ -1098,9 +1110,9 @@ void ElfFile<ElfFileParamNames>::rewriteHeaders(Elf_Addr phdrAddress)
10981110 (e.g., those produced by klibc's klcc). */
10991111 auto shdrDynamic = findSection2 (" .dynamic" );
11001112 if (shdrDynamic) {
1101- auto dyn = (Elf_Dyn *)(contents + rdi (shdrDynamic->sh_offset ));
1113+ auto dyn_table = (Elf_Dyn *) (contents + rdi (shdrDynamic->sh_offset ));
11021114 unsigned int d_tag;
1103- for ( ; (d_tag = rdi (dyn->d_tag )) != DT_NULL; dyn++)
1115+ for (auto dyn = dyn_table ; (d_tag = rdi (dyn->d_tag )) != DT_NULL; dyn++)
11041116 if (d_tag == DT_STRTAB)
11051117 dyn->d_un .d_ptr = findSection (" .dynstr" ).sh_addr ;
11061118 else if (d_tag == DT_STRSZ)
@@ -1142,6 +1154,23 @@ void ElfFile<ElfFileParamNames>::rewriteHeaders(Elf_Addr phdrAddress)
11421154 dyn->d_un .d_ptr = findSection (" .gnu.version_r" ).sh_addr ;
11431155 else if (d_tag == DT_VERSYM)
11441156 dyn->d_un .d_ptr = findSection (" .gnu.version" ).sh_addr ;
1157+ else if (d_tag == DT_MIPS_RLD_MAP_REL) {
1158+ /* the MIPS_RLD_MAP_REL tag stores the offset to the debug
1159+ pointer, relative to the address of the tag */
1160+ auto shdr = findSection2 (" .rld_map" );
1161+ if (shdr) {
1162+ auto rld_map_addr = findSection (" .rld_map" ).sh_addr ;
1163+ auto dyn_offset = ((char *)dyn) - ((char *)dyn_table);
1164+ dyn->d_un .d_ptr = rld_map_addr + dyn_offset - shdrDynamic->sh_addr ;
1165+ } else {
1166+ /* ELF file with DT_MIPS_RLD_MAP_REL but without .rld_map
1167+ is broken, and it's not our job to fix it; yet, we have
1168+ to find some location for dynamic loader to write the
1169+ debug pointer to; well, let's write it right here */
1170+ fprintf (stderr, " warning: DT_MIPS_RLD_MAP_REL entry is present, but .rld_map section is not\n " );
1171+ dyn->d_un .d_ptr = 0 ;
1172+ }
1173+ }
11451174 }
11461175
11471176
0 commit comments