Add bfd_get_file_size to get archive element size

We can't use stat() to get archive element size.  Add bfd_get_file_size
to get size for both normal files and archive elements.

bfd/

	PR binutils/21519
	* bfdio.c (bfd_get_file_size): New function.
	* bfd-in2.h: Regenerated.

binutils/

	PR binutils/21519
	* objdump.c (dump_relocs_in_section): Replace get_file_size
	with bfd_get_file_size to get archive element size.
	* testsuite/binutils-all/objdump.exp (test_objdump_f): New
	proc.
	(test_objdump_h): Likewise.
	(test_objdump_t): Likewise.
	(test_objdump_r): Likewise.
	(test_objdump_s): Likewise.
	Add objdump tests on archive.
This commit is contained in:
H.J. Lu 2017-05-30 06:34:05 -07:00
parent 08c3f6d234
commit 8e2f54bcee
6 changed files with 170 additions and 54 deletions

View File

@ -1,3 +1,9 @@
2017-05-30 H.J. Lu <hongjiu.lu@intel.com>
PR binutils/21519
* bfdio.c (bfd_get_file_size): New function.
* bfd-in2.h: Regenerated.
2017-05-23 Dilian Palauzov <git-dpa@aegee.org>
* elf32-arc.c (arc_elf_merge_attributes): Add fall through

View File

@ -1242,6 +1242,8 @@ long bfd_get_mtime (bfd *abfd);
file_ptr bfd_get_size (bfd *abfd);
file_ptr bfd_get_file_size (bfd *abfd);
void *bfd_mmap (bfd *abfd, void *addr, bfd_size_type len,
int prot, int flags, file_ptr offset,
void **map_addr, bfd_size_type *map_len);

View File

@ -434,6 +434,29 @@ bfd_get_size (bfd *abfd)
return buf.st_size;
}
/*
FUNCTION
bfd_get_file_size
SYNOPSIS
file_ptr bfd_get_file_size (bfd *abfd);
DESCRIPTION
Return the file size (as read from file system) for the file
associated with BFD @var{abfd}. It supports both normal files
and archive elements.
*/
file_ptr
bfd_get_file_size (bfd *abfd)
{
if (abfd->my_archive != NULL
&& !bfd_is_thin_archive (abfd->my_archive))
return arelt_size (abfd);
return bfd_get_size (abfd);
}
/*
FUNCTION

View File

@ -1,3 +1,16 @@
2017-05-30 H.J. Lu <hongjiu.lu@intel.com>
PR binutils/21519
* objdump.c (dump_relocs_in_section): Replace get_file_size
with bfd_get_file_size to get archive element size.
* testsuite/binutils-all/objdump.exp (test_objdump_f): New
proc.
(test_objdump_h): Likewise.
(test_objdump_t): Likewise.
(test_objdump_r): Likewise.
(test_objdump_s): Likewise.
Add objdump tests on archive.
2017-05-24 Yao Qi <yao.qi@linaro.org>
* objdump.c (disassemble_data): Caller update.

View File

@ -3382,7 +3382,7 @@ dump_relocs_in_section (bfd *abfd,
}
if ((bfd_get_file_flags (abfd) & (BFD_IN_MEMORY | BFD_LINKER_CREATED)) == 0
&& relsize > get_file_size (bfd_get_filename (abfd)))
&& relsize > bfd_get_file_size (abfd))
{
printf (" (too many: 0x%x)\n", section->reloc_count);
bfd_set_error (bfd_error_file_truncated);

View File

@ -64,96 +64,168 @@ if [regexp $want $got] then {
if {![binutils_assemble $srcdir/$subdir/bintest.s tmpdir/bintest.o]} then {
return
}
if {![binutils_assemble $srcdir/$subdir/bintest.s tmpdir/bintest2.o]} then {
return
}
if [is_remote host] {
set testfile [remote_download host tmpdir/bintest.o]
set testfile2 [remote_download host tmpdir/bintest2.o]
} else {
set testfile tmpdir/bintest.o
set testfile2 tmpdir/bintest2.o
}
if { ![istarget "alpha-*-*"] || [is_elf_format] } then {
remote_file host file delete tmpdir/bintest.a
set got [binutils_run $AR "rc tmpdir/bintest.a $testfile2"]
if ![string match "" $got] then {
fail "bintest.a"
remote_file host delete tmpdir/bintest.a
} else {
if [is_remote host] {
set testarchive [remote_download host tmpdir/bintest.a]
} else {
set testarchive tmpdir/bintest.a
}
}
remote_file host delete tmpdir/bintest2.o
}
# Test objdump -f
set got [binutils_run $OBJDUMP "$OBJDUMPFLAGS -f $testfile"]
proc test_objdump_f { testfile dumpfile } {
global OBJDUMP
global OBJDUMPFLAGS
global cpus_regex
set want "$testfile:\[ \]*file format.*architecture:\[ \]*${cpus_regex}.*HAS_RELOC.*HAS_SYMS"
set got [binutils_run $OBJDUMP "$OBJDUMPFLAGS -f $testfile"]
if ![regexp $want $got] then {
fail "objdump -f"
} else {
pass "objdump -f"
set want "$dumpfile:\[ \]*file format.*architecture:\[ \]*${cpus_regex}.*HAS_RELOC.*HAS_SYMS"
if ![regexp $want $got] then {
fail "objdump -f ($testfile, $dumpfile)"
} else {
pass "objdump -f ($testfile, $dumpfile)"
}
}
test_objdump_f $testfile $testfile
if { [ remote_file host exists $testarchive ] } then {
test_objdump_f $testarchive bintest2.o
}
# Test objdump -h
set got [binutils_run $OBJDUMP "$OBJDUMPFLAGS -h $testfile"]
proc test_objdump_h { testfile dumpfile } {
global OBJDUMP
global OBJDUMPFLAGS
set want "$testfile:\[ \]*file format.*Sections.*\[0-9\]+\[ \]+\[^ \]*(text|TEXT|P|\\\$CODE\\\$)\[^ \]*\[ \]*(\[0-9a-fA-F\]+).*\[0-9\]+\[ \]+\[^ \]*(\\.data|DATA|D_1)\[^ \]*\[ \]*(\[0-9a-fA-F\]+)"
set got [binutils_run $OBJDUMP "$OBJDUMPFLAGS -h $testfile"]
if ![regexp $want $got all text_name text_size data_name data_size] then {
fail "objdump -h"
} else {
verbose "text name is $text_name size is $text_size"
verbose "data name is $data_name size is $data_size"
set ets 8
set eds 4
# The [ti]c4x target has the property sizeof(char)=sizeof(long)=1
if [istarget *c4x*-*-*] then {
set ets 2
set eds 1
}
# c54x section sizes are in bytes, not octets; adjust accordingly
if [istarget *c54x*-*-*] then {
set ets 4
set eds 2
}
if {[expr "0x$text_size"] < $ets || [expr "0x$data_size"] < $eds} then {
send_log "sizes too small\n"
fail "objdump -h"
set want "$dumpfile:\[ \]*file format.*Sections.*\[0-9\]+\[ \]+\[^ \]*(text|TEXT|P|\\\$CODE\\\$)\[^ \]*\[ \]*(\[0-9a-fA-F\]+).*\[0-9\]+\[ \]+\[^ \]*(\\.data|DATA|D_1)\[^ \]*\[ \]*(\[0-9a-fA-F\]+)"
if ![regexp $want $got all text_name text_size data_name data_size] then {
fail "objdump -h ($testfile, $dumpfile)"
} else {
pass "objdump -h"
verbose "text name is $text_name size is $text_size"
verbose "data name is $data_name size is $data_size"
set ets 8
set eds 4
# The [ti]c4x target has the property sizeof(char)=sizeof(long)=1
if [istarget *c4x*-*-*] then {
set ets 2
set eds 1
}
# c54x section sizes are in bytes, not octets; adjust accordingly
if [istarget *c54x*-*-*] then {
set ets 4
set eds 2
}
if {[expr "0x$text_size"] < $ets || [expr "0x$data_size"] < $eds} then {
send_log "sizes too small\n"
fail "objdump -h ($testfile, $dumpfile)"
} else {
pass "objdump -h ($testfile, $dumpfile)"
}
}
}
test_objdump_h $testfile $testfile
if { [ remote_file host exists $testarchive ] } then {
test_objdump_h $testarchive bintest2.o
}
# Test objdump -t
set got [binutils_run $OBJDUMP "$OBJDUMPFLAGS -t $testfile"]
proc test_objdump_t { testfile} {
global OBJDUMP
global OBJDUMPFLAGS
if [info exists vars] then { unset vars }
while {[regexp "(\[a-z\]*_symbol)(.*)" $got all symbol rest]} {
set vars($symbol) 1
set got $rest
set got [binutils_run $OBJDUMP "$OBJDUMPFLAGS -t $testfile"]
if [info exists vars] then { unset vars }
while {[regexp "(\[a-z\]*_symbol)(.*)" $got all symbol rest]} {
set vars($symbol) 1
set got $rest
}
if {![info exists vars(text_symbol)] \
|| ![info exists vars(data_symbol)] \
|| ![info exists vars(common_symbol)] \
|| ![info exists vars(external_symbol)]} then {
fail "objdump -t ($testfile)"
} else {
pass "objdump -t ($testfile)"
}
}
if {![info exists vars(text_symbol)] \
|| ![info exists vars(data_symbol)] \
|| ![info exists vars(common_symbol)] \
|| ![info exists vars(external_symbol)]} then {
fail "objdump -t"
} else {
pass "objdump -t"
test_objdump_t $testfile
if { [ remote_file host exists $testarchive ] } then {
test_objdump_t $testarchive
}
# Test objdump -r
set got [binutils_run $OBJDUMP "$OBJDUMPFLAGS -r $testfile"]
proc test_objdump_r { testfile dumpfile } {
global OBJDUMP
global OBJDUMPFLAGS
set want "$testfile:\[ \]*file format.*RELOCATION RECORDS FOR \\\[\[^\]\]*(text|TEXT|P|\\\$CODE\\\$)\[^\]\]*\\\].*external_symbol"
set got [binutils_run $OBJDUMP "$OBJDUMPFLAGS -r $testfile"]
if [regexp $want $got] then {
pass "objdump -r"
} else {
fail "objdump -r"
set want "$dumpfile:\[ \]*file format.*RELOCATION RECORDS FOR \\\[\[^\]\]*(text|TEXT|P|\\\$CODE\\\$)\[^\]\]*\\\].*external_symbol"
if [regexp $want $got] then {
pass "objdump -r ($testfile, $dumpfile)"
} else {
fail "objdump -r ($testfile, $dumpfile)"
}
}
test_objdump_r $testfile $testfile
if { [ remote_file host exists $testarchive ] } then {
test_objdump_r $testarchive bintest2.o
}
# Test objdump -s
set got [binutils_run $OBJDUMP "$OBJDUMPFLAGS -s $testfile"]
proc test_objdump_s { testfile dumpfile } {
global OBJDUMP
global OBJDUMPFLAGS
set want "$testfile:\[ \]*file format.*Contents.*(text|TEXT|P|\\\$CODE\\\$)\[^0-9\]*\[ \]*\[0-9a-fA-F\]*\[ \]*(00000001|01000000|00000100).*Contents.*(data|DATA|D_1)\[^0-9\]*\[ \]*\[0-9a-fA-F\]*\[ \]*(00000002|02000000|00000200)"
set got [binutils_run $OBJDUMP "$OBJDUMPFLAGS -s $testfile"]
if [regexp $want $got] then {
pass "objdump -s"
} else {
fail "objdump -s"
set want "$dumpfile:\[ \]*file format.*Contents.*(text|TEXT|P|\\\$CODE\\\$)\[^0-9\]*\[ \]*\[0-9a-fA-F\]*\[ \]*(00000001|01000000|00000100).*Contents.*(data|DATA|D_1)\[^0-9\]*\[ \]*\[0-9a-fA-F\]*\[ \]*(00000002|02000000|00000200)"
if [regexp $want $got] then {
pass "objdump -s ($testfile, $dumpfile)"
} else {
fail "objdump -s ($testfile, $dumpfile)"
}
}
test_objdump_s $testfile $testfile
if { [ remote_file host exists $testarchive ] } then {
test_objdump_s $testarchive bintest2.o
}
# Test objdump -s on a file that contains a compressed .debug section