OSDN Git Service

Since the nios2 port is the only one to use the get_gp_value() function,
[uclinux-h8/elf2flt.git] / elf2flt.c
index 17a8b69..9ff0299 100644 (file)
--- a/elf2flt.c
+++ b/elf2flt.c
@@ -54,6 +54,7 @@
 
 /* from $(INSTALLDIR)/include       */
 #include <bfd.h>      /* Main header file for the BFD library                */
+#include <libiberty.h>
 
 #if defined(TARGET_h8300)
 #include <elf/h8.h>      /* TARGET_* ELF support for the BFD library            */
@@ -73,6 +74,7 @@
 
 /* from uClinux-x.x.x/include/linux */
 #include "flat.h"     /* Binary flat header description                      */
+#include "compress.h"
 
 #ifdef TARGET_e1
 #include <e1.h>
@@ -142,7 +144,7 @@ int verbose = 0;      /* extra output when running */
 int pic_with_got = 0; /* do elf/got processing with PIC code */
 int load_to_ram = 0;  /* instruct loader to allocate everything into RAM */
 int ktrace = 0;       /* instruct loader output kernel trace on load */
-int compress = 0;     /* 1 = compress everything, 2 = compress data only */
+int docompress = 0;   /* 1 = compress everything, 2 = compress data only */
 int use_resolved = 0; /* If true, get the value of symbol references from */
                      /* the program contents, not from the relocation table. */
                      /* In this case, the input ELF file must be already */
@@ -223,7 +225,7 @@ einfo (int type, const char *format, ...) {
 asymbol**
 get_symbols (bfd *abfd, long *num)
 {
-  long storage_needed;
+  int32_t storage_needed;
   asymbol **symbol_table;
   long number_of_symbols;
   
@@ -235,7 +237,7 @@ get_symbols (bfd *abfd, long *num)
   if (storage_needed == 0)
     return NULL;
 
-  symbol_table = (asymbol **) malloc (storage_needed);
+  symbol_table = xmalloc (storage_needed);
 
   number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table);
   
@@ -279,6 +281,7 @@ get_symbol_offset(char *name, asection *sec, asymbol **symbol_table, long number
 
 
 
+#ifdef TARGET_nios2
 long
 get_gp_value(asymbol **symbol_table, long number_of_symbols)
 {
@@ -289,14 +292,15 @@ get_gp_value(asymbol **symbol_table, long number_of_symbols)
   }
   return -1;
 }
+#endif
 
 
-long
-add_com_to_bss(asymbol **symbol_table, long number_of_symbols, long bss_len)
+
+int32_t
+add_com_to_bss(asymbol **symbol_table, int32_t number_of_symbols, int32_t bss_len)
 {
-  long i, comsize;
-  long offset;
+  int32_t i, comsize;
+  int32_t offset;
 
   comsize = 0;
   for (i=0; i<number_of_symbols; i++) {
@@ -382,9 +386,9 @@ output_relocs (
   bfd *abs_bfd,
   asymbol **symbols,
   int number_of_symbols,
-  unsigned long *n_relocs,
-  unsigned char *text, int text_len, unsigned long text_vma,
-  unsigned char *data, int data_len, unsigned long data_vma,
+  uint32_t *n_relocs,
+  unsigned char *text, int text_len, uint32_t text_vma,
+  unsigned char *data, int data_len, uint32_t data_vma,
   bfd *rel_bfd)
 {
   uint32_t             *flat_relocs;
@@ -394,7 +398,7 @@ output_relocs (
   unsigned char                *sectionp;
   unsigned long                pflags;
   char                 addstr[16];
-  long                 sym_addr, sym_vma, section_vma;
+  uint32_t             sym_addr, sym_vma, section_vma;
   int                  relsize, relcount;
   int                  flat_reloc_count;
   int                  sym_reloc_size, rc;
@@ -426,13 +430,13 @@ dump_symbols(symbols, number_of_symbols);
    * terminator even though the relocatable one doesn't have the GOT!
    */
   if (pic_with_got && !use_resolved) {
-    unsigned long *lp = (unsigned long *)data;
+    uint32_t *lp = (uint32_t *)data;
     /* Should call ntohl(*lp) here but is isn't going to matter */
     while (*lp != 0xffffffff) lp++;
     got_size = ((unsigned char *)lp) - data;
     if (verbose)
            printf("GOT table contains %d entries (%d bytes)\n",
-                           got_size/sizeof(unsigned long), got_size);
+                           got_size/sizeof(uint32_t), got_size);
 #ifdef TARGET_m68k
     if (got_size > GOT_LIMIT) {
            fprintf(stderr, "GOT too large: %d bytes (limit = %d bytes)\n",
@@ -492,7 +496,8 @@ dump_symbols(symbols, number_of_symbols);
        }
 
        symb = get_symbols(rel_bfd, &nsymb);
-       relpp = (arelent **) xmalloc(relsize);
+       relpp = xmalloc(relsize);
+
        relcount = bfd_canonicalize_reloc(rel_bfd, r, relpp, symb);
        if (relcount <= 0) {
                if (verbose)
@@ -727,7 +732,7 @@ dump_symbols(symbols, number_of_symbols);
                                           give an error by default, and
                                           require `safe' relocations to be
                                           enumberated explicitly?).  */
-                                       goto good_32bit_resolve_reloc;
+                                       goto good_32bit_resolved_reloc;
 #endif
                                good_32bit_resolved_reloc:
                                        if (bfd_big_endian (abs_bfd))
@@ -792,7 +797,7 @@ dump_symbols(symbols, number_of_symbols);
                                                        sym_vma, (*(q->sym_ptr_ptr))->value,
                                                        q->address, sym_addr,
                                                        (*p)->howto->rightshift,
-                                                       *(unsigned long *)r_mem);
+                                                       *(uint32_t *)r_mem);
                                        sym_vma = bfd_section_vma(abs_bfd, sym_section);
                                        sym_addr += sym_vma + q->addend;
                                        break;
@@ -809,7 +814,7 @@ dump_symbols(symbols, number_of_symbols);
                                                        sym_vma, (*(q->sym_ptr_ptr))->value,
                                                        q->address, sym_addr,
                                                        (*p)->howto->rightshift,
-                                                       *(unsigned long *)r_mem);
+                                                       *(uint32_t *)r_mem);
                                case R_ARM_PC24:
                                        sym_vma = 0;
                                        sym_addr = (sym_addr-q->address)>>(*p)->howto->rightshift;
@@ -900,7 +905,7 @@ dump_symbols(symbols, number_of_symbols);
                   the relocation symbol. */
                                {
                                        unsigned char *p = r_mem;
-                                       unsigned long offset;
+                                       uint32_t offset;
                                        pflags=0x80000000;
 
                                        /* work out the relocation */
@@ -979,8 +984,6 @@ dump_symbols(symbols, number_of_symbols);
 #ifdef TARGET_nios2
 #define  htoniosl(x)   (x)
 #define  niostohl(x)   (x)
-                       switch ((*p)->howto->type) 
-                       {
                                case R_NIOS2_BFD_RELOC_32:
                                        relocation_needed = 1;
                                        pflags = (FLAT_NIOS2_R_32 << 28);
@@ -1133,7 +1136,6 @@ NIOS2_RELOC_ERR:
                                        printf("Err: unexpected reloc type %s(%d)\n", q->howto->name, q->howto->type);
                                        bad_relocs++;
                                        continue;
-                       }
 #endif /* TARGET_nios2 */
 
 #ifdef TARGET_sparc
@@ -1152,7 +1154,7 @@ NIOS2_RELOC_ERR:
                                        sym_addr = (((*(q->sym_ptr_ptr))->value-
                                                q->address) >> 2) & 0x3fffffff;
                                        sym_addr |= (
-                                               ntohl(*(unsigned long *)r_mem)
+                                               ntohl(*(uint32_t *)r_mem)
                                                & 0xc0000000
                                                );
                                        break;
@@ -1162,7 +1164,7 @@ NIOS2_RELOC_ERR:
                                        sym_vma = bfd_section_vma(abs_bfd, sym_section);
                                        sym_addr += sym_vma + q->addend;
                                        sym_addr |= (
-                                               htonl(*(unsigned long *)r_mem)
+                                               htonl(*(uint32_t *)r_mem)
                                                & 0xffc00000
                                                );
                                        break;
@@ -1173,7 +1175,7 @@ NIOS2_RELOC_ERR:
                                        sym_addr += sym_vma + q->addend;
                                        sym_addr &= 0x000003ff;
                                        sym_addr |= (
-                                               htonl(*(unsigned long *)r_mem)
+                                               htonl(*(uint32_t *)r_mem)
                                                & 0xfffffc00
                                                );
                                        break;
@@ -1493,9 +1495,9 @@ DIS29_RELOCATION:
 #if defined(TARGET_arm)
                                union {
                                        unsigned char c[4];
-                                       unsigned long l;
+                                       uint32_t l;
                                } tmp;
-                               long hl;
+                               int32_t hl;
                                int i0, i1, i2, i3;
 
                                /*
@@ -1513,7 +1515,7 @@ DIS29_RELOCATION:
                                        i3 = 0;
                                }
 
-                               tmp.l = *(unsigned long *)r_mem;
+                               tmp.l = *(uint32_t *)r_mem;
                                hl = tmp.c[i0] | (tmp.c[i1] << 8) | (tmp.c[i2] << 16);
                                if (use_resolved ||
                                        (((*p)->howto->type != R_ARM_PC24) &&
@@ -1531,9 +1533,9 @@ DIS29_RELOCATION:
                                        ((*p)->howto->type != R_ARM_PLT32)))
                                        tmp.c[i3] = (hl >> 24) & 0xff;
                                if ((*p)->howto->type == R_ARM_ABS32)
-                                       *(unsigned long *)r_mem = htonl(hl);
+                                       *(uint32_t *)r_mem = htonl(hl);
                                else
-                                       *(unsigned long *)r_mem = tmp.l;
+                                       *(uint32_t *)r_mem = tmp.l;
 
 #elif defined(TARGET_bfin)
                                if ((*p)->howto->type == R_pcrel24
@@ -1769,7 +1771,7 @@ static void usage(void)
 
 
 /* Write NUM zeroes to STREAM.  */
-static void write_zeroes (unsigned long num, FILE *stream)
+static void write_zeroes (unsigned long num, stream *stream)
 {
   char zeroes[1024];
   if (num > 0) {
@@ -1777,11 +1779,11 @@ static void write_zeroes (unsigned long num, FILE *stream)
        work for stdio output files.  */
     memset(zeroes, 0x00, 1024);
     while (num > sizeof(zeroes)) {
-      fwrite(zeroes, sizeof(zeroes), 1, stream);
+      fwrite_stream(zeroes, sizeof(zeroes), 1, stream);
       num -= sizeof(zeroes);
     }
     if (num > 0)
-      fwrite(zeroes, num, 1, stream);
+      fwrite_stream(zeroes, num, 1, stream);
   }
 }
 
@@ -1796,22 +1798,21 @@ int main(int argc, char *argv[])
   int opt;
   int i;
   int stack;
-  char  cmd[1024];
-  FILE *gf = NULL;
+  stream gf;
 
   asymbol **symbol_table;
   long number_of_symbols;
 
-  unsigned long data_len = 0;
-  unsigned long bss_len = 0;
-  unsigned long text_len = 0;
-  unsigned long reloc_len;
+  uint32_t data_len = 0;
+  uint32_t bss_len = 0;
+  uint32_t text_len = 0;
+  uint32_t reloc_len;
 
-  unsigned long data_vma = ~0;
-  unsigned long bss_vma = ~0;
-  unsigned long text_vma = ~0;
+  uint32_t data_vma = ~0;
+  uint32_t bss_vma = ~0;
+  uint32_t text_vma = ~0;
 
-  unsigned long text_offs;
+  uint32_t text_offs;
 
   void *text;
   void *data;
@@ -1819,10 +1820,9 @@ int main(int argc, char *argv[])
   
   struct flat_hdr hdr;
 
-  int gf_is_pipe = 0;
-
   program = argv[0];
   progname = argv[0];
+  xmalloc_set_program_name(program);
 
   if (argc < 2)
        usage();
@@ -1853,10 +1853,10 @@ int main(int argc, char *argv[])
       ktrace++;
       break;
     case 'z':
-      compress = 1;
+      docompress = 1;
       break;
     case 'd':
-      compress = 2;
+      docompress = 2;
       break;
     case 'p':
       pfile = optarg;
@@ -1868,7 +1868,10 @@ int main(int argc, char *argv[])
       use_resolved = 1;
       break;
     case 's':
-      stack = atoi(optarg);
+      if (sscanf(optarg, "%i", &stack) != 1) {
+        fprintf(stderr, "%s invalid stack size %s\n", argv[0], optarg);
+        usage();
+      }
       break;
     case 'R':
       rel_file = optarg;
@@ -1940,7 +1943,7 @@ int main(int argc, char *argv[])
 
   /* Group output sections into text, data, and bss, and calc their sizes.  */
   for (s = abs_bfd->sections; s != NULL; s = s->next) {
-    unsigned long *vma, *len;
+    uint32_t *vma, *len;
     bfd_size_type sec_size;
     bfd_vma sec_vma;
 
@@ -1974,7 +1977,7 @@ int main(int argc, char *argv[])
     exit (2);
   }
 
-  text = malloc(text_len);
+  text = xmalloc(text_len);
 
   if (verbose)
     printf("TEXT -> vma=0x%x len=0x%x\n", text_vma, text_len);
@@ -1994,7 +1997,7 @@ int main(int argc, char *argv[])
     fprintf (stderr, "%s: no .data section", abs_file);
     exit (2);
   }
-  data = malloc(data_len);
+  data = xmalloc(data_len);
 
   if (verbose)
     printf("DATA -> vma=0x%x len=0x%x\n", data_vma, data_len);
@@ -2021,6 +2024,9 @@ int main(int argc, char *argv[])
        exit(2);
       }
 
+  if (bss_vma == ~0)
+    bss_vma = data_vma + data_len;
+
   /* Put common symbols in bss.  */
   bss_len += add_com_to_bss(symbol_table, number_of_symbols, bss_len);
 
@@ -2039,9 +2045,9 @@ int main(int argc, char *argv[])
     data_len = bss_vma - data_vma;
   }
 
-  reloc = output_relocs(abs_bfd, symbol_table, number_of_symbols, &reloc_len,
-                       text, text_len, text_vma, data, data_len, data_vma,
-                       rel_bfd);
+  reloc = (uint32_t *)
+    output_relocs(abs_bfd, symbol_table, number_of_symbols, &reloc_len,
+                 text, text_len, text_vma, data, data_len, data_vma, rel_bfd);
 
   if (reloc == NULL)
     printf("No relocations in code!\n");
@@ -2062,9 +2068,9 @@ int main(int argc, char *argv[])
          | (load_to_ram ? FLAT_FLAG_RAM : 0)
          | (ktrace ? FLAT_FLAG_KTRACE : 0)
          | (pic_with_got ? FLAT_FLAG_GOTPIC : 0)
-         | (compress ? (compress == 2 ? FLAT_FLAG_GZDATA : FLAT_FLAG_GZIP) : 0)
+         | (docompress ? (docompress == 2 ? FLAT_FLAG_GZDATA : FLAT_FLAG_GZIP) : 0)
          );
-  hdr.build_date = htonl((unsigned long)time(NULL));
+  hdr.build_date = htonl((uint32_t)time(NULL));
   memset(hdr.filler, 0x00, sizeof(hdr.filler));
 
   for (i=0; i<reloc_len; i++) reloc[i] = htonl(reloc[i]);
@@ -2078,7 +2084,7 @@ int main(int argc, char *argv[])
   }
   
   if (!ofile) {
-    ofile = malloc(strlen(fname) + 5 + 1); /* 5 to add suffix */
+    ofile = xmalloc(strlen(fname) + 5 + 1); /* 5 to add suffix */
     strcpy(ofile, fname);
     strcat(ofile, ".bflt");
   }
@@ -2091,54 +2097,32 @@ int main(int argc, char *argv[])
   write(fd, &hdr, sizeof(hdr));
   close(fd);
 
-  /*
-   * get the compression command ready
-   */
-  sprintf(cmd, "gzip -f -9 >> %s", ofile);
-
-#define        START_COMPRESSOR do { \
-               if (gf) \
-                       if (gf_is_pipe) \
-                               pclose(gf); \
-                       else \
-                               fclose(gf); \
-               if (!(gf = popen(cmd, "w" BINARY_FILE_OPTS))) { \
-                       fprintf(stderr, "Can't run cmd %s\n", cmd); \
-                       exit(4); \
-               } \
-               gf_is_pipe = 1; \
-       } while (0)
-
-  gf = fopen(ofile, "ab");     /* Add 'b' to support non-posix (ie windows) */
-  if (!gf) {
-       fprintf(stderr, "Can't open file %s for writing\n", ofile); \
-       exit(4);
+  if (fopen_stream_u(&gf, ofile, "a" BINARY_FILE_OPTS)) {
+    fprintf(stderr, "Can't open file %s for writing\n", ofile);
+    exit(4);
   }
 
-  if (compress == 1)
-       START_COMPRESSOR;
+  if (docompress == 1)
+    reopen_stream_compressed(&gf);
 
   /* Fill in any hole at the beginning of the text segment.  */
   if (verbose)
-         printf("ZERO before text len=0x%x\n", text_offs);
-  write_zeroes(text_offs, gf);
+    printf("ZERO before text len=0x%x\n", text_offs);
+  write_zeroes(text_offs, &gf);
 
   /* Write the text segment.  */
-  fwrite(text, text_len, 1, gf);
+  fwrite_stream(text, text_len, 1, &gf);
 
-  if (compress == 2)
-       START_COMPRESSOR;
+  if (docompress == 2)
+    reopen_stream_compressed(&gf);
 
   /* Write the data segment.  */
-  fwrite(data, data_len, 1, gf);
+  fwrite_stream(data, data_len, 1, &gf);
 
   if (reloc)
-    fwrite(reloc, reloc_len * 4, 1, gf);
+    fwrite_stream(reloc, reloc_len * 4, 1, &gf);
 
-  if(gf_is_pipe)
-    pclose(gf);
-  else
-  fclose(gf);
+  fclose_stream(&gf);
 
   exit(0);
 }