Browse Source

components: libc: fix pointer-to-integer cast warnings and address truncation

[Problem Description]
1. When enabling RT_USING_MODULE=y, compilation warnings occur:
   dlelf.c:386:27: warning: cast from pointer to integer of different size
   dlelf.c:398:25: warning: cast from pointer to integer of different size
   dlelf.c:408:24: warning: cast from pointer to integer of different size

2. On RV64 architectures (e.g. Sophgo SG2042 with RISC-V Sv39 and 40-bit physical addressing),
   dlsym may fail when accessing addresses beyond 32-bit range.

[Root Cause]
In dlmodule_load_relocated_object() and dlmodule_symbol_find(),
pointer is cast to rt_uint32_t which truncates:
| rt_ubase_t rodata_addr = (rt_uint32_t)ptr;
This causes:
- Warnings on 64-bit systems (pointer width > 32-bit)
- Actual address truncation on RV64 when physical address exceeds 32-bit

[Solution]
Replace rt_uint32_t with architecture-adaptive rt_ubase_t:
| rt_ubase_t rodata_addr = (rt_ubase_t)ptr;
The rt_ubase_t is defined in include/rttypes.h as:
| #ifdef ARCH_CPU_64BIT
|   typedef rt_uint64_t rt_ubase_t;
| #else
|   typedef rt_uint32_t rt_ubase_t;
| #endif
This ensures correct width casting for both 32/64-bit architectures.

Signed-off-by: Liu Gui <kenneth.liu@sophgo.com>
kenneth.liu 4 months ago
parent
commit
4940bb1051

+ 5 - 5
components/libc/posix/libdl/dlelf.c

@@ -383,9 +383,9 @@ rt_err_t dlmodule_load_relocated_object(struct rt_dlmodule* module, void *module
             rt_memcpy(ptr,
             rt_memcpy(ptr,
                       (rt_uint8_t *)elf_module + shdr[index].sh_offset,
                       (rt_uint8_t *)elf_module + shdr[index].sh_offset,
                       shdr[index].sh_size);
                       shdr[index].sh_size);
-            rodata_addr = (rt_uint32_t)ptr;
+            rodata_addr = (rt_ubase_t)ptr;
             LOG_D("load rodata 0x%x, size %d, rodata 0x%x", ptr,
             LOG_D("load rodata 0x%x, size %d, rodata 0x%x", ptr,
-                shdr[index].sh_size, *(rt_uint32_t *)data_addr);
+                shdr[index].sh_size, *(rt_ubase_t *)rodata_addr);
             ptr += shdr[index].sh_size;
             ptr += shdr[index].sh_size;
         }
         }
 
 
@@ -395,9 +395,9 @@ rt_err_t dlmodule_load_relocated_object(struct rt_dlmodule* module, void *module
             rt_memcpy(ptr,
             rt_memcpy(ptr,
                       (rt_uint8_t *)elf_module + shdr[index].sh_offset,
                       (rt_uint8_t *)elf_module + shdr[index].sh_offset,
                       shdr[index].sh_size);
                       shdr[index].sh_size);
-            data_addr = (rt_uint32_t)ptr;
+            data_addr = (rt_ubase_t)ptr;
             LOG_D("load data 0x%x, size %d, data 0x%x", ptr,
             LOG_D("load data 0x%x, size %d, data 0x%x", ptr,
-                shdr[index].sh_size, *(rt_uint32_t *)data_addr);
+                shdr[index].sh_size, *(rt_ubase_t *)data_addr);
             ptr += shdr[index].sh_size;
             ptr += shdr[index].sh_size;
         }
         }
 
 
@@ -405,7 +405,7 @@ rt_err_t dlmodule_load_relocated_object(struct rt_dlmodule* module, void *module
         if (IS_NOPROG(shdr[index]) && IS_AW(shdr[index]))
         if (IS_NOPROG(shdr[index]) && IS_AW(shdr[index]))
         {
         {
             rt_memset(ptr, 0, shdr[index].sh_size);
             rt_memset(ptr, 0, shdr[index].sh_size);
-            bss_addr = (rt_uint32_t)ptr;
+            bss_addr = (rt_ubase_t)ptr;
             LOG_D("load bss 0x%x, size %d", ptr, shdr[index].sh_size);
             LOG_D("load bss 0x%x, size %d", ptr, shdr[index].sh_size);
         }
         }
     }
     }

+ 3 - 3
components/libc/posix/libdl/dlmodule.c

@@ -837,10 +837,10 @@ void dlmodule_exit(int ret_code)
  * @brief search for a symbol by its name in the kernel symbol table.
  * @brief search for a symbol by its name in the kernel symbol table.
  *
  *
  * @param sym_str the symbol name string.
  * @param sym_str the symbol name string.
- * @return rt_uint32_t On success, it returns the address of the symbol.
+ * @return rt_ubase_t On success, it returns the address of the symbol.
  *         Otherwise, it returns 0 (indicating the symbol was not found).
  *         Otherwise, it returns 0 (indicating the symbol was not found).
  */
  */
-rt_uint32_t dlmodule_symbol_find(const char *sym_str)
+rt_ubase_t dlmodule_symbol_find(const char *sym_str)
 {
 {
     /* find in kernel symbol table */
     /* find in kernel symbol table */
     struct rt_module_symtab *index;
     struct rt_module_symtab *index;
@@ -848,7 +848,7 @@ rt_uint32_t dlmodule_symbol_find(const char *sym_str)
     for (index = _rt_module_symtab_begin; index != _rt_module_symtab_end; index ++)
     for (index = _rt_module_symtab_begin; index != _rt_module_symtab_end; index ++)
     {
     {
         if (rt_strcmp(index->name, sym_str) == 0)
         if (rt_strcmp(index->name, sym_str) == 0)
-            return (rt_uint32_t)index->addr;
+            return (rt_ubase_t)index->addr;
     }
     }
 
 
     return 0;
     return 0;

+ 1 - 1
components/libc/posix/libdl/dlmodule.h

@@ -82,6 +82,6 @@ void dlmodule_exit(int ret_code);
 
 
 struct rt_dlmodule *dlmodule_find(const char *name);
 struct rt_dlmodule *dlmodule_find(const char *name);
 
 
-rt_uint32_t dlmodule_symbol_find(const char *sym_str);
+rt_ubase_t dlmodule_symbol_find(const char *sym_str);
 
 
 #endif
 #endif