From 86d8bf1161c4c9a20208ee89b84d8cbb191b48a4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Vivek=20Das=C2=A0Mohapatra?= <vivek@collabora.co.uk>
Date: Wed, 24 May 2017 00:12:19 +0100
Subject: [PATCH] ELF32_R_x vs EL64_R_x: compiler not smart enough to infer
 path safety

If we use the ELF64 and ELF32 _R_x macros in the relevant branches of
a switch( __ELF_NATIVE_CLASS ) case statement we're guaranteed to be
safe but the compiler isn't smart enough to deduce this and emits some
warnings about bit shift overflows.

Use #if __ELF_NATIVE_CLASS == x code selection instead.
---
 utils/dump.c               | 56 ++++++++++++++++----------------------
 utils/elf-dump.c           | 56 ++++++++++++++++----------------------
 utils/process-pt-dynamic.c | 48 ++++++++++++++------------------
 3 files changed, 68 insertions(+), 92 deletions(-)

diff --git a/utils/dump.c b/utils/dump.c
index 3a97835e1..37bbbba0c 100644
--- a/utils/dump.c
+++ b/utils/dump.c
@@ -708,22 +708,18 @@ dump_rel (const char *indent,
 
         const ElfW(Sym) *symbol;
 
-        switch( __ELF_NATIVE_CLASS )
-        {
-          case 32:
-            sym = ELF32_R_SYM (entry->r_info);
-            chr = ELF32_R_TYPE(entry->r_info);
-            break;
-          case 64:
-            sym = ELF64_R_SYM (entry->r_info);
-            chr = ELF64_R_TYPE(entry->r_info);
-            break;
-          default:
-            fprintf( stderr,
-                     "__ELF_NATIVE_CLASS is NOT 32 or 64:"
-                     " What the actual hell\n" );
-            exit(-1);
-        }
+#if __ELF_NATIVE_CLASS == 32
+        sym = ELF32_R_SYM (entry->r_info);
+        chr = ELF32_R_TYPE(entry->r_info);
+#elif __ELF_NATIVE_CLASS == 64
+        sym = ELF64_R_SYM (entry->r_info);
+        chr = ELF64_R_TYPE(entry->r_info);
+#else
+        fprintf( stderr,
+                 "__ELF_NATIVE_CLASS is NOT 32 or 64:"
+                 " What the actual hell\n" );
+        exit( 22 );
+#endif
 
         symbol = find_symbol( sym, symtab, strtab, &name );
         if( symbol )
@@ -764,22 +760,18 @@ dump_rela (const char *indent,
 
         const ElfW(Sym) *symbol;
 
-        switch( __ELF_NATIVE_CLASS )
-        {
-          case 32:
-            sym = ELF32_R_SYM (entry->r_info);
-            chr = ELF32_R_TYPE(entry->r_info);
-            break;
-          case 64:
-            sym = ELF64_R_SYM (entry->r_info);
-            chr = ELF64_R_TYPE(entry->r_info);
-            break;
-          default:
-            fprintf( stderr,
-                     "__ELF_NATIVE_CLASS is NOT 32 or 64:"
-                     " What the actual hell\n" );
-            exit(-1);
-        }
+#if __ELF_NATIVE_CLASS == 32
+        sym = ELF32_R_SYM (entry->r_info);
+        chr = ELF32_R_TYPE(entry->r_info);
+#elif __ELF_NATIVE_CLASS == 64
+        sym = ELF64_R_SYM (entry->r_info);
+        chr = ELF64_R_TYPE(entry->r_info);
+#else
+        fprintf( stderr,
+                 "__ELF_NATIVE_CLASS is NOT 32 or 64:"
+                 " What the actual hell\n" );
+        exit( 22 );
+#endif
 
         symbol = find_symbol( sym, symtab, strtab, &name );
         if( symbol )
diff --git a/utils/elf-dump.c b/utils/elf-dump.c
index 5591e50a5..4295640ae 100644
--- a/utils/elf-dump.c
+++ b/utils/elf-dump.c
@@ -707,22 +707,18 @@ dump_rel (const char *indent,
 
         const ElfW(Sym) *symbol;
 
-        switch( __ELF_NATIVE_CLASS )
-        {
-          case 32:
-            sym = ELF32_R_SYM (entry->r_info);
-            chr = ELF32_R_TYPE(entry->r_info);
-            break;
-          case 64:
-            sym = ELF64_R_SYM (entry->r_info);
-            chr = ELF64_R_TYPE(entry->r_info);
-            break;
-          default:
-            fprintf( stderr,
-                     "__ELF_NATIVE_CLASS is NOT 32 or 64:"
-                     " What the actual hell\n" );
-            exit(-1);
-        }
+#if __ELF_NATIVE_CLASS == 32
+        sym = ELF32_R_SYM (entry->r_info);
+        chr = ELF32_R_TYPE(entry->r_info);
+#elif __ELF_NATIVE_CLASS == 64
+        sym = ELF64_R_SYM (entry->r_info);
+        chr = ELF64_R_TYPE(entry->r_info);
+#else
+        fprintf( stderr,
+                 "__ELF_NATIVE_CLASS is NOT 32 or 64:"
+                 " What the actual hell\n" );
+        exit( 22 );
+#endif
 
         symbol = find_symbol( sym, symtab, strtab, &name );
         if( symbol )
@@ -763,22 +759,18 @@ dump_rela (const char *indent,
 
         const ElfW(Sym) *symbol;
 
-        switch( __ELF_NATIVE_CLASS )
-        {
-          case 32:
-            sym = ELF32_R_SYM (entry->r_info);
-            chr = ELF32_R_TYPE(entry->r_info);
-            break;
-          case 64:
-            sym = ELF64_R_SYM (entry->r_info);
-            chr = ELF64_R_TYPE(entry->r_info);
-            break;
-          default:
-            fprintf( stderr,
-                     "__ELF_NATIVE_CLASS is NOT 32 or 64:"
-                     " What the actual hell\n" );
-            exit(-1);
-        }
+#if __ELF_NATIVE_CLASS == 32
+        sym = ELF32_R_SYM (entry->r_info);
+        chr = ELF32_R_TYPE(entry->r_info);
+#elif __ELF_NATIVE_CLASS == 64
+        sym = ELF64_R_SYM (entry->r_info);
+        chr = ELF64_R_TYPE(entry->r_info);
+#else
+        fprintf( stderr,
+                 "__ELF_NATIVE_CLASS is NOT 32 or 64:"
+                 " What the actual hell\n" );
+        exit( 22 );
+#endif
 
         symbol = find_symbol( sym, symtab, strtab, &name );
         if( symbol )
diff --git a/utils/process-pt-dynamic.c b/utils/process-pt-dynamic.c
index 3315c18ff..62131eba3 100644
--- a/utils/process-pt-dynamic.c
+++ b/utils/process-pt-dynamic.c
@@ -234,20 +234,16 @@ process_dt_rela (const void *start,
         char *name = NULL;
         const ElfW(Sym) *symbol;
 
-        switch( __ELF_NATIVE_CLASS )
-        {
-          case 32:
-            sym = ELF32_R_SYM (entry->r_info);
-            chr = ELF32_R_TYPE(entry->r_info);
-            break;
-          case 64:
-            sym = ELF64_R_SYM (entry->r_info);
-            chr = ELF64_R_TYPE(entry->r_info);
-            break;
-          default:
-            fprintf( stderr, "__ELF_NATIVE_CLASS is neither 32 nor 64" );
-            exit( 22 );
-        }
+#if __ELF_NATIVE_CLASS == 32
+        sym = ELF32_R_SYM (entry->r_info);
+        chr = ELF32_R_TYPE(entry->r_info);
+#elif __ELF_NATIVE_CLASS == 64
+        sym = ELF64_R_SYM (entry->r_info);
+        chr = ELF64_R_TYPE(entry->r_info);
+#else
+        fprintf( stderr, "__ELF_NATIVE_CLASS is neither 32 nor 64" );
+        exit( 22 );
+#endif
 
         DEBUG( DEBUG_ELF, "RELA entry at %p", entry );
 
@@ -413,20 +409,16 @@ process_dt_rel (const void *start,
 
         const ElfW(Sym) *symbol;
 
-        switch( __ELF_NATIVE_CLASS )
-        {
-          case 32:
-            sym = ELF32_R_SYM (entry->r_info);
-            chr = ELF32_R_TYPE(entry->r_info);
-            break;
-          case 64:
-            sym = ELF64_R_SYM (entry->r_info);
-            chr = ELF64_R_TYPE(entry->r_info);
-            break;
-          default:
-            fprintf( stderr, "__ELF_NATIVE_CLASS is neither 32 nor 64" );
-            exit( 22 );
-        }
+#if __ELF_NATIVE_CLASS == 32
+        sym = ELF32_R_SYM (entry->r_info);
+        chr = ELF32_R_TYPE(entry->r_info);
+#elif __ELF_NATIVE_CLASS == 64
+        sym = ELF64_R_SYM (entry->r_info);
+        chr = ELF64_R_TYPE(entry->r_info);
+#else
+        fprintf( stderr, "__ELF_NATIVE_CLASS is neither 32 nor 64" );
+        exit( 22 );
+#endif
 
         symbol = find_symbol( sym, symtab, strtab, &name );
 
-- 
GitLab