From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 27821 invoked by alias); 2 Aug 2004 21:13:36 -0000 Mailing-List: contact ecos-discuss-help@ecos.sourceware.org; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: ecos-discuss-owner@ecos.sourceware.org Received: (qmail 27795 invoked from network); 2 Aug 2004 21:13:34 -0000 Received: from unknown (HELO mx-la.paetec.net) (64.80.125.114) by sourceware.org with SMTP; 2 Aug 2004 21:13:34 -0000 Received: from dtcnt40s4.dtccom.com ([66.153.88.146]) by mx-la.paetec.net (8.12.10/8.12.10) with ESMTP id i72LDYWc012821 for ; Mon, 2 Aug 2004 17:13:34 -0400 (EDT) Received: by DTCNT40S4 with Internet Mail Service (5.5.2653.19) id ; Mon, 2 Aug 2004 17:13:31 -0400 Message-ID: From: "Doyle, Patrick" To: ecos discuss list Date: Mon, 02 Aug 2004 21:13:00 -0000 MIME-Version: 1.0 Content-Type: text/plain Subject: RE: [ECOS] binutils wizardry X-SW-Source: 2004-08/txt/msg00038.txt.bz2 Thanks to Gary, Sergei, and Andrew for the pointers... they got me started in the right direction. Since I don't maintain a web page, much less a blog, and I might want to find this again, I thought I would summarize what I learned and what I did. Perhaps somebody else might even find this useful in some bizarre set of circumstances. Anyway, my original problem was that I have an existing ELF executable that loads into memory starting at address 0x20000 and some binary data that I want associated with that executable that wants to be loaded into memory at address 0x80000. I guess I forgot to mention that I don't really want to relink my executable every time them binary data changes. Anyway, Sergei suggested $ echo | as -o elf_file $ objcopy --add-section=section_name=binary_file elf_file which transforms the binary file into a section called "section_name" in an ELF file. Andrew suggested $ objcopy -I binary -O elf32-littlemips \ --rename-section .data=.rodata,alloc,load,readonly,data,contents \ binary_file elf_file which does the same thing, but doesn't require the assembler to create a blank ELF file first, and which allows one to manipulate the flags in the section header. Once I had the ELF version of my binary file, I found that I could append it to my existing ELF image using objcopy. (Actually, using Sergei's "objcopy" command with a "--set-section-flags" argument could be used as well. Unfortunately, no matter how hard I tried, I couldn't convince RedBoot to load my newly appended section. (Also, the objcopy command produced a strange error when I tried it ("BFD: stHmId0k: warning: allocation section `blah' not in segment") but objdump showed that it did append the section to my file. Interestingly, if I converted my file to an S-Record file (using "objcopy -O srec") or to a raw binary file (using "objcopy -O binary"), my binary data showed up -- I just couldn't get RedBoot to load it directly from the ELF file. I didn't like the way that the S-Record file doubled my output file size. The binary file also increased significantly in size due to the padding of zeros between the end of my executable image (at something like 0x3a240) and the start of my data (at address 0x80000). Also, it lost the entry point information. Looking at the source code for the "load" command in RedBoot, I learned that it loaded memory based on the contents of the "program headers" rather than the contents of the "section headers". Now the error message from objcopy started to make sense (except for that "stHmId0k" part). Apparently, objcopy can manipulate section headers, but not program headers. The tool that I've always used to manipulate program headers is "ld". So, to make a long boring email even longer, what I did was to convert my executable image into a binary file (keeping track of its start address and entry point), and linked that with my data to produce a new executable with two separate program headers. RedBoot is happy to load this file. If anybody is interested (is anybody still reading at this point?) I have attached the perl script I created to perform this process. Please don't laugh too hard as you read it -- remember, you were just starting with perl once too :-) --wpd ============================================================= #!/usr/bin/perl -w use strict; my $image = "prog.img"; my $binfile = "wavefiles"; my $binaddr = "0x80000"; my $outfile = "combo"; my $tc = "arm-elf-"; # toolchain my $target = "elf32-littlearm"; my $arch = "arm"; my $bin2elf = "${tc}objcopy -I binary -O $target -B $arch"; # I wonder how I would do the "grep" part in perl. All I want to do is # to grab the one line that starts with whitespace followed by the # word "LOAD" out of the output of the "readelf" command. Would it be # more or less efficient to do it in perl? # Of course, I also need the one line that starts with "Entry point" # as well. I really should figure out how to do this idiomatically. my $image_info_line = `${tc}readelf -l $image | egrep '^[[:space:]]*LOAD'`; my @image_info = split(' ', $image_info_line); my $image_addr = $image_info[2]; my $entry_info_line = `${tc}readelf -l $image | egrep '^Entry point'`; my @entry_info = split(' ', $entry_info_line); my $entry_point = $entry_info[2]; system("${tc}objcopy -O binary $image $image.bin") == 0 or die "error creating binary image of $image"; system("$bin2elf --rename-section .data=image $image.bin $image.o") == 0 or die "error creating relocatable version of $image"; system("$bin2elf --rename-section .data=data $binfile $binfile.o") == 0 or die "error creating relocatable version of $binfile"; open TARGET, ">", "target.ld" or die "Unable to open \"target.ld\" for writing\n"; print TARGET <