changeset 2925:7cbaadc92c67

* services/objloader/current/src/objloader.c, services/objloader/current/src/objelf.c services/objloader/current/include/objelf.h: Fixed a memory leak where a library section was loaded but memory allocated was not released. This bug was reported by Davy Wouters on the eCos list. Added minor cosmetics and a number of CYG_ASSERT and if() to test the values returned by cyg_ldr_load_elf_section() * services/objloader/current/cdl/objloader.cdl: Eliminate workarounds for file path handling issue in obsolete Cygwin tclsh. Use ACTUAL_CFLAGS for robustness. * fs/rom/current/cdl/romfs.cdl: Eliminate workarounds for file path handling issue in obsolete Cygwin tclsh. Build the mk_romfs tool with higher priority than the custom rules which use it.
author jld
date Fri, 09 Oct 2009 13:53:09 +0000
parents 56796f529a99
children a7719f548c95
files packages/fs/rom/current/ChangeLog packages/fs/rom/current/cdl/romfs.cdl packages/services/objloader/current/ChangeLog packages/services/objloader/current/cdl/objloader.cdl packages/services/objloader/current/include/objelf.h packages/services/objloader/current/src/objelf.c packages/services/objloader/current/src/objloader.c
diffstat 7 files changed, 94 insertions(+), 55 deletions(-) [+]
line wrap: on
line diff
--- a/packages/fs/rom/current/ChangeLog
+++ b/packages/fs/rom/current/ChangeLog
@@ -1,6 +1,12 @@
+2009-10-09  John Dallaway  <john@dallaway.org.uk>
+
+	* cdl/romfs.cdl: Eliminate workarounds for file path handling
+	issue in obsolete Cygwin tclsh. Build the mk_romfs tool with higher
+	priority than the custom rules which use it.
+
 2009-04-28  John Dallaway  <john@dallaway.org.uk>
 
-	cdl/romfs.cdl: Use CYGPKG_IO_FILEIO as the parent.
+	* cdl/romfs.cdl: Use CYGPKG_IO_FILEIO as the parent.
 
 2009-02-07  John Dallaway  <john@dallaway.org.uk>
 
--- a/packages/fs/rom/current/cdl/romfs.cdl
+++ b/packages/fs/rom/current/cdl/romfs.cdl
@@ -69,12 +69,17 @@ cdl_package CYGPKG_FS_ROM {
         flavor        bool
         default_value 1
 
+        make -priority 98 {
+            <PREFIX>/bin/file2c.tcl: <PACKAGE>/support/file2c.tcl
+            @mkdir -p "$(dir $@)"
+            @cp $< $@
+        }
+
         # FIXME: host compiler/flags should be provided by config system
-        make -priority 100 {
-            <PREFIX>/bin/mk_romfs: <PACKAGE>/support/mk_romfs.c <PREFIX>/bin/file2c.tcl
+        make -priority 98 {
+            <PREFIX>/bin/mk_romfs: <PACKAGE>/support/mk_romfs.c
             @mkdir -p "$(dir $@)"
             @$(HOST_CC) -g -O2 -o $@ $< || cc -g -O2 -o $@ $< || gcc -g -O2 -o $@ $<
-            @cp $(REPOSITORY)/$(PACKAGE)/support/file2c.tcl $(PREFIX)/bin
         }
 
         description "
@@ -112,24 +117,17 @@ cdl_package CYGPKG_FS_ROM {
                 This option enables the building of the ROM filesystem tests."
 
         make -priority 100 {
-            <PREFIX>/include/cyg/romfs/testromfs_le.h : <PREFIX>/bin/mk_romfs <PACKAGE>/support/file2c.tcl
-            $(PREFIX)/bin/mk_romfs $(REPOSITORY)/$(PACKAGE)/tests/testromfs testromfs_le.bin
+            <PREFIX>/include/cyg/romfs/testromfs_le.h : <PACKAGE>/tests/testromfs <PREFIX>/bin/mk_romfs <PREFIX>/bin/file2c.tcl
+            $(PREFIX)/bin/mk_romfs $< testromfs_le.bin
             @mkdir -p "$(dir $@)"
-            # work around cygwin path problems by copying to build dir
-            @cp $(REPOSITORY)/$(PACKAGE)/support/file2c.tcl .
-            tclsh file2c.tcl testromfs_le.bin testromfs_le.h
-            @rm -f $@ file2c.tcl
-            @cp testromfs_le.h $@
+            tclsh $(PREFIX)/bin/file2c.tcl testromfs_le.bin $@
         }
     
         make -priority 100 {
-            <PREFIX>/include/cyg/romfs/testromfs_be.h : <PREFIX>/bin/mk_romfs <PACKAGE>/support/file2c.tcl
-            $(PREFIX)/bin/mk_romfs -b $(REPOSITORY)/$(PACKAGE)/tests/testromfs testromfs_be.bin
+            <PREFIX>/include/cyg/romfs/testromfs_be.h : <PACKAGE>/tests/testromfs <PREFIX>/bin/mk_romfs <PREFIX>/bin/file2c.tcl
+            $(PREFIX)/bin/mk_romfs -b $< testromfs_be.bin
             @mkdir -p "$(dir $@)"
-            # work around cygwin path problems by copying to bin dir
-            @cp $(REPOSITORY)/$(PACKAGE)/support/file2c.tcl $(PREFIX)/bin/
-            tclsh $(PREFIX)/bin/file2c.tcl testromfs_be.bin testromfs_be.h
-            @cp testromfs_be.h $@
+            tclsh $(PREFIX)/bin/file2c.tcl testromfs_be.bin $@
         }
     
         cdl_option CYGPKG_FS_ROM_TESTS {
--- a/packages/services/objloader/current/ChangeLog
+++ b/packages/services/objloader/current/ChangeLog
@@ -1,3 +1,16 @@
+2009-10-09  John Dallaway  <john@dallaway.org.uk>
+
+	* cdl/objloader.cdl: Eliminate workarounds for file path handling
+	issue in obsolete Cygwin tclsh. Use ACTUAL_CFLAGS for robustness.
+
+2009-09-13  Anthony Tonizzo  <atonizzo@gmail.com>
+
+	* src/objloader.c, src/objelf.c, include/objelf.h : Fixed a memory
+	leak where a library section was loaded but memory allocated was not
+	released. This bug was reported by Davy Wouters on the eCos list.
+	Added minor cosmetics and a number of CYG_ASSERT and if() to test the
+	values returnedby cyg_ldr_load_elf_section().
+
 2009-07-03  John Dallaway  <john@dallaway.org.uk>
 
 	* cdl/objloader.cdl, src/objelf.c, src/relocate_ppc.c,
--- a/packages/services/objloader/current/cdl/objloader.cdl
+++ b/packages/services/objloader/current/cdl/objloader.cdl
@@ -191,25 +191,23 @@ cdl_package CYGPKG_OBJLOADER {
             application for testing the loader." 
         
         make -priority 320 {
-            tests/testromfs/hello.o : <PACKAGE>/tests/library/hello.c
-            @sh -c "mkdir -p tests tests/testromfs"
-            $(CC) -c $(INCLUDE_PATH) -I$(dir $<) $(CFLAGS) -o $@ $<
+            testobj/hello.o : <PACKAGE>/tests/library/hello.c
+            @mkdir -p "$(dir $@)"
+            $(CC) -c $(INCLUDE_PATH) -I$(dir $<) $(ACTUAL_CFLAGS) -o $@ $<
         }
 
         make -priority 322 {
-            <PREFIX>/include/cyg/objloader/testromfs_be.h : tests/testromfs/hello.o 
-            $(PREFIX)/bin/mk_romfs -b tests/testromfs testromfs_be.bin 
-	    @mkdir -p "$(dir $@)"
-            @tclsh $(PREFIX)/bin/file2c.tcl testromfs_be.bin testromfs_be.h
-            @cp testromfs_be.h $@
+            <PREFIX>/include/cyg/objloader/testromfs_be.h : testobj/hello.o
+            $(PREFIX)/bin/mk_romfs -b $(dir $<) testromfs_be.bin
+            @mkdir -p "$(dir $@)"
+            @tclsh $(PREFIX)/bin/file2c.tcl testromfs_be.bin $@
         }
         
         make -priority 322 {
-            <PREFIX>/include/cyg/objloader/testromfs_le.h : tests/testromfs/hello.o 
-            $(PREFIX)/bin/mk_romfs tests/testromfs testromfs_le.bin
-	    @mkdir -p "$(dir $@)"
-            @tclsh $(PREFIX)/bin/file2c.tcl testromfs_le.bin testromfs_le.h
-            @cp testromfs_le.h $@
+            <PREFIX>/include/cyg/objloader/testromfs_le.h : testobj/hello.o
+            $(PREFIX)/bin/mk_romfs $(dir $<) testromfs_le.bin
+            @mkdir -p "$(dir $@)"
+            @tclsh $(PREFIX)/bin/file2c.tcl testromfs_le.bin $@
         }
     
         cdl_option CYGPKG_OBJLOADER_TESTS {
--- a/packages/services/objloader/current/include/objelf.h
+++ b/packages/services/objloader/current/include/objelf.h
@@ -9,7 +9,7 @@
  * ####ECOSGPLCOPYRIGHTBEGIN####                                     
  * -------------------------------------------                       
  * This file is part of eCos, the Embedded Configurable Operating System.
- * Copyright (C) 2005, 2008 Free Software Foundation, Inc.                 
+ * Copyright (C) 2005, 2008, 2009 Free Software Foundation, Inc.                 
  *
  * eCos is free software; you can redistribute it and/or modify it under
  * the terms of the GNU General Public License as published by the Free
@@ -98,9 +98,9 @@ typedef struct ELF_OBJECT
 // Debug functions.
 
 #if CYGPKG_SERVICES_OBJLOADER_DEBUG_LEVEL > 0
-void       cyg_ldr_print_section_data(PELF_OBJECT);
-void       cyg_ldr_print_symbol_names(PELF_OBJECT);
-void       cyg_ldr_print_rel_names(PELF_OBJECT);
+void      cyg_ldr_print_section_data(PELF_OBJECT);
+void      cyg_ldr_print_symbol_names(PELF_OBJECT);
+cyg_int32 cyg_ldr_print_rel_names(PELF_OBJECT);
 #endif
 
 //==============================================================================
--- a/packages/services/objloader/current/src/objelf.c
+++ b/packages/services/objloader/current/src/objelf.c
@@ -51,6 +51,7 @@
  */
 
 #include <cyg/infra/diag.h>     // For diagnostic printing.
+#include <cyg/infra/cyg_ass.h>
 #include <cyg/hal/hal_tables.h>
 #include <stdio.h>
 
@@ -116,7 +117,7 @@ cyg_ldr_print_symbol_names(PELF_OBJECT p
     diag_printf("\n");
 }
 
-void 
+cyg_int32
 cyg_ldr_print_rel_names(PELF_OBJECT p)
 {
     int        i, j, r_entries, sym_index;
@@ -135,16 +136,20 @@ cyg_ldr_print_rel_names(PELF_OBJECT p)
         if ((p->p_sechdr[i].sh_type == SHT_REL) ||
                                   (p->p_sechdr[i].sh_type == SHT_RELA))
         {                                  
-            // Calculate the total number of entries in the .rela section.
+            // Calculate the total number of entries in the .rela/.rel section.
             r_entries = p->p_sechdr[i].sh_size / p->p_sechdr[i].sh_entsize;
 
             diag_printf("\n\nSymbols at: %s\n\n", 
                          p_shstrtab + p->p_sechdr[i].sh_name);
 #if ELF_ARCH_RELTYPE == Elf_Rela        
-            p_rela = (Elf32_Rela*)cyg_ldr_load_elf_section(p, i);
+            p_rela = (Elf32_Rela *)cyg_ldr_load_elf_section(p, i);
+            if (p_rela == 0)
+                return -1;
             printf("Offset    Info      Name [+ Addend]\n");
 #else
-            p_rel = (Elf32_Rel*)cyg_ldr_load_elf_section(p, i);
+            p_rel = (Elf32_Rel *)cyg_ldr_load_elf_section(p, i);
+            if (p_rel == 0)
+                return -1;
             printf("Offset    Info     Name\n");
 #endif
 
@@ -288,17 +293,21 @@ cyg_ldr_relocate_section(PELF_OBJECT p, 
 {
     int         i, rc;
 #if ELF_ARCH_RELTYPE == Elf_Rela        
-    Elf32_Rela* p_rela = (Elf32_Rela*)cyg_ldr_load_elf_section(p, r_shndx);
+    Elf32_Rela *p_rela = (Elf32_Rela *)cyg_ldr_load_elf_section(p, r_shndx);
+    if (p_rela == 0)
+        return -1;
 #else
-    Elf32_Rel*  p_rel = (Elf32_Rel*)cyg_ldr_load_elf_section(p, r_shndx);
+    Elf32_Rel *p_rel = (Elf32_Rel *)cyg_ldr_load_elf_section(p, r_shndx);
+    if (p_rel == 0)
+        return -1;
 #endif
 
 #if CYGPKG_SERVICES_OBJLOADER_DEBUG_LEVEL > 0
-    Elf32_Sym *p_symtab = (Elf32_Sym*)cyg_ldr_section_address(p, 
+    Elf32_Sym *p_symtab = (Elf32_Sym *)cyg_ldr_section_address(p, 
                                                            p->hdrndx_symtab);
-    char      *p_strtab = (char*)cyg_ldr_section_address(p, p->hdrndx_strtab);
-    char      *p_shstrtab = (char*)cyg_ldr_section_address(p, 
-                                                     p->p_elfhdr->e_shstrndx);
+    char *p_strtab = (char *)cyg_ldr_section_address(p, p->hdrndx_strtab);
+    char *p_shstrtab = (char *)cyg_ldr_section_address(p, 
+                                                       p->p_elfhdr->e_shstrndx);
 #endif
 
     // Now we can get the address of the contents of the section to modify.
@@ -311,7 +320,7 @@ cyg_ldr_relocate_section(PELF_OBJECT p, 
             p_shstrtab + p->p_sechdr[r_target_shndx].sh_name);
     diag_printf("----------------------------------------\n"); 
 #if CYGPKG_SERVICES_OBJLOADER_DEBUG_LEVEL > 1
-    diag_printf(" Ndx  Type             Offset   Name\"\n");
+    diag_printf(" Ndx  Type             Offset    Name\n");
 #endif
 #endif
 
--- a/packages/services/objloader/current/src/objloader.c
+++ b/packages/services/objloader/current/src/objloader.c
@@ -8,7 +8,7 @@
  * ####ECOSGPLCOPYRIGHTBEGIN####                                     
  * -------------------------------------------                       
  * This file is part of eCos, the Embedded Configurable Operating System.
- * Copyright (C) 2005, 2008 Free Software Foundation, Inc.                 
+ * Copyright (C) 2005, 2008, 2009 Free Software Foundation, Inc.                 
  *
  * eCos is free software; you can redistribute it and/or modify it under
  * the terms of the GNU General Public License as published by the Free
@@ -81,6 +81,8 @@ cyg_ldr_free(void *s)
 void
 cyg_ldr_delete_elf_section(PELF_OBJECT p, cyg_uint32 idx)
 {
+    if (p->sections[idx] == 0)
+        return;
     cyg_ldr_free(p->sections[idx]);
     p->sections[idx] = 0; 
 }    
@@ -94,7 +96,7 @@ cyg_ldr_free_elf_object(PELF_OBJECT p)
     cyg_int32 i;
         
     for (i = 0; i < p->p_elfhdr->e_shnum + 1; i++)
-        if (p->sections[i])
+        if (p->sections[i] != 0)
             cyg_ldr_delete_elf_section(p, i);
 
     if (p->sections != 0)
@@ -142,16 +144,27 @@ cyg_ldr_find_common_size(PELF_OBJECT p)
 cyg_uint32 
 *cyg_ldr_load_elf_section(PELF_OBJECT p, cyg_uint32 idx)
 {
-    cyg_uint32 *addr = (cyg_uint32 *)cyg_ldr_malloc(p->p_sechdr[idx].sh_size);
-    CYG_ASSERT(addr != 0, "Cannot malloc() section");
-    if (addr == 0)
+    // Make sure we are not requesting the loading of a section for which we
+    //  have no pointer.
+    CYG_ASSERT(idx < p->p_elfhdr->e_shnum + 1, "Invalid section id.");
+    
+    // If this section has already been loaded its pointer is already available
+    //  in the sections[] array.
+    if (p->sections[idx] != 0)
+        return p->sections[idx];
+    p->sections[idx] = (cyg_uint32)cyg_ldr_malloc(p->p_sechdr[idx].sh_size);
+    CYG_ASSERT(p->sections[idx] != 0, "Cannot malloc() section");
+    if (p->sections[idx] == 0)
     {
         cyg_ldr_last_error = "ERROR IN MALLOC";
         return (void*)0;
     }
     p->seek(p, p->p_sechdr[idx].sh_offset);
-    p->read(p, sizeof(char), p->p_sechdr[idx].sh_size, addr);
-    return addr;
+    p->read(p,
+            sizeof(char),
+            p->p_sechdr[idx].sh_size,
+            (void *)p->sections[idx]);
+    return p->sections[idx];
 }    
 
 // Returns the starting address of a section. If the section is not already
@@ -277,7 +290,9 @@ cyg_ldr_load_sections(PELF_OBJECT p)
     // Load the section header string table. This is a byte oriented table,
     //  so alignment is not an issue.
     idx = p->p_elfhdr->e_shstrndx;
-    p->sections[idx] = cyg_ldr_load_elf_section(p, idx);
+    cyg_uint32 section_addr = cyg_ldr_load_elf_section(p, idx);
+    if (section_addr == 0)
+        return -1;
     return 0;
 }
 
@@ -339,7 +354,7 @@ cyg_ldr_open_library(CYG_ADDRWORD ptr, c
         if (!strcmp(p_shstrtab + e_obj->p_sechdr[i].sh_name, ELF_STRING_symtab))
         {              
             e_obj->hdrndx_symtab = i;
-            e_obj->sections[i] = cyg_ldr_load_elf_section(e_obj, i);
+            cyg_ldr_load_elf_section(e_obj, i);
             if (e_obj->sections[i] == 0)
             {
                 cyg_ldr_free_elf_object(e_obj);
@@ -353,7 +368,7 @@ cyg_ldr_open_library(CYG_ADDRWORD ptr, c
         if (!strcmp(p_shstrtab + e_obj->p_sechdr[i].sh_name, ELF_STRING_strtab))
         {              
             e_obj->hdrndx_strtab = i;
-            e_obj->sections[i] = cyg_ldr_load_elf_section(e_obj, i);
+            cyg_ldr_load_elf_section(e_obj, i);
             if (e_obj->sections[i] == 0)
             {
                 cyg_ldr_free_elf_object(e_obj);