@@ -348,6 +348,18 @@ static int compressed_section_fix(Elf *elf, Elf_Scn *scn, GElf_Shdr *sh)
348348 return 0 ;
349349}
350350
351+ static void bswap_32_data (void * data , u32 nr_bytes )
352+ {
353+ u32 cnt , i ;
354+ u32 * ptr ;
355+
356+ cnt = nr_bytes / sizeof (u32 );
357+ ptr = data ;
358+
359+ for (i = 0 ; i < cnt ; i ++ )
360+ ptr [i ] = bswap_32 (ptr [i ]);
361+ }
362+
351363static int elf_collect (struct object * obj )
352364{
353365 Elf_Scn * scn = NULL ;
@@ -429,6 +441,16 @@ static int elf_collect(struct object *obj)
429441 obj -> efile .symbols_shndx = idx ;
430442 obj -> efile .strtabidx = sh .sh_link ;
431443 } else if (!strcmp (name , BTF_IDS_SECTION )) {
444+ /*
445+ * If target endianness differs from host, we need to bswap32
446+ * the .BTF_ids section data on load, because .BTF_ids has
447+ * Elf_Type = ELF_T_BYTE, and so libelf returns data buffer in
448+ * the target endiannes. We repeat this on dump.
449+ */
450+ if (obj -> efile .encoding != ELFDATANATIVE ) {
451+ pr_debug ("bswap_32 .BTF_ids data from target to host endianness\n" );
452+ bswap_32_data (data -> d_buf , data -> d_size );
453+ }
432454 obj -> efile .idlist = data ;
433455 obj -> efile .idlist_shndx = idx ;
434456 obj -> efile .idlist_addr = sh .sh_addr ;
@@ -751,22 +773,6 @@ static int sets_patch(struct object *obj)
751773 */
752774 BUILD_BUG_ON ((u32 * )set8 -> pairs != & set8 -> pairs [0 ].id );
753775 qsort (set8 -> pairs , set8 -> cnt , sizeof (set8 -> pairs [0 ]), cmp_id );
754-
755- /*
756- * When ELF endianness does not match endianness of the
757- * host, we have to make sure SET8 flags are not byteswapped
758- * on dump, because they are already in the target endianness.
759- * So we bswap them here to the host endiannes.
760- */
761- if (obj -> efile .encoding != ELFDATANATIVE ) {
762- int i ;
763-
764- set8 -> flags = bswap_32 (set8 -> flags );
765- for (i = 0 ; i < set8 -> cnt ; i ++ ) {
766- set8 -> pairs [i ].flags =
767- bswap_32 (set8 -> pairs [i ].flags );
768- }
769- }
770776 break ;
771777 case BTF_ID_KIND_SYM :
772778 default :
@@ -823,27 +829,21 @@ static int dump_raw_data(const char *out_path, const void *data, u32 size)
823829static int dump_raw_btf_ids (struct object * obj , const char * out_path )
824830{
825831 Elf_Data * data = obj -> efile .idlist ;
826- int fd , err , i , cnt ;
827- u32 * ptr ;
832+ int fd , err ;
828833
829834 if (!data || !data -> d_buf ) {
830835 pr_debug ("%s has no BTF_ids data to dump\n" , obj -> path );
831836 return 0 ;
832837 }
833838
834839 /*
835- * If target endianness differs from host, we need to byteswap
836- * all the u32 values in the .BTF_ids section before dumping,
837- * because elf_getdata() converts to host endianness and
838- * objcopy --update-section does a raw byte copy.
840+ * If target endianness differs from host, we need to bswap32 the
841+ * .BTF_ids section data before dumping so that the output is in
842+ * target endianness.
839843 */
840844 if (obj -> efile .encoding != ELFDATANATIVE ) {
841- cnt = data -> d_size / sizeof (u32 );
842- ptr = data -> d_buf ;
843-
844845 pr_debug ("bswap_32 .BTF_ids data from host to target endianness\n" );
845- for (i = 0 ; i < cnt ; i ++ )
846- ptr [i ] = bswap_32 (ptr [i ]);
846+ bswap_32_data (data -> d_buf , data -> d_size );
847847 }
848848
849849 err = dump_raw_data (out_path , data -> d_buf , data -> d_size );
0 commit comments