diff -r -U 5 -N -x CVS -x '*~' -x '.#~' /home/atonizzo/ecos/ecos-objloader/clean/eCos.hhc /home/atonizzo/ecos/ecos-objloader/devo/eCos.hhc
--- /home/atonizzo/ecos/ecos-objloader/clean/eCos.hhc	1969-12-31 16:00:00.000000000 -0800
+++ /home/atonizzo/ecos/ecos-objloader/devo/eCos.hhc	2009-08-24 10:04:38.000000000 -0700
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<HTML>
+<HEAD>
+<meta name="GENERATOR" content="Microsoft&reg; HTML Help Workshop 4.1">
+<!-- Sitemap 1.0 -->
+</HEAD><BODY>
+<UL>
+</UL>
+</BODY></HTML>
\ No newline at end of file
diff -r -U 5 -N -x CVS -x '*~' -x '.#~' /home/atonizzo/ecos/ecos-objloader/clean/eCos.hhp /home/atonizzo/ecos/ecos-objloader/devo/eCos.hhp
--- /home/atonizzo/ecos/ecos-objloader/clean/eCos.hhp	1969-12-31 16:00:00.000000000 -0800
+++ /home/atonizzo/ecos/ecos-objloader/devo/eCos.hhp	2009-08-24 10:04:38.000000000 -0700
@@ -0,0 +1,19 @@
+[OPTIONS]
+Auto Index=Yes
+Binary Index=No
+Compatibility=1.1 or later
+Compiled file=eCos.chm
+Contents file=eCos.hhc
+Default Window=mainwin
+Default topic=/home/atonizzo/ecos/ecos-objloader/devo/doc/index.html
+Display compile progress=Yes
+Full-text search=Yes
+Language=0x409 English (United States)
+Title=eCos Documentation
+[WINDOWS]
+mainwin="eCos Documentation","eCos.hhc",,,"index.html","http://sources.redhat.com/ecos/","Net Release","http://www.redhat.com/products/ecos/","eCos Product",0x40060420,,0xc287e,[0,0,762,400],,,,,,,0
+
+[FILES]
+index.html
+
+[INFOTYPES]
diff -r -U 5 -N -x CVS -x '*~' -x '.#~' /home/atonizzo/ecos/ecos-objloader/clean/packages/services/objloader/current/ChangeLog /home/atonizzo/ecos/ecos-objloader/devo/packages/services/objloader/current/ChangeLog
--- /home/atonizzo/ecos/ecos-objloader/clean/packages/services/objloader/current/ChangeLog	2009-07-03 07:49:44.000000000 -0700
+++ /home/atonizzo/ecos/ecos-objloader/devo/packages/services/objloader/current/ChangeLog	2009-09-14 10:10:14.000000000 -0700
@@ -1,5 +1,13 @@
+2009-09-13  Anthony Tonizzo  <atonizzo@gmail.com>
+    * src/objloader.c :
+    * src/objelf.c : 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().
+
 2009-07-03  John Dallaway  <john@dallaway.org.uk>
 
 	* cdl/objloader.cdl, src/objelf.c, src/relocate_ppc.c,
 	  src/relocate_arm.c: Eliminate dependency on CYGPKG_IO_FILEIO when
 	the filesystem loader is not required.
diff -r -U 5 -N -x CVS -x '*~' -x '.#~' /home/atonizzo/ecos/ecos-objloader/clean/packages/services/objloader/current/include/objelf.h /home/atonizzo/ecos/ecos-objloader/devo/packages/services/objloader/current/include/objelf.h
--- /home/atonizzo/ecos/ecos-objloader/clean/packages/services/objloader/current/include/objelf.h	2009-07-03 07:49:44.000000000 -0700
+++ /home/atonizzo/ecos/ecos-objloader/devo/packages/services/objloader/current/include/objelf.h	2009-08-26 09:46:49.000000000 -0700
@@ -96,13 +96,13 @@
 
 //==============================================================================
 // 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
 
 //==============================================================================
 // Internal functions
 
diff -r -U 5 -N -x CVS -x '*~' -x '.#~' /home/atonizzo/ecos/ecos-objloader/clean/packages/services/objloader/current/src/objelf.c /home/atonizzo/ecos/ecos-objloader/devo/packages/services/objloader/current/src/objelf.c
--- /home/atonizzo/ecos/ecos-objloader/clean/packages/services/objloader/current/src/objelf.c	2009-07-03 07:49:45.000000000 -0700
+++ /home/atonizzo/ecos/ecos-objloader/devo/packages/services/objloader/current/src/objelf.c	2009-08-26 09:57:46.000000000 -0700
@@ -49,10 +49,11 @@
  * 
  * =================================================================
  */
 
 #include <cyg/infra/diag.h>     // For diagnostic printing.
+#include <cyg/infra/cyg_ass.h>
 #include <cyg/hal/hal_tables.h>
 #include <stdio.h>
 
 #include <pkgconf/objloader.h>
 #include <cyg/objloader/elf.h>
@@ -114,11 +115,11 @@
                     p_symtab[i].st_shndx,
                     p_strtab + p_symtab[i].st_name);
     diag_printf("\n");
 }
 
-void 
+cyg_int32
 cyg_ldr_print_rel_names(PELF_OBJECT p)
 {
     int        i, j, r_entries, sym_index;
     Elf32_Sym *p_symtab = (Elf32_Sym*)p->sections[p->hdrndx_symtab];
     char      *p_strtab = (char*)p->sections[p->hdrndx_strtab];
@@ -133,20 +134,24 @@
     for (i = 1; i < p->p_elfhdr->e_shnum; i++)
     {
         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
 
             for (j = 0; j < r_entries; j++)
             {
@@ -286,21 +291,25 @@
 cyg_int32 
 cyg_ldr_relocate_section(PELF_OBJECT p, cyg_uint32 r_shndx)
 {
     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.
     cyg_uint32 r_target_shndx = p->p_sechdr[r_shndx].sh_info;
     cyg_uint32 r_target_addr  = (cyg_uint32)cyg_ldr_section_address(p, 
@@ -309,11 +318,11 @@
 #if CYGPKG_SERVICES_OBJLOADER_DEBUG_LEVEL > 0
     diag_printf("Relocating section \"%s\"\n",
             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
 
     // Perform relocatation for each of the members of this table.
     cyg_uint32 r_entries = p->p_sechdr[r_shndx].sh_size / 
diff -r -U 5 -N -x CVS -x '*~' -x '.#~' /home/atonizzo/ecos/ecos-objloader/clean/packages/services/objloader/current/src/objloader.c /home/atonizzo/ecos/ecos-objloader/devo/packages/services/objloader/current/src/objloader.c
--- /home/atonizzo/ecos/ecos-objloader/clean/packages/services/objloader/current/src/objloader.c	2009-07-03 07:49:45.000000000 -0700
+++ /home/atonizzo/ecos/ecos-objloader/devo/packages/services/objloader/current/src/objloader.c	2009-08-28 13:03:37.000000000 -0700
@@ -79,10 +79,12 @@
 }
 
 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; 
 }    
 
 // Frees all the memory allocated for a particular ELF object. Also calls
@@ -92,11 +94,11 @@
 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)
         cyg_ldr_free(p->sections); 
 
@@ -140,20 +142,31 @@
 // Allocates memory and loads the contents of a specific ELF section.
 // Returns the address of the newly allocated memory, of 0 for any error.
 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
 //  loaded in memory, area for it will be allocated and the section will be
 //  loaded.
@@ -275,11 +288,13 @@
     p->read(p, p->p_elfhdr->e_shentsize, p->p_elfhdr->e_shnum, p->p_sechdr);
     
     // 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;
 }
 
 PELF_OBJECT
 cyg_ldr_open_library(CYG_ADDRWORD ptr, cyg_int32 mode)
@@ -337,11 +352,11 @@
         // Now look for the index of .symtab. These are the symbols needed for 
         //  the symbol retrieval as well as relocation.
         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);
                 return 0;
             }    
@@ -351,11 +366,11 @@
         //  to compare the name of external references symbols against the
         //  names in the in the CYG_HAL_TABLE provided by the user.
         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);
                 return 0;
             }    
