This is the mail archive of the ecos-discuss@sources.redhat.com mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

RE: binutils wizardry


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 <<EOF;
SECTIONS
{
image $image_addr : { *(image) }
data  $binaddr : { *(data) }
}
EOF
close TARGET;

system("${tc}ld -e $entry_point -o $outfile -T target.ld $image.o
$binfile.o") == 0
    or die "error creating output file $outfile";

====================================================================

Patrick Doyle
DSP Design Engineer
(603) 546-2179

 

This communication is from DTC Communications, Inc. and is intended to be
confidential and solely for the use of the persons or entities addressed
above.  If you are not an intended recipient, be aware that the information
contained herein may be protected from unauthorized use by privilege or law,
and any copying, distribution, disclosure, or other use of this information
is prohibited.  If you have received this communication in error, please
contact the sender by return e-mail or telephone the above number
immediately and delete or destroy all copies.  Thank you for your
cooperation.

 



-- 
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]